// TrackContour() - compute and track a contour by table lookup and propagation // through adjacent cells // isovalue = surface value of interest // nextslice = queue of seeds for next slice (used only if tracking in 2d) void Conplot2d::TrackContour(float isovalue, int cell) { float val[3]; u_int* verts; u_int v1, v2; int code; int adj; int e; int nvert = 0, nedge = 0; // to save isocontour components queue.Add(cell); curslc = (Dataslc*)data->getData(curtime); curcon = &con2[curtime]; if(filePrefix) // keep track of current nvert, nedge { nvert = curcon->getNVert(); nedge = curcon->getNEdge(); } while(queue.Get(cell) > 0) { curslc->getCellValues(cell, val); verts = curslc->getCellVerts(cell); code = 0; if(val[0] < isovalue) { code += 0x01; } if(val[1] < isovalue) { code += 0x02; } if(val[2] < isovalue) { code += 0x04; } for(e=0; e<unst2d[code][0]; e++) { v1 = InterpEdge(unst2d[code][2*e+1], val, verts, isovalue, cell); v2 = InterpEdge(unst2d[code][2*e+2], val, verts, isovalue, cell); curcon->AddEdge(v1, v2); adj = curslc->getCellAdj(cell, unst2d[code][2*e+1]); if(adj != -1 && !CellTouched(adj)) { TouchCell(adj); queue.Add(adj); } adj = curslc->getCellAdj(cell, unst2d[code][2*e+2]); if(adj != -1 && !CellTouched(adj)) { TouchCell(adj); queue.Add(adj); } } EnqueueFaces(code, cell, queue); } if(filePrefix) // write this isocontour component { if(curcon->getNEdge() - nedge > 25) // more than 25 edges { FILE* fp; int v, e; char filename[200]; sprintf(filename, "%s%04d.ipoly", filePrefix, ncomponents); if((fp = fopen(filename, "w"))) { fprintf(fp, "%d %d 0 0 0 0 0\n0 0 0\n", curcon->getNVert() - nvert, curcon->getNEdge() - nedge); for(v = nvert; v < curcon->getNVert(); v++) fprintf(fp, "%g %g %g\n", curcon->vert[v][0], curcon->vert[v][1], 0.0); fprintf(fp, "0 0\n"); for(e = nedge; e < curcon->getNEdge(); e++) fprintf(fp, "%d %d\n", curcon->edge[e][0], curcon->edge[e][1]); fclose(fp); ncomponents++; } else { char str[256]; sprintf(str, "Conplot2d::TrackContour: couldn't open file: %s", filename); errorHandler(str, false); } } } }
// TrackContour() - compute and track a contour by table lookup and propagation // through adjacent cells // isovalue = surface value of interest // i,j,k = index of seed cell // nextslice = queue of seeds for next slice (used only if tracking in 2d) void Conplot3d::TrackContour(float isovalue, int cell) { float val[4]; u_int* verts; u_int v1, v2, v3; int code; int adj; int e, a; int nvert=0, ntri=0; // to save isocontour components queue.Add(cell); curvol = (Datavol*)data->getData(curtime); curcon = &con3[curtime]; if(filePrefix) // keep track of current nvert, ntri { nvert = curcon->getNVert(); ntri = curcon->getNTri(); } while(queue.Get(cell) > 0) { curvol->getCellValues(cell, val); verts = curvol->getCellVerts(cell); code = 0; if(val[0] < isovalue) { code += 0x01; } if(val[1] < isovalue) { code += 0x02; } if(val[2] < isovalue) { code += 0x04; } if(val[3] < isovalue) { code += 0x08; } for(e=0; e<unst3d[code][0]; e++) { v1 = InterpEdge(unst3d[code][3*e+1], val, verts, isovalue, cell); v2 = InterpEdge(unst3d[code][3*e+2], val, verts, isovalue, cell); v3 = InterpEdge(unst3d[code][3*e+3], val, verts, isovalue, cell); curcon->AddTri(v1, v2, v3); for(a=0; a<tetadj[code][0]; a++) { adj = curvol->getCellAdj(cell, tetadj[code][a+1]); if(adj != -1 && !CellTouched(adj)) { TouchCell(adj); queue.Add(adj); } } } } if(filePrefix) // write this isocontour component { if(curcon->getNTri() - ntri > 25) // more than 25 triangles { FILE* fp; int v, t; char filename[200]; sprintf(filename, "%s%04d.ipoly", filePrefix, ncomponents); if((fp = fopen(filename, "w"))) { fprintf(fp, "%d 0 %d 0 0 0 0\n0 0 0\n", curcon->getNVert() - nvert, curcon->getNTri() - ntri); for(v = nvert; v < curcon->getNVert(); v++) fprintf(fp, "%g %g %g\n", curcon->vert[v][0], curcon->vert[v][1], curcon->vert[v][2]); fprintf(fp, "0 0\n"); for(t = ntri; t < curcon->getNTri(); t++) fprintf(fp, "3\n%d %d %d\n", curcon->tri[t][0], curcon->tri[t][1], curcon->tri[t][2]); fclose(fp); ncomponents++; } else { char str[256]; sprintf(str, "Conplot3d::TrackContour: couldn't open file: %s", filename); errorHandler(str, false); } } } }
//------------------------------------------------------------------------ // // EnqueueFaces() - enqueue adjacent faces for propagation of contour // code = case table lookup code for current cell // i,j,k = index of current cell // queue = queue of cells to be processed on current slice // nextslice = queue of cells to be processed on next slice // trackinz = flag indicating whether to propagate in z-dir // 0 -> don't track in z, but queue cells in nextslice // 1 -> propagate contour in all 3 dim // //------------------------------------------------------------------------ inline void Conplotreg3::EnqueueFaces(int code, int i, int j, int k, CellQueue &queue) { int f; int id; for (f=0; f<adjfaces[code][0]; f++) { switch (adjfaces[code][1+f]) { case 0: if (j >= 1) { id = curreg3->index2cell(i, j-1, k); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; case 1: if (i >= 1) { id = curreg3->index2cell(i-1, j, k); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; case 2: if (j <= curreg3->dim[1]-3) { id = curreg3->index2cell(i, j+1, k); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; case 3: if (i <= curreg3->dim[0]-3) { id = curreg3->index2cell(i+1, j, k); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; case 4: if (k <= curreg3->dim[2]-3) { id = curreg3->index2cell(i, j, k+1); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; case 5: if (k >= 1) { id = curreg3->index2cell(i, j, k-1); if (!CellTouched(id)) { TouchCell(id); queue.Add(id); } } break; } } }