src/del_impl.cpp

Go to the documentation of this file.
00001 
00006 #include <iostream>
00007 #include <triangle_impl.hpp>
00008 #include <del_interface.hpp>
00009 #include <new>
00010 
00011 #define REAL double
00012 
00013 namespace tpp {
00014 
00015 using std::cout;
00016 using std::cerr;
00017 
00018 
00019 
00020 void Delaunay::Triangulate(std::string& triswitches){
00021         typedef struct triangulateio  TriangStruct;
00022         typedef struct triangulateio* pTriangStruct;
00023 
00024         in = new TriangStruct;
00025 
00026         pTriangStruct pin = (struct triangulateio *)in;
00027         
00028 
00029         pin->numberofpoints = (int)PList.size();
00030         pin->numberofpointattributes = (int)0;
00031         pin->pointlist = static_cast<double *> ((void *)(&PList[0])) ;
00032         pin->pointattributelist = NULL;
00033         pin->pointmarkerlist = (int *) NULL;
00034         pin->numberofsegments = 0;
00035         pin->numberofholes = 0;
00036         pin->numberofregions = 0;
00037         pin->regionlist = (REAL *) NULL;
00038 
00039         delclass = new piyush;
00040         piyush *pdelclass = (piyush *)delclass;
00041         triswitches.push_back('\0');
00042         char *ptris = &triswitches[0];
00043 
00044         pmesh = new piyush::__pmesh;
00045         pbehavior = new piyush::__pbehavior;
00046 
00047         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00048         piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
00049 
00050         pdelclass->triangleinit(tpmesh);
00051         pdelclass->parsecommandline(1, &ptris, tpbehavior);
00052 
00053         pdelclass->transfernodes(tpmesh, tpbehavior, pin->pointlist, 
00054                 pin->pointattributelist,
00055                 pin->pointmarkerlist, pin->numberofpoints,
00056                 pin->numberofpointattributes);
00057         tpmesh->hullsize = pdelclass->delaunay(tpmesh, tpbehavior);
00058 
00059   /* Ensure that no vertex can be mistaken for a triangular bounding */
00060   /*   box vertex in insertvertex().                                 */
00061         tpmesh->infvertex1 = (piyush::vertex) NULL;
00062         tpmesh->infvertex2 = (piyush::vertex) NULL;
00063         tpmesh->infvertex3 = (piyush::vertex) NULL;
00064 
00065         /* Calculate the number of edges. */
00066         tpmesh->edges = (3l * tpmesh->triangles.items + tpmesh->hullsize) / 2l;
00067         pdelclass->numbernodes(tpmesh, tpbehavior);
00068 
00069         Triangulated = true;
00070 }
00071 
00072 
00073 Delaunay::~Delaunay(){
00074         struct triangulateio *pin = (struct triangulateio *)in;
00075 
00076         piyush *pdelclass =  (piyush *)delclass;
00077 
00078         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00079         piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
00080 
00081         pdelclass->triangledeinit(tpmesh, tpbehavior);
00082 
00083         delete tpmesh;
00084         delete tpbehavior;
00085         delete pin;
00086         delete pdelclass;       
00087 }
00088 
00089 void Delaunay::writeoff(std::string& fname){
00090         if(!Triangulated) {
00091                 cerr << "FATAL: Write called before triangulation\n";
00092                 exit(1);
00093         }
00094         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00095         piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
00096         piyush *pdelclass =  (piyush *)delclass;
00097         char *pfname = new char[fname.size()+1];
00098         strcpy(pfname , fname.c_str());
00099 
00100         pdelclass->writeoff(tpmesh, tpbehavior, pfname, 0, NULL);
00101         delete [] pfname;
00102 }
00103 
00104 int Delaunay::nedges(){
00105         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00106         return tpmesh->edges;
00107 }
00108 
00109 int Delaunay::ntriangles(){
00110         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00111         return tpmesh->triangles.items; 
00112 }
00113 
00114 int Delaunay::nvertices(){
00115         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00116         piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
00117         int outvertices;
00118 
00119         if (tpbehavior->jettison) {
00120             outvertices = tpmesh->vertices.items - tpmesh->undeads;
00121         } else {
00122             outvertices = tpmesh->vertices.items;
00123         }
00124 
00125         return outvertices;
00126 }
00127 
00128 int Delaunay::hull_size(){
00129         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00130         return  tpmesh->hullsize;       
00131 }
00132 
00133 int Delaunay::vertexId(vIterator const &vit){
00134  piyush::__pmesh     * tpmesh     = (piyush::__pmesh *) vit.MyDelaunay->pmesh;
00135  return ((int *)vit.vloop)[tpmesh->vertexmarkindex];
00136 }
00137 
00138 
00139 
00140 
00142 //
00143 // Vertex Iterator Impl.
00144 //
00146 
00147 
00148 Delaunay::vIterator::vIterator(Delaunay* adel) {
00149      typedef piyush::vertex vertex;
00150      MyDelaunay = adel;
00151 
00152      piyush::__pmesh     * tpmesh     = (piyush::__pmesh *) adel->pmesh;
00153      piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) adel->pbehavior;
00154      piyush *pdelclass =  (piyush *)adel->delclass;
00155 
00156      pdelclass->traversalinit(&( tpmesh->vertices ) );
00157      vloop = pdelclass->vertextraverse(tpmesh);
00158 
00159      while
00160         (
00161                  tpbehavior->jettison || 
00162                 (
00163                   ((int *)vloop)[tpmesh->vertexmarkindex+1] == UNDEADVERTEX
00164                 )
00165         ) 
00166         vloop = (void *) pdelclass->vertextraverse(tpmesh);
00167 }
00168 
00169 Delaunay::vIterator::~vIterator(){
00170 }
00171 
00172 
00173 Delaunay::vIterator Delaunay::vend(){
00174         vIterator vit;
00175         vit.vloop = ((piyush::vertex) NULL);
00176         return vit;
00177 }
00178 
00179 
00180 
00181 Delaunay::vIterator Delaunay::vIterator::operator++() {
00182      typedef piyush::vertex vertex;     
00183 
00184      piyush::__pmesh     * tpmesh     = (piyush::__pmesh *) MyDelaunay->pmesh;
00185      piyush::__pbehavior * tpbehavior = 
00186                                 (piyush::__pbehavior *) MyDelaunay->pbehavior;
00187 
00188      piyush *pdelclass =  (piyush *) MyDelaunay->delclass;
00189 
00190      while
00191         (
00192                  tpbehavior->jettison ||
00193                 (
00194                   ((int *)vloop)[tpmesh->vertexmarkindex+1] == UNDEADVERTEX
00195                 )
00196         )
00197         vloop = (void *) pdelclass->vertextraverse(tpmesh);
00198         vloop = (void *) pdelclass->vertextraverse(tpmesh);
00199 
00200                 vIterator vit;
00201                 vit.vloop = vloop;
00202                 vit.MyDelaunay = MyDelaunay;
00203 
00204                 return vit;
00205 }
00206 
00207 Delaunay::Point & Delaunay::vIterator::operator*() const{
00208         return *((Point *)vloop);
00209 }
00210 
00211 
00212 bool operator==(Delaunay::vIterator const &vit1,
00213                 Delaunay::vIterator const &vit2) {
00214         if (vit1.vloop == vit2.vloop) return true;
00215         return false;
00216 }
00217 
00218 
00219 bool operator!=(Delaunay::vIterator const &vit1,
00220                 Delaunay::vIterator const &vit2) {
00221         if (vit1.vloop != vit2.vloop) return true;
00222         return false;
00223 }
00224 
00225 
00226 
00227 
00229 //
00230 // Face Iterator Impl.
00231 //
00233 
00234 
00235 
00236 Delaunay::fIterator::fIterator(Delaunay* adel) {
00237      typedef piyush::vertex vertex;
00238      typedef piyush::__otriangle trianglelooptype;
00239 
00240      MyDelaunay = adel;
00241 
00242      piyush::__pmesh     * tpmesh     = (piyush::__pmesh *) adel->pmesh;
00243      piyush *pdelclass =  (piyush *)adel->delclass;
00244 
00245      pdelclass->traversalinit(&( tpmesh->triangles ) );
00246      // floop = new trianglelooptype;
00247      trianglelooptype *ploop = (trianglelooptype *)(&floop);
00248      ploop->tri    = pdelclass->triangletraverse(tpmesh);
00249      ploop->orient = 0;
00250 
00251 }
00252 
00253 Delaunay::fIterator::~fIterator(){
00254 }
00255 
00256 Delaunay::fIterator Delaunay::fend(){
00257         fIterator fit;
00258                 typedef piyush::__otriangle trianglelooptype;
00259         fit.floop.tri = (double ***) NULL;
00260         return fit;
00261 }
00262 
00263 void Delaunay::fIterator::operator++() {
00264          // cout << "++ called\n";
00265      typedef piyush::vertex   vertex;
00266      typedef piyush::triangle triangle;
00267      typedef piyush::__otriangle trianglelooptype;
00268 
00269      piyush::__pmesh     * tpmesh     = (piyush::__pmesh *) MyDelaunay->pmesh;
00270      
00271      trianglelooptype *ploop = (trianglelooptype *)(&floop);
00272      piyush *pdelclass =  (piyush *) MyDelaunay->delclass;
00273 
00274      ploop->tri = pdelclass->triangletraverse(tpmesh);
00275          // cout << "tri val = " << ploop->tri << endl;
00276 }
00277 
00278 bool operator==(Delaunay::fIterator const &fit1,
00279                 Delaunay::fIterator const &fit2) {
00280 
00281     return (fit1.floop.tri == fit2.floop.tri);
00282 
00283 }
00284 
00285 bool operator!=(Delaunay::fIterator const &fit1,
00286                 Delaunay::fIterator const &fit2) {
00287                 return !( operator==(fit1,fit2) );
00288 }
00289 
00290 
00291 /*  A triangle abc has origin (org) a,destination (dest) b, and apex (apex)  */
00292 /*  c.  These vertices occur in counterclockwise order about the triangle.   */
00293 int Delaunay::Org (fIterator const & fit){
00294      typedef piyush::vertex   vertex;
00295      typedef piyush::triangle triangle;
00296      typedef piyush::__otriangle trianglelooptype;
00297 
00298      piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) 
00299                                                 ((fit.MyDelaunay)->pbehavior);
00300 
00301      piyush::__pmesh  * tpmesh  = (piyush::__pmesh *) (fit.MyDelaunay->pmesh);
00302      trianglelooptype * ploop   = (trianglelooptype *)(&(fit.floop));
00303 
00304      vertex vertexptr = (vertex) ((ploop->tri)[plus1mod3[ploop->orient] + 3]);
00305      return
00306         ( ((int *) (vertexptr))[tpmesh->vertexmarkindex] )
00307         -
00308         tpbehavior->firstnumber;
00309                 
00310 }
00311 
00312 
00313 int Delaunay::Dest(fIterator const & fit){
00314      typedef piyush::vertex   vertex;
00315      typedef piyush::triangle triangle;
00316      typedef piyush::__otriangle trianglelooptype;
00317 
00318      piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *)
00319                                                 ((fit.MyDelaunay)->pbehavior);
00320 
00321      piyush::__pmesh  * tpmesh  = (piyush::__pmesh *) (fit.MyDelaunay->pmesh);
00322      trianglelooptype * ploop   = (trianglelooptype *)(&(fit.floop));
00323 
00324      vertex vertexptr = (vertex) ((ploop->tri)[minus1mod3[ploop->orient] + 3]);
00325      return
00326         ( ((int *) (vertexptr))[tpmesh->vertexmarkindex] )
00327         -
00328         tpbehavior->firstnumber;
00329 
00330 }
00331 
00332 int Delaunay::Apex(fIterator const & fit){
00333      typedef piyush::vertex   vertex;
00334      typedef piyush::triangle triangle;
00335      typedef piyush::__otriangle trianglelooptype;
00336 
00337      piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *)
00338                                                 ((fit.MyDelaunay)->pbehavior);
00339 
00340      piyush::__pmesh  * tpmesh  = (piyush::__pmesh *) (fit.MyDelaunay->pmesh);
00341      trianglelooptype * ploop   = (trianglelooptype *)(&(fit.floop));
00342 
00343      vertex vertexptr = (vertex) ((ploop->tri)[ploop->orient + 3]);
00344      return
00345         ( ((int *) (vertexptr))[tpmesh->vertexmarkindex] )
00346         -
00347         tpbehavior->firstnumber;
00348 }
00349 
00350 
00351 int Delaunay::Sym(fIterator const & fit, char i){
00352          typedef piyush::vertex      vertex;
00353      typedef piyush::triangle    triangle;
00354      typedef piyush::__otriangle trianglelooptype;
00355          triangle ptr;                         /* Temporary variable used by sym(). */
00356 
00357      //piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *)
00358      //                                           ((fit.MyDelaunay)->pbehavior);
00359 
00360      piyush::__pmesh  * tpmesh  = (piyush::__pmesh *) (fit.MyDelaunay->pmesh);
00361      trianglelooptype * ploop   = (trianglelooptype *)(&(fit.floop));
00362 
00363          char oval = ploop->orient;
00364      ploop->orient = i;
00365 
00366          trianglelooptype top;
00367          sym(*ploop, top);
00368          ploop->orient = oval;
00369 
00370          if(top.tri != tpmesh->dummytri){
00371                  vertex farvertex;
00372                  apex(top, farvertex);
00373                  return ((int *)farvertex)[tpmesh->vertexmarkindex];
00374          }
00375          
00376         return -1;       
00377 }
00378 
00379 
00380 Delaunay::fIterator Delaunay::Sym(fIterator const & fit){
00381          fIterator retval;
00382          retval.MyDelaunay = fit.MyDelaunay;
00383 
00384          typedef piyush::vertex      vertex;
00385          typedef piyush::triangle    triangle;
00386          typedef piyush::__otriangle trianglelooptype;
00387          triangle ptr;                         /* Temporary variable used by sym(). */
00388 
00389      piyush::__pmesh  * tpmesh  = (piyush::__pmesh *) (fit.MyDelaunay->pmesh);
00390      trianglelooptype * ploop   = (trianglelooptype *)(&(fit.floop));
00391 
00392          
00393          trianglelooptype top;
00394          sym(*ploop, top);
00395          
00396 
00397          if(top.tri != tpmesh->dummytri){
00398                  retval.floop.tri = top.tri;
00399                  retval.floop.orient = top.orient;
00400 
00401                  return retval;
00402          }
00403          
00404          retval.floop.tri = NULL;
00405          retval.floop.orient = 0;
00406          return retval;
00407 
00408 }
00409 
00410 double Delaunay::area(fIterator const & fit){
00411         Point torg, tdest, tapex;
00412         torg  = point_at_vertex_id(Org(fit));
00413         tdest = point_at_vertex_id(Dest(fit));
00414         tapex = point_at_vertex_id(Apex(fit));
00415         double dxod(torg[0] - tdest[0]);
00416         double dyod(torg[1] - tdest[1]);
00417         double dxda(tdest[0] - tapex[0]);
00418         double dyda(tdest[1] - tapex[1]);
00419 
00420         double area = 0.5 * (dxod * dyda - dyod * dxda);
00421         return area;
00422 }
00423 
00424 Delaunay::fIterator Delaunay::locate(int vertexid){
00425         fIterator retval;
00426         retval.MyDelaunay = this;
00427 
00428     typedef piyush::vertex      vertex;
00429     typedef piyush::triangle    triangle;
00430     typedef piyush::__otriangle trianglelooptype;
00431 
00432         trianglelooptype horiz;               /* Temporary variable for use in locate(). */
00433         triangle ptr;                         /* Temporary variable used by sym(). */
00434 
00435         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00436         piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
00437         piyush  *pdelclass               = (piyush *)              delclass;
00438 
00439         horiz.tri = tpmesh->dummytri;
00440     horiz.orient = 0;
00441         symself(horiz);
00442         double dv[2];
00443         dv[0] = PList[vertexid][0];
00444         dv[1] = PList[vertexid][1];
00445 
00446         /* Search for a triangle containing `newvertex'. */
00447         int intersect = pdelclass->locate(tpmesh, tpbehavior, dv, &horiz);
00448         if(intersect != piyush::ONVERTEX) { // Not on vertex!
00449                 cout << "Something went wrong in point location\n";
00450                 exit(1);
00451         }
00452         
00453         retval.floop.tri = horiz.tri;
00454         retval.floop.orient = horiz.orient;
00455 
00456         return retval;
00457 
00458 }
00459 
00460 inline Delaunay::fIterator Delaunay::Lnext(fIterator const & fit){
00461 /* lnext() finds the next edge (counterclockwise) of a triangle.        */
00462         typedef piyush::__otriangle trianglelooptype;
00463 
00464         fIterator retval;
00465         retval.MyDelaunay = this;
00466 
00467         lnext(   (*(trianglelooptype *)(&(fit.floop))), (*(trianglelooptype *)(&(retval.floop))));
00468         return retval;
00469 }
00470 
00471 inline Delaunay::fIterator Delaunay::Lprev(fIterator const & fit){
00472 /*                                                                           */
00473 /*  lprev:  Find the previous edge (clockwise) of a triangle.                */
00474 /*  lprev(abc) -> cab                                                        */
00475 /*                                                                           */
00476         typedef piyush::__otriangle trianglelooptype;
00477 
00478         fIterator retval;
00479         retval.MyDelaunay = this;
00480 
00481         lprev(   (*(trianglelooptype *)(&(fit.floop))), (*(trianglelooptype *)(&(retval.floop))));
00482         return retval;
00483 }
00484 
00485 
00486 inline Delaunay::fIterator Delaunay::Onext(fIterator const & fit){
00487 
00488 /*  onext:  Find the next edge counterclockwise with the same origin.        */
00489 /*  onext(abc) -> ac*                                                        */
00490         
00491         typedef piyush::__otriangle trianglelooptype;
00492         typedef piyush::triangle    triangle;
00493 
00494         triangle ptr;
00495         fIterator retval;
00496         retval.MyDelaunay = this;
00497 
00498         //cout << "Onext called:\n " 
00499         //       << Org(fit) << "\t" << Dest(fit) << "\t" << Apex(fit) << "\n";
00500 
00501         onext(   (*(trianglelooptype *)(&(fit.floop))), (*(trianglelooptype *)(&(retval.floop))));
00502 
00503         // retval could be dummy!
00504         return retval;
00505 }
00506 
00507 
00508 inline Delaunay::fIterator Delaunay::Oprev(fIterator const & fit){
00509 
00510 /*                                                                           */
00511 /*  oprev:  Find the next edge clockwise with the same origin.               */
00512 /*  oprev(abc) -> a*b                                                        */
00513 /*                                                                           */
00514         typedef piyush::__otriangle trianglelooptype;
00515         typedef piyush::triangle    triangle;
00516 
00517         triangle ptr;
00518         fIterator retval;
00519         retval.MyDelaunay = this;
00520 
00521         oprev(   (*(trianglelooptype *)(&(fit.floop))), (*(trianglelooptype *)(&(retval.floop))));
00522         return retval;
00523 }
00524 
00525 
00526 inline bool Delaunay::isdummy(fIterator const & fit){
00527         piyush::__pmesh     * tpmesh     = (piyush::__pmesh *)     pmesh;
00528         typedef piyush::__otriangle trianglelooptype;
00529 
00530         return ( ((trianglelooptype *)(&(fit.floop)))->tri == tpmesh->dummytri );
00531 }
00532 
00533 void Delaunay::trianglesAroundVertex(int vertexid, std::vector<int>& ivv){
00534         fIterator fit = locate(vertexid);
00535         ivv.clear();
00536 
00537         int start = Dest(fit);
00538         int linkn = Apex(fit);
00539 
00540         ivv.push_back(vertexid);
00541         ivv.push_back(start);
00542         ivv.push_back(linkn);
00543 
00544         fIterator nfit = fit;
00545         fIterator pnfit = fit; // follows nfit by one triangle
00546 
00547         while( linkn != start ){
00548                 
00549                 nfit = Onext(nfit);
00550                 if (isdummy(nfit)){
00551                         // Do another algorithm
00552                         ivv.clear();
00553 
00554                         // use oprev now...
00555                         fit = pnfit;
00556                         nfit = fit;
00557 
00558                         start = Apex(fit);
00559                         linkn = Dest(fit);
00560                         
00561                         ivv.push_back(vertexid);
00562                         ivv.push_back(linkn);
00563                         ivv.push_back(start);
00564                         
00565                         while( linkn != start ){
00566                                 nfit = Oprev(nfit);
00567                                 if(isdummy(nfit))
00568                                         return;
00569                                 int a = Org(nfit);
00570                                 int b = Dest(nfit);
00571                                 int c = Apex(nfit);
00572                                 ivv.push_back(a);
00573                                 ivv.push_back(b);
00574                                 ivv.push_back(c);
00575                                 linkn = Dest(nfit);
00576                         }
00577 
00578                         return;
00579                 }
00580                 
00581                 pnfit = nfit;
00582 
00583                 int a = Org(nfit);
00584                 int b = Dest(nfit);
00585                 int c = Apex(nfit);
00586 
00587                 //cout << "Triangle: " << a << "\t"  << b << "\t"  << c << "\n";
00588 
00589                 ivv.push_back(a);
00590                 ivv.push_back(b);
00591                 ivv.push_back(c);
00592 
00593                 linkn = Apex(nfit);
00594         }
00595 
00596 }
00597 
00598 } // namespace tpp ends.

Generated on Fri Nov 3 21:59:03 2006 for Triangle++ by  doxygen 1.4.6