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
00060
00061 tpmesh->infvertex1 = (piyush::vertex) NULL;
00062 tpmesh->infvertex2 = (piyush::vertex) NULL;
00063 tpmesh->infvertex3 = (piyush::vertex) NULL;
00064
00065
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
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
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
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
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
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
00292
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;
00356
00357
00358
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;
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;
00433 triangle ptr;
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
00447 int intersect = pdelclass->locate(tpmesh, tpbehavior, dv, &horiz);
00448 if(intersect != piyush::ONVERTEX) {
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
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
00474
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
00489
00490
00491 typedef piyush::__otriangle trianglelooptype;
00492 typedef piyush::triangle triangle;
00493
00494 triangle ptr;
00495 fIterator retval;
00496 retval.MyDelaunay = this;
00497
00498
00499
00500
00501 onext( (*(trianglelooptype *)(&(fit.floop))), (*(trianglelooptype *)(&(retval.floop))));
00502
00503
00504 return retval;
00505 }
00506
00507
00508 inline Delaunay::fIterator Delaunay::Oprev(fIterator const & fit){
00509
00510
00511
00512
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;
00546
00547 while( linkn != start ){
00548
00549 nfit = Onext(nfit);
00550 if (isdummy(nfit)){
00551
00552 ivv.clear();
00553
00554
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
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 }