00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <queue>
00027 #endif
00028
00029 #include <Base/Console.h>
00030 #include <Base/Exception.h>
00031 #include "Triangulation.h"
00032 #include "Approximation.h"
00033 #include "MeshKernel.h"
00034
00035 #include <Mod/Mesh/App/WildMagic4/Wm4Delaunay2.h>
00036
00037
00038 using namespace MeshCore;
00039
00040
00041 AbstractPolygonTriangulator::AbstractPolygonTriangulator()
00042 {
00043 _discard = false;
00044 }
00045
00046 AbstractPolygonTriangulator::~AbstractPolygonTriangulator()
00047 {
00048 }
00049
00050 void AbstractPolygonTriangulator::SetPolygon(const std::vector<Base::Vector3f>& raclPoints)
00051 {
00052 this->_points = raclPoints;
00053 if (this->_points.size() > 0) {
00054 if (this->_points.front() == this->_points.back())
00055 this->_points.pop_back();
00056 }
00057 }
00058
00059 std::vector<Base::Vector3f> AbstractPolygonTriangulator::GetPolygon() const
00060 {
00061 return _points;
00062 }
00063
00064 float AbstractPolygonTriangulator::GetLength() const
00065 {
00066 float len = 0.0f;
00067 if (_points.size() > 2) {
00068 for (std::vector<Base::Vector3f>::const_iterator it = _points.begin(); it != _points.end();++it) {
00069 std::vector<Base::Vector3f>::const_iterator jt = it + 1;
00070 if (jt == _points.end()) jt = _points.begin();
00071 len += Base::Distance(*it, *jt);
00072 }
00073 }
00074
00075 return len;
00076 }
00077
00078 std::vector<Base::Vector3f> AbstractPolygonTriangulator::AddedPoints() const
00079 {
00080
00081 std::vector<Base::Vector3f> added;
00082 added.reserve(_newpoints.size());
00083 for (std::vector<Base::Vector3f>::const_iterator pt = _newpoints.begin(); pt != _newpoints.end(); ++pt)
00084 added.push_back(_inverse * *pt);
00085 return added;
00086 }
00087
00088 Base::Matrix4D AbstractPolygonTriangulator::GetTransformToFitPlane() const
00089 {
00090 PlaneFit planeFit;
00091 for (std::vector<Base::Vector3f>::const_iterator it = _points.begin(); it!=_points.end(); ++it)
00092 planeFit.AddPoint(*it);
00093
00094 if (planeFit.Fit() == FLOAT_MAX)
00095 throw Base::Exception("Plane fit failed");
00096
00097 Base::Vector3f bs = planeFit.GetBase();
00098 Base::Vector3f ex = planeFit.GetDirU();
00099 Base::Vector3f ey = planeFit.GetDirV();
00100 Base::Vector3f ez = planeFit.GetNormal();
00101
00102
00103 Base::Matrix4D rInverse;
00104 rInverse.setToUnity();
00105 rInverse[0][0] = ex.x; rInverse[0][1] = ey.x; rInverse[0][2] = ez.x; rInverse[0][3] = bs.x;
00106 rInverse[1][0] = ex.y; rInverse[1][1] = ey.y; rInverse[1][2] = ez.y; rInverse[1][3] = bs.y;
00107 rInverse[2][0] = ex.z; rInverse[2][1] = ey.z; rInverse[2][2] = ez.z; rInverse[2][3] = bs.z;
00108
00109 return rInverse;
00110 }
00111
00112 std::vector<Base::Vector3f> AbstractPolygonTriangulator::ProjectToFitPlane()
00113 {
00114 std::vector<Base::Vector3f> proj = _points;
00115 _inverse = GetTransformToFitPlane();
00116 Base::Vector3f bs((float)_inverse[0][3], (float)_inverse[1][3], (float)_inverse[2][3]);
00117 Base::Vector3f ex((float)_inverse[0][0], (float)_inverse[1][0], (float)_inverse[2][0]);
00118 Base::Vector3f ey((float)_inverse[0][1], (float)_inverse[1][1], (float)_inverse[2][1]);
00119 for (std::vector<Base::Vector3f>::iterator jt = proj.begin(); jt!=proj.end(); ++jt)
00120 jt->TransformToCoordinateSystem(bs, ex, ey);
00121 return proj;
00122 }
00123
00124 void AbstractPolygonTriangulator::ProjectOntoSurface(const std::vector<Base::Vector3f>& points)
00125 {
00126
00127
00128 unsigned int uMinPts = 50;
00129
00130 PolynomialFit polyFit;
00131 Base::Vector3f bs((float)_inverse[0][3], (float)_inverse[1][3], (float)_inverse[2][3]);
00132 Base::Vector3f ex((float)_inverse[0][0], (float)_inverse[1][0], (float)_inverse[2][0]);
00133 Base::Vector3f ey((float)_inverse[0][1], (float)_inverse[1][1], (float)_inverse[2][1]);
00134
00135 for (std::vector<Base::Vector3f>::const_iterator it = points.begin(); it != points.end(); ++it) {
00136 Base::Vector3f pt = *it;
00137 pt.TransformToCoordinateSystem(bs, ex, ey);
00138 polyFit.AddPoint(pt);
00139 }
00140
00141 if (polyFit.CountPoints() >= uMinPts && polyFit.Fit() < FLOAT_MAX) {
00142 for (std::vector<Base::Vector3f>::iterator pt = _newpoints.begin(); pt != _newpoints.end(); ++pt)
00143 pt->z = (float)polyFit.Value(pt->x, pt->y);
00144 }
00145 }
00146
00147 bool AbstractPolygonTriangulator::TriangulatePolygon()
00148 {
00149 try {
00150 bool ok = Triangulate();
00151 if (ok) Done();
00152 return ok;
00153 }
00154 catch (const Base::Exception& e) {
00155 Base::Console().Log("Triangulation: %s\n", e.what());
00156 return false;
00157 }
00158 catch (const std::exception& e) {
00159 Base::Console().Log("Triangulation: %s\n", e.what());
00160 return false;
00161 }
00162 catch (...) {
00163 return false;
00164 }
00165 }
00166
00167 std::vector<unsigned long> AbstractPolygonTriangulator::GetInfo() const
00168 {
00169 return _info;
00170 }
00171
00172 void AbstractPolygonTriangulator::Discard()
00173 {
00174 if (!_discard) {
00175 _discard = true;
00176 _info.pop_back();
00177 }
00178 }
00179
00180 void AbstractPolygonTriangulator::Done()
00181 {
00182 _info.push_back(_points.size());
00183 _discard = false;
00184 }
00185
00186
00187
00188 EarClippingTriangulator::EarClippingTriangulator()
00189 {
00190 }
00191
00192 EarClippingTriangulator::~EarClippingTriangulator()
00193 {
00194 }
00195
00196 bool EarClippingTriangulator::Triangulate()
00197 {
00198 _facets.clear();
00199 _triangles.clear();
00200
00201 std::vector<Base::Vector3f> pts = ProjectToFitPlane();
00202 std::vector<unsigned long> result;
00203
00204
00205 Triangulate::Process(pts,result);
00206
00207
00208 unsigned long tcount = result.size()/3;
00209
00210 bool ok = tcount+2 == _points.size();
00211 if (tcount > _points.size())
00212 return false;
00213
00214 MeshGeomFacet clFacet;
00215 MeshFacet clTopFacet;
00216 for (unsigned long i=0; i<tcount; i++) {
00217 if (Triangulate::_invert) {
00218 clFacet._aclPoints[0] = _points[result[i*3+0]];
00219 clFacet._aclPoints[2] = _points[result[i*3+1]];
00220 clFacet._aclPoints[1] = _points[result[i*3+2]];
00221 clTopFacet._aulPoints[0] = result[i*3+0];
00222 clTopFacet._aulPoints[2] = result[i*3+1];
00223 clTopFacet._aulPoints[1] = result[i*3+2];
00224 }
00225 else {
00226 clFacet._aclPoints[0] = _points[result[i*3+0]];
00227 clFacet._aclPoints[1] = _points[result[i*3+1]];
00228 clFacet._aclPoints[2] = _points[result[i*3+2]];
00229 clTopFacet._aulPoints[0] = result[i*3+0];
00230 clTopFacet._aulPoints[1] = result[i*3+1];
00231 clTopFacet._aulPoints[2] = result[i*3+2];
00232 }
00233
00234 _triangles.push_back(clFacet);
00235 _facets.push_back(clTopFacet);
00236 }
00237
00238 return ok;
00239 }
00240
00241 float EarClippingTriangulator::Triangulate::Area(const std::vector<Base::Vector3f> &contour)
00242 {
00243 int n = contour.size();
00244
00245 float A=0.0f;
00246
00247 for(int p=n-1,q=0; q<n; p=q++) {
00248 A+= contour[p].x*contour[q].y - contour[q].x*contour[p].y;
00249 }
00250 return A*0.5f;
00251 }
00252
00253
00254
00255
00256
00257 bool EarClippingTriangulator::Triangulate::InsideTriangle(float Ax, float Ay, float Bx,
00258 float By, float Cx, float Cy,
00259 float Px, float Py)
00260 {
00261 float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
00262 float cCROSSap, bCROSScp, aCROSSbp;
00263
00264 ax = Cx - Bx; ay = Cy - By;
00265 bx = Ax - Cx; by = Ay - Cy;
00266 cx = Bx - Ax; cy = By - Ay;
00267 apx= Px - Ax; apy= Py - Ay;
00268 bpx= Px - Bx; bpy= Py - By;
00269 cpx= Px - Cx; cpy= Py - Cy;
00270
00271 aCROSSbp = ax*bpy - ay*bpx;
00272 cCROSSap = cx*apy - cy*apx;
00273 bCROSScp = bx*cpy - by*cpx;
00274
00275 return ((aCROSSbp >= FLOAT_EPS) && (bCROSScp >= FLOAT_EPS) && (cCROSSap >= FLOAT_EPS));
00276 }
00277
00278 bool EarClippingTriangulator::Triangulate::Snip(const std::vector<Base::Vector3f> &contour,
00279 int u,int v,int w,int n,int *V)
00280 {
00281 int p;
00282 float Ax, Ay, Bx, By, Cx, Cy, Px, Py;
00283
00284 Ax = contour[V[u]].x;
00285 Ay = contour[V[u]].y;
00286
00287 Bx = contour[V[v]].x;
00288 By = contour[V[v]].y;
00289
00290 Cx = contour[V[w]].x;
00291 Cy = contour[V[w]].y;
00292
00293 if (FLOAT_EPS > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax)))) return false;
00294
00295 for (p=0;p<n;p++) {
00296 if( (p == u) || (p == v) || (p == w) ) continue;
00297 Px = contour[V[p]].x;
00298 Py = contour[V[p]].y;
00299 if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
00300 }
00301
00302 return true;
00303 }
00304
00305 bool EarClippingTriangulator::Triangulate::_invert = false;
00306
00307 bool EarClippingTriangulator::Triangulate::Process(const std::vector<Base::Vector3f> &contour,
00308 std::vector<unsigned long> &result)
00309 {
00310
00311
00312 int n = contour.size();
00313 if ( n < 3 ) return false;
00314
00315 int *V = new int[n];
00316
00317
00318
00319 if (0.0f < Area(contour)) {
00320 for (int v=0; v<n; v++) V[v] = v;
00321 _invert = true;
00322 }
00323
00324 else {
00325 for(int v=0; v<n; v++) V[v] = (n-1)-v;
00326 _invert = false;
00327 }
00328
00329 int nv = n;
00330
00331
00332 int count = 2*nv;
00333
00334 for(int m=0, v=nv-1; nv>2; ) {
00335
00336 if (0 >= (count--)) {
00337
00338 return false;
00339 }
00340
00341
00342 int u = v ; if (nv <= u) u = 0;
00343 v = u+1; if (nv <= v) v = 0;
00344 int w = v+1; if (nv <= w) w = 0;
00345
00346 if (Snip(contour,u,v,w,nv,V)) {
00347 int a,b,c,s,t;
00348
00349
00350 a = V[u]; b = V[v]; c = V[w];
00351
00352
00353 result.push_back( a );
00354 result.push_back( b );
00355 result.push_back( c );
00356
00357 m++;
00358
00359
00360 for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;
00361
00362
00363 count = 2*nv;
00364 }
00365 }
00366
00367 delete [] V;
00368
00369 return true;
00370 }
00371
00372
00373
00374 QuasiDelaunayTriangulator::QuasiDelaunayTriangulator()
00375 {
00376 }
00377
00378 QuasiDelaunayTriangulator::~QuasiDelaunayTriangulator()
00379 {
00380 }
00381
00382 bool QuasiDelaunayTriangulator::Triangulate()
00383 {
00384 if (EarClippingTriangulator::Triangulate() == false)
00385 return false;
00386
00387
00388
00389 std::map<std::pair<unsigned long, unsigned long>, std::vector<unsigned long> > aEdge2Face;
00390 for (std::vector<MeshFacet>::iterator pI = _facets.begin(); pI != _facets.end(); pI++) {
00391 for (int i = 0; i < 3; i++) {
00392 unsigned long ulPt0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00393 unsigned long ulPt1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00394
00395 if ((ulPt1-ulPt0)%(_points.size()-1) > 1)
00396 aEdge2Face[std::pair<unsigned long, unsigned long>(ulPt0, ulPt1)].push_back(pI - _facets.begin());
00397 }
00398 }
00399
00400
00401 std::list<std::pair<unsigned long, unsigned long> > aEdgeList;
00402 std::map<std::pair<unsigned long, unsigned long>, std::vector<unsigned long> >::iterator pE;
00403 for (pE = aEdge2Face.begin(); pE != aEdge2Face.end(); ++pE)
00404 aEdgeList.push_back(pE->first);
00405
00406
00407 unsigned long uMaxIter = 5 * aEdge2Face.size();
00408
00409
00410 while (!aEdgeList.empty() && uMaxIter > 0) {
00411
00412 std::pair<unsigned long, unsigned long> aEdge = aEdgeList.front();
00413 aEdgeList.pop_front();
00414 uMaxIter--;
00415
00416
00417 pE = aEdge2Face.find( aEdge );
00418
00419
00420 if (pE == aEdge2Face.end())
00421 continue;
00422
00423 MeshFacet& rF1 = _facets[pE->second[0]];
00424 MeshFacet& rF2 = _facets[pE->second[1]];
00425 unsigned short side1 = rF1.Side(aEdge.first, aEdge.second);
00426
00427 Base::Vector3f cP1 = _points[rF1._aulPoints[side1]];
00428 Base::Vector3f cP2 = _points[rF1._aulPoints[(side1+1)%3]];
00429 Base::Vector3f cP3 = _points[rF1._aulPoints[(side1+2)%3]];
00430
00431 unsigned short side2 = rF2.Side(aEdge.first, aEdge.second);
00432 Base::Vector3f cP4 = _points[rF2._aulPoints[(side2+2)%3]];
00433
00434 MeshGeomFacet cT1(cP1, cP2, cP3); float fMax1 = cT1.MaximumAngle();
00435 MeshGeomFacet cT2(cP2, cP1, cP4); float fMax2 = cT2.MaximumAngle();
00436 MeshGeomFacet cT3(cP4, cP3, cP1); float fMax3 = cT3.MaximumAngle();
00437 MeshGeomFacet cT4(cP3, cP4, cP2); float fMax4 = cT4.MaximumAngle();
00438
00439 float fMax12 = std::max<float>(fMax1, fMax2);
00440 float fMax34 = std::max<float>(fMax3, fMax4);
00441
00442
00443
00444 Base::Vector3f cU = cP2-cP1;
00445 Base::Vector3f cV = cP4-cP3;
00446
00447 Base::Vector3f cN1 = (cU % cV) % cU;
00448 if (((cP3-cP1)*cN1)*((cP4-cP1)*cN1) >= 0.0f)
00449 continue;
00450
00451 Base::Vector3f cN2 = (cU % cV) % cV;
00452 if (((cP1-cP3)*cN2)*((cP2-cP3)*cN2) >= 0.0f)
00453 continue;
00454
00455
00456 if (fMax12 > fMax34) {
00457 rF1._aulPoints[(side1+1)%3] = rF2._aulPoints[(side2+2)%3];
00458 rF2._aulPoints[(side2+1)%3] = rF1._aulPoints[(side1+2)%3];
00459
00460
00461 for (int i=0; i<3; i++) {
00462 std::map<std::pair<unsigned long, unsigned long>, std::vector<unsigned long> >::iterator it;
00463
00464 unsigned long ulPt0 = std::min<unsigned long>(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]);
00465 unsigned long ulPt1 = std::max<unsigned long>(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]);
00466 it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) );
00467 if (it != aEdge2Face.end()) {
00468 if (it->second[0] == pE->second[1])
00469 it->second[0] = pE->second[0];
00470 else if (it->second[1] == pE->second[1])
00471 it->second[1] = pE->second[0];
00472 aEdgeList.push_back(it->first);
00473 }
00474
00475
00476 ulPt0 = std::min<unsigned long>(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]);
00477 ulPt1 = std::max<unsigned long>(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]);
00478 it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) );
00479 if (it != aEdge2Face.end()) {
00480 if (it->second[0] == pE->second[0])
00481 it->second[0] = pE->second[1];
00482 else if (it->second[1] == pE->second[0])
00483 it->second[1] = pE->second[1];
00484 aEdgeList.push_back(it->first);
00485 }
00486 }
00487
00488
00489 unsigned long ulPt0 = std::min<unsigned long>(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]);
00490 unsigned long ulPt1 = std::max<unsigned long>(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]);
00491 std::pair<unsigned long, unsigned long> aNewEdge = std::make_pair(ulPt0, ulPt1);
00492 aEdge2Face[aNewEdge] = pE->second;
00493 aEdge2Face.erase(pE);
00494 }
00495 }
00496
00497 return true;
00498 }
00499
00500
00501
00502 namespace MeshCore {
00503 namespace Triangulation {
00504 struct Vertex2d_Less : public std::binary_function<const Base::Vector3f&, const Base::Vector3f&, bool>
00505 {
00506 bool operator()(const Base::Vector3f& p, const Base::Vector3f& q) const
00507 {
00508 if (fabs(p.x - q.x) < MeshDefinitions::_fMinPointDistanceD1) {
00509 if (fabs(p.y - q.y) < MeshDefinitions::_fMinPointDistanceD1) {
00510 return false; } else return p.y < q.y;
00511 } else return p.x < q.x; return true;
00512 }
00513 };
00514 struct Vertex2d_EqualTo : public std::binary_function<const Base::Vector3f&, const Base::Vector3f&, bool>
00515 {
00516 bool operator()(const Base::Vector3f& p, const Base::Vector3f& q) const
00517 {
00518 if (fabs(p.x - q.x) < MeshDefinitions::_fMinPointDistanceD1
00519 && fabs(p.y - q.y) < MeshDefinitions::_fMinPointDistanceD1)
00520 return true; return false;
00521 }
00522 };
00523 }
00524 }
00525
00526 DelaunayTriangulator::DelaunayTriangulator()
00527 {
00528 }
00529
00530 DelaunayTriangulator::~DelaunayTriangulator()
00531 {
00532 }
00533
00534 bool DelaunayTriangulator::Triangulate()
00535 {
00536
00537
00538 std::vector<Base::Vector3f> aPoints = _points;
00539
00540 std::sort(aPoints.begin(), aPoints.end(), Triangulation::Vertex2d_Less());
00541
00542 if (std::adjacent_find(aPoints.begin(), aPoints.end(),
00543 Triangulation::Vertex2d_EqualTo()) < aPoints.end())
00544 return false;
00545
00546 _facets.clear();
00547 _triangles.clear();
00548
00549 std::vector<Wm4::Vector2d> akVertex;
00550 akVertex.reserve(_points.size());
00551 for (std::vector<Base::Vector3f>::iterator it = _points.begin(); it != _points.end(); it++) {
00552 akVertex.push_back(Wm4::Vector2d(it->x, it->y));
00553 }
00554
00555 Wm4::Delaunay2d del(akVertex.size(), &(akVertex[0]), 0.001, false, Wm4::Query::QT_INT64);
00556 int iTQuantity = del.GetSimplexQuantity();
00557 std::vector<int> aiTVertex(3*iTQuantity);
00558 size_t uiSize = 3*iTQuantity*sizeof(int);
00559 Wm4::System::Memcpy(&(aiTVertex[0]),uiSize,del.GetIndices(),uiSize);
00560
00561
00562
00563
00564 int iEQuantity = 0;
00565 int* aiIndex = 0;
00566 del.GetHull(iEQuantity,aiIndex);
00567 int iUniqueVQuantity = del.GetUniqueVertexQuantity();
00568 int iTVerify = 2*iUniqueVQuantity - 2 - iEQuantity;
00569 (void)iTVerify;
00570 bool succeeded = (iTVerify == iTQuantity);
00571 int iEVerify = 3*iUniqueVQuantity - 3 - iEQuantity;
00572 (void)iEVerify;
00573 delete[] aiIndex;
00574
00575 MeshGeomFacet triangle;
00576 MeshFacet facet;
00577 for (int i = 0; i < iTQuantity; i++) {
00578 for (int j=0; j<3; j++) {
00579 facet._aulPoints[j] = aiTVertex[3*i+j];
00580 triangle._aclPoints[j].x = (float)akVertex[aiTVertex[3*i+j]].X();
00581 triangle._aclPoints[j].y = (float)akVertex[aiTVertex[3*i+j]].Y();
00582 }
00583
00584 _triangles.push_back(triangle);
00585 _facets.push_back(facet);
00586 }
00587
00588 return succeeded;
00589 }
00590
00591
00592
00593 FlatTriangulator::FlatTriangulator()
00594 {
00595 }
00596
00597 FlatTriangulator::~FlatTriangulator()
00598 {
00599 }
00600
00601 bool FlatTriangulator::Triangulate()
00602 {
00603 _newpoints.clear();
00604
00605
00606 std::vector<Base::Vector3f> aPoints = ProjectToFitPlane();
00607 std::vector<Base::Vector3f> tmp = aPoints;
00608
00609 std::sort(tmp.begin(), tmp.end(), Triangulation::Vertex2d_Less());
00610
00611 if (std::adjacent_find(tmp.begin(), tmp.end(),
00612 Triangulation::Vertex2d_EqualTo()) < tmp.end() )
00613 return false;
00614
00615 _facets.clear();
00616 _triangles.clear();
00617
00618
00619 QuasiDelaunayTriangulator tria;
00620 tria.SetPolygon(this->GetPolygon());
00621 bool succeeded = tria.TriangulatePolygon();
00622 this->_facets = tria.GetFacets();
00623 this->_triangles = tria.GetTriangles();
00624
00625 return succeeded;
00626 }
00627
00628 void FlatTriangulator::ProjectOntoSurface(const std::vector<Base::Vector3f>&)
00629 {
00630 }
00631
00632
00633
00634 ConstraintDelaunayTriangulator::ConstraintDelaunayTriangulator(float area)
00635 : fMaxArea(area)
00636 {
00637 }
00638
00639 ConstraintDelaunayTriangulator::~ConstraintDelaunayTriangulator()
00640 {
00641 }
00642
00643 bool ConstraintDelaunayTriangulator::Triangulate()
00644 {
00645 _newpoints.clear();
00646
00647
00648 std::vector<Base::Vector3f> aPoints = ProjectToFitPlane();
00649 std::vector<Base::Vector3f> tmp = aPoints;
00650
00651 std::sort(tmp.begin(), tmp.end(), Triangulation::Vertex2d_Less());
00652
00653 if (std::adjacent_find(tmp.begin(), tmp.end(),
00654 Triangulation::Vertex2d_EqualTo()) < tmp.end() )
00655 return false;
00656
00657 _facets.clear();
00658 _triangles.clear();
00659
00660
00661 QuasiDelaunayTriangulator tria;
00662 tria.SetPolygon(this->GetPolygon());
00663 bool succeeded = tria.TriangulatePolygon();
00664 this->_facets = tria.GetFacets();
00665 this->_triangles = tria.GetTriangles();
00666
00667 return succeeded;
00668 }
00669
00670
00671
00672 Triangulator::Triangulator(const MeshKernel& k) : _kernel(k)
00673 {
00674 }
00675
00676 Triangulator::~Triangulator()
00677 {
00678 }
00679
00680 bool Triangulator::Triangulate()
00681 {
00682 return false;
00683 }