/**************************************************************************** * * MODULE: r.terraflow * * COPYRIGHT (C) 2007 Laura Toma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *****************************************************************************/ #include #include #include "grid.h" #include "common.h" #define GRID_DEBUG if(0) /* leave a border of 1 cell around */ grid::grid(dimension_type giMin, dimension_type gjMin, dimension_type iMax, dimension_type jMax, long gsize, cclabel_type glabel) : iMin(giMin-1), jMin(gjMin-1), label(glabel), size(gsize) { width = jMax - jMin + 2; height = iMax - iMin + 2; assert(width*height*sizeof(gridElement) < getAvailableMemory()); data = new gridElement[width*height]; assert(data); memset(data, 0, width*height*sizeof(gridElement)); } grid::~grid() { delete [] data; } void grid::load(AMI_STREAM &str) { AMI_err ae; plateauType *pt; GRID_DEBUG cout << "loading grid" << endl; for(int i=0; ivalid); assert(pt->cclabel == label); dimension_type pti, ptj; pti = pt->i - iMin; ptj = pt->j - jMin; gridElement *datap = data + pti * width + ptj; datap->dir = pt->dir; datap->depth = DEPTH_INITIAL; /* initial depth */ datap->valid = 1; #ifdef KEEP_COORDS datap->i = pt->i; datap->j = pt->j; #endif if(datap->dir) { /* if it has a dir, it's on the boundary */ boundaryQueue[0].enqueue(datap); } } } void grid::save(AMI_STREAM &str) { GRID_DEBUG cout << "saving grid" << endl; for(dimension_type i=1; ivalid) { /* DONT save the label */ waterType wt(i+iMin, j+jMin, datap->dir, LABEL_UNDEF, datap->depth); AMI_err ae = str.write_item(wt); assert(ae == AMI_ERROR_NO_ERROR); } } } } void grid::print() { cout << " "; for(int i=0; ij << endl; } GRID_DEBUG cout << endl; #endif int k1=0, k2=1; while(!boundaryQueue[k1].isEmpty()) { while(boundaryQueue[k1].dequeue(&datap)) { /* should only find dominant if not on edge */ if(sfdmode && datap->depth > DEPTH_INITIAL) { datap->dir = findDominant(datap->dir); } #ifdef KEEP_COORDS GRID_DEBUG cout << "(" << datap->i << "," << datap->j << ") " << "my direction is " << datap->dir; #endif for(int i=0; i<8; i++) { np = getNeighbour(datap, i); if(np->valid) { if(!np->dir) { np->depth = datap->depth + 1; boundaryQueue[k2].enqueue(np); #ifdef KEEP_COORDS GRID_DEBUG cout << " pushing " << "(" << np->i << "," << np->j << ")"; #endif } if(np->depth == datap->depth + 1) { /* can only update ifin othr list */ np->dir |= getDirection(i); /* neighbor points to us */ /* if(!np->dir) np->dir |= getDirection(i); */ } } } GRID_DEBUG cout << endl; } k1 ^= 1; k2 ^= 1; } }