static long gc_common(long iMax, long jMax, double *x, double *y, int *reg, short *triangle, int region, const double *zz, long nchunk, long *nparts) { long ntotal= 0; long n; gc_site.imax= iMax; gc_site.jmax= jMax; gc_site.x= x; gc_site.y= y; gc_site.reg= reg; gc_site.triangle= triangle; gc_site.z= zz; gc_site.xcp= gc_site.ycp= 0; gc_site.n= gc_site.count= 0; *nparts= 0; /* get scratch space for data array */ if (GaGetScratchS(gc_site.imax*(gc_site.jmax+1)+1)) return 0; /* initialize the data array */ data_init(&gc_site, gasScratch, region, nchunk); /* make first pass to compute required sizes for GcTrace second pass */ for (;;) { n= curve_tracer(&gc_site, gasScratch, 0); if (!n) break; if (n>0) { (*nparts)++; ntotal+= n; } else { ntotal-= n; } } return ntotal; }
int GaContourInit(GaQuadMesh *msh, int regn, const GpReal *zz, GpReal lev) /* Find the edges cut by the current contour, remembering z, triangle, and level for the GaContour routine, which actually walks the contour. The z array represents function values on the mesh msh. If triangle!=0, it represents the initial value of the triangulation array, which determines the behavior of GaContour in saddle zones. triangle[j][i]= 1, -1, or 0 as the zone bounded by [j-1][i-1], [j-1][i], [j][i], and [j][i-1] has been triangulated from (-1,-1) to (0,0), from (-1,0) to (0,-1), or has not yet been triangulated. The msh->triangle array is updated by GaContour. If a contour passes through an untriangulated saddle zone, GaContour chooses a triangulation and marks the triangle array approriately, so that subsequent calls to GaContour will never produce intersecting contour curves. */ { long iMax= msh->iMax; long ijMax= iMax*msh->jMax; int *ireg= msh->reg; long ij; /* Create default region array if none supplied */ if (!ireg) { ireg= NewReg(iMax, ijMax); if (!ireg) return 0; msh->reg= ireg; } /* Remember data for GaContour */ mesh= msh; region= regn; z= zz; level= lev; /* Get scratch space to hold edges */ if (GaGetScratchS(2*ijMax)) return 0; iedges= gasScratch; jedges= gasScratch+ijMax; /* Find all points above contour level */ for (ij=0 ; ij<ijMax ; ij++) iedges[ij]= zz[ij]>lev; /* Find j=const edges which cut level plane */ nj= njb= 0; for (ij=1 ; ij<ijMax ; ij++) { if ((iedges[ij]^iedges[ij-1]) && (EXISTS(ij)||EXISTS(ij+iMax))) { if ((ireg[ij]==region) ^ (ireg[ij+iMax]==region)) { jedges[ij]= 2; /* contour enters mesh here */ njb++; } else { jedges[ij]= 1; /* interior edge */ nj++; } } else { jedges[ij]= 0; } } jbegin= 1; /* Find i=const edges which cut level plane */ ni= nib= 0; for (ij=ijMax-1 ; ij>=iMax ; ij--) { if ((iedges[ij]^iedges[ij-iMax]) && (EXISTS(ij)||EXISTS(ij+1))) { if ((ireg[ij]==region) ^ (ireg[ij+1]==region)) { iedges[ij]= 2; /* contour enters mesh here */ nib++; } else { iedges[ij]= 1; /* interior edge */ ni++; } } else { iedges[ij]= 0; } } ibegin= iMax; /* Set keepLeft to a known value (arbitrary but repeatable) */ keepLeft= 0; /* Get scratch space for level curves */ if (GaGetScratchP(ni+nib+nj+njb+1)) return 0; if (tmpReg) FreeTmpReg(); return ni || nib || nj || njb; }