00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4TriangulateEC.h"
00019 #include "Wm4Query2Filtered.h"
00020 #include "Wm4Query2Int64.h"
00021 #include "Wm4Query2TInteger.h"
00022 #include "Wm4Query2TRational.h"
00023
00024 namespace Wm4
00025 {
00026
00027 template <class Real>
00028 TriangulateEC<Real>::TriangulateEC (const Positions& rkPositions,
00029 Query::Type eQueryType, Real fEpsilon, Indices& rkTriangles)
00030 {
00031
00032 InitializePositions(rkPositions,eQueryType,fEpsilon,0);
00033
00034
00035 int iVQuantity = (int)rkPositions.size();
00036 const int* aiIndex = 0;
00037 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00038 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00039 }
00040
00041 template <class Real>
00042 TriangulateEC<Real>::TriangulateEC (const Positions& rkPositions,
00043 Query::Type eQueryType, Real fEpsilon, const Indices& rkPolygon,
00044 Indices& rkTriangles)
00045 {
00046
00047 InitializePositions(rkPositions,eQueryType,fEpsilon,0);
00048
00049
00050 int iVQuantity = (int)rkPolygon.size();
00051 const int* aiIndex = &rkPolygon[0];
00052 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00053 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00054 }
00055
00056 template <class Real>
00057 TriangulateEC<Real>::TriangulateEC (const Positions& rkPositions,
00058 Query::Type eQueryType, Real fEpsilon, const Indices& rkOuter,
00059 const Indices& rkInner, Indices& rkTriangles)
00060 {
00061
00062
00063 InitializePositions(rkPositions,eQueryType,fEpsilon,2);
00064
00065
00066
00067
00068 int iNextElement = (int)rkPositions.size();
00069 IndexMap kMap;
00070 Indices kCombined;
00071 CombinePolygons(eQueryType,fEpsilon,iNextElement,rkOuter,rkInner,kMap,
00072 kCombined);
00073
00074
00075
00076 int iVQuantity = (int)kCombined.size();
00077 const int* aiIndex = &kCombined[0];
00078 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00079 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00080
00081
00082 RemapIndices(kMap,rkTriangles);
00083 }
00084
00085 template <class Real>
00086 TriangulateEC<Real>::TriangulateEC (const Positions& rkPositions,
00087 Query::Type eQueryType, Real fEpsilon, const Indices& rkOuter,
00088 const IndicesArray& rkInners, Indices& rkTriangles)
00089 {
00090
00091
00092 int iNumInners = (int)rkInners.size();
00093 int iExtraElements = 2*iNumInners;
00094 InitializePositions(rkPositions,eQueryType,fEpsilon,iExtraElements);
00095
00096
00097
00098
00099 int iNextElement = (int)rkPositions.size();
00100 Indices kCombined;
00101 IndexMap kMap;
00102 ProcessOuterAndInners(eQueryType,fEpsilon,rkOuter,rkInners,iNextElement,
00103 kMap,kCombined);
00104
00105
00106
00107 int iVQuantity = (int)kCombined.size();
00108 const int* aiIndex = &kCombined[0];
00109 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00110 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00111
00112
00113 RemapIndices(kMap,rkTriangles);
00114 }
00115
00116 template <class Real>
00117 TriangulateEC<Real>::TriangulateEC (const Positions& rkPositions,
00118 Query::Type eQueryType, Real fEpsilon, const Tree* pkTree,
00119 Indices& rkTriangles)
00120 {
00121
00122
00123 int iExtraElements = GetExtraElements(pkTree);
00124 InitializePositions(rkPositions,eQueryType,fEpsilon,iExtraElements);
00125
00126 int iNextElement = (int)rkPositions.size();
00127 IndexMap kMap;
00128
00129 std::queue<const Tree*> kQueue;
00130 kQueue.push(pkTree);
00131 while (kQueue.size() > 0)
00132 {
00133 const Tree* pkOuterNode = kQueue.front();
00134 kQueue.pop();
00135
00136 int iNumChildren = (int)pkOuterNode->Child.size();
00137 int iVQuantity;
00138 const int* aiIndex;
00139
00140 if (iNumChildren == 0)
00141 {
00142
00143
00144 iVQuantity = (int)pkOuterNode->Polygon.size();
00145 aiIndex = &pkOuterNode->Polygon[0];
00146 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00147 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00148 }
00149 else
00150 {
00151
00152
00153 std::vector<std::vector<int>*> kInners(iNumChildren);
00154 for (int i = 0; i < iNumChildren; i++)
00155 {
00156 const Tree* pkInnerNode = pkOuterNode->Child[i];
00157 kInners[i] = (std::vector<int>*)&pkInnerNode->Polygon;
00158 int iNumGrandChildren = (int)pkInnerNode->Child.size();
00159 for (int j = 0; j < iNumGrandChildren; j++)
00160 {
00161 kQueue.push(pkInnerNode->Child[j]);
00162 }
00163 }
00164
00165
00166
00167
00168 std::vector<int> kCombined;
00169 ProcessOuterAndInners(eQueryType,fEpsilon,pkOuterNode->Polygon,
00170 kInners,iNextElement,kMap,kCombined);
00171
00172
00173
00174 iVQuantity = (int)kCombined.size();
00175 aiIndex = &kCombined[0];
00176 InitializeVertices(iVQuantity,aiIndex,rkTriangles);
00177 DoEarClipping(iVQuantity,aiIndex,rkTriangles);
00178 }
00179 }
00180
00181
00182 RemapIndices(kMap,rkTriangles);
00183 }
00184
00185 template <class Real>
00186 TriangulateEC<Real>::~TriangulateEC ()
00187 {
00188 WM4_DELETE m_pkQuery;
00189 }
00190
00191 template <class Real>
00192 void TriangulateEC<Real>::InitializePositions (const Positions& rkPositions,
00193 Query::Type eQueryType, Real fEpsilon, int iExtraElements)
00194 {
00195 int iPQuantity = (int)rkPositions.size();
00196 assert(iPQuantity >= 3);
00197 int iPEQuantity = iPQuantity + iExtraElements;
00198 m_kSPositions.resize(iPEQuantity);
00199
00200 if (eQueryType == Query::QT_FILTERED)
00201 {
00202 assert((Real)0.0 <= fEpsilon && fEpsilon <= (Real)1.0);
00203 }
00204
00205 Vector2<Real> kMin, kMax, kRange;
00206 Real fScale, fRMax;
00207 int i;
00208
00209 switch (eQueryType)
00210 {
00211 case Query::QT_INT64:
00212
00213 Vector2<Real>::ComputeExtremes(iPQuantity,&rkPositions[0],kMin,kMax);
00214 kRange = kMax - kMin;
00215 fRMax = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
00216 fScale = ((Real)(1 << 20))/fRMax;
00217 for (i = 0; i < iPQuantity; i++)
00218 {
00219 m_kSPositions[i] = (rkPositions[i] - kMin)*fScale;
00220 }
00221 m_pkQuery = WM4_NEW Query2Int64<Real>(iPEQuantity,&m_kSPositions[0]);
00222 return;
00223
00224 case Query::QT_INTEGER:
00225
00226 Vector2<Real>::ComputeExtremes(iPQuantity,&rkPositions[0],kMin,kMax);
00227 kRange = kMax - kMin;
00228 fRMax = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
00229 fScale = ((Real)(1 << 24))/fRMax;
00230 for (i = 0; i < iPQuantity; i++)
00231 {
00232 m_kSPositions[i] = (rkPositions[i] - kMin)*fScale;
00233 }
00234 m_pkQuery = WM4_NEW Query2TInteger<Real>(iPEQuantity,
00235 &m_kSPositions[0]);
00236 return;
00237
00238 case Query::QT_REAL:
00239
00240 Vector2<Real>::ComputeExtremes(iPQuantity,&rkPositions[0],kMin,kMax);
00241 kRange = kMax - kMin;
00242 fRMax = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
00243 fScale = ((Real)1.0)/fRMax;
00244 for (i = 0; i < iPQuantity; i++)
00245 {
00246 m_kSPositions[i] = (rkPositions[i] - kMin)*fScale;
00247 }
00248 m_pkQuery = WM4_NEW Query2<Real>(iPEQuantity,&m_kSPositions[0]);
00249 return;
00250
00251 case Query::QT_RATIONAL:
00252
00253
00254 for (i = 0; i < iPQuantity; i++)
00255 {
00256 m_kSPositions[i] = rkPositions[i];
00257 }
00258 m_pkQuery = WM4_NEW Query2TRational<Real>(iPEQuantity,
00259 &m_kSPositions[0]);
00260 return;
00261
00262 case Query::QT_FILTERED:
00263
00264
00265 for (i = 0; i < iPQuantity; i++)
00266 {
00267 m_kSPositions[i] = rkPositions[i];
00268 }
00269 m_pkQuery = WM4_NEW Query2Filtered<Real>(iPEQuantity,
00270 &m_kSPositions[0],fEpsilon);
00271 return;
00272 }
00273
00274 assert(false);
00275 }
00276
00277 template <class Real>
00278 void TriangulateEC<Real>::InitializeVertices (int iVQuantity,
00279 const int* aiIndex, std::vector<int>& rkTriangle)
00280 {
00281 m_kVertex.clear();
00282 m_kVertex.resize(iVQuantity);
00283 m_iCFirst = -1;
00284 m_iCLast = -1;
00285 m_iRFirst = -1;
00286 m_iRLast = -1;
00287 m_iEFirst = -1;
00288 m_iELast = -1;
00289
00290
00291
00292 int iVQm1 = iVQuantity - 1;
00293 int i;
00294 for (i = 0; i <= iVQm1; i++)
00295 {
00296 Vertex& rkV = V(i);
00297 rkV.Index = (aiIndex ? aiIndex[i] : i);
00298 rkV.VPrev = (i > 0 ? i-1 : iVQm1);
00299 rkV.VNext = (i < iVQm1 ? i+1 : 0);
00300 }
00301
00302
00303
00304
00305
00306 for (i = 0; i <= iVQm1; i++)
00307 {
00308 if (IsConvex(i))
00309 {
00310 InsertAfterC(i);
00311 }
00312 else
00313 {
00314 InsertAfterR(i);
00315 }
00316 }
00317 }
00318
00319 template <class Real>
00320 void TriangulateEC<Real>::DoEarClipping (int iVQuantity, const int* aiIndex,
00321 std::vector<int>& rkTriangle)
00322 {
00323
00324 int i;
00325 if (m_iRFirst == -1)
00326 {
00327 int iVQm1 = iVQuantity - 1;
00328 if (aiIndex)
00329 {
00330 for (i = 1; i < iVQm1; i++)
00331 {
00332 rkTriangle.push_back(aiIndex[0]);
00333 rkTriangle.push_back(aiIndex[i]);
00334 rkTriangle.push_back(aiIndex[i+1]);
00335 }
00336 }
00337 else
00338 {
00339 for (i = 1; i < iVQm1; i++)
00340 {
00341 rkTriangle.push_back(0);
00342 rkTriangle.push_back(i);
00343 rkTriangle.push_back(i+1);
00344 }
00345 }
00346 return;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 for (i = m_iCFirst; i != -1; i = V(i).SNext)
00358 {
00359 if (IsEar(i))
00360 {
00361 InsertEndE(i);
00362 }
00363 }
00364 V(m_iEFirst).EPrev = m_iELast;
00365 V(m_iELast).ENext = m_iEFirst;
00366
00367
00368 while (true)
00369 {
00370
00371 int iVPrev = V(m_iEFirst).VPrev;
00372 int iVNext = V(m_iEFirst).VNext;
00373 rkTriangle.push_back(V(iVPrev).Index);
00374 rkTriangle.push_back(V(m_iEFirst).Index);
00375 rkTriangle.push_back(V(iVNext).Index);
00376
00377
00378 RemoveV(m_iEFirst);
00379 if (--iVQuantity == 3)
00380 {
00381
00382 m_iEFirst = RemoveE(m_iEFirst);
00383 iVPrev = V(m_iEFirst).VPrev;
00384 iVNext = V(m_iEFirst).VNext;
00385 rkTriangle.push_back(V(iVPrev).Index);
00386 rkTriangle.push_back(V(m_iEFirst).Index);
00387 rkTriangle.push_back(V(iVNext).Index);
00388 break;
00389 }
00390
00391
00392
00393 Vertex& rkVPrev = V(iVPrev);
00394 if (rkVPrev.IsEar)
00395 {
00396 if (!IsEar(iVPrev))
00397 {
00398 RemoveE(iVPrev);
00399 }
00400 }
00401 else
00402 {
00403 bool bWasReflex = !rkVPrev.IsConvex;
00404 if (IsConvex(iVPrev))
00405 {
00406 if (bWasReflex)
00407 {
00408 RemoveR(iVPrev);
00409 }
00410
00411 if (IsEar(iVPrev))
00412 {
00413 InsertBeforeE(iVPrev);
00414 }
00415 }
00416 }
00417
00418 Vertex& rkVNext = V(iVNext);
00419 if (rkVNext.IsEar)
00420 {
00421 if (!IsEar(iVNext))
00422 {
00423 RemoveE(iVNext);
00424 }
00425 }
00426 else
00427 {
00428 bool bWasReflex = !rkVNext.IsConvex;
00429 if (IsConvex(iVNext))
00430 {
00431 if (bWasReflex)
00432 {
00433 RemoveR(iVNext);
00434 }
00435
00436 if (IsEar(iVNext))
00437 {
00438 InsertAfterE(iVNext);
00439 }
00440 }
00441 }
00442
00443
00444 m_iEFirst = RemoveE(m_iEFirst);
00445 }
00446 }
00447
00448 template <class Real>
00449 int TriangulateEC<Real>::TriangleQuery (const Vector2<Real>& rkPoint,
00450 Query::Type eQueryType, Real fEpsilon, const Vector2<Real> akSTriangle[3])
00451 const
00452 {
00453 switch (eQueryType)
00454 {
00455 case Query::QT_INT64:
00456 return Query2Int64<Real>(3,akSTriangle).ToTriangle(rkPoint,0,1,2);
00457
00458 case Query::QT_INTEGER:
00459 return Query2TInteger<Real>(3,akSTriangle).ToTriangle(rkPoint,0,1,2);
00460
00461 case Query::QT_REAL:
00462 return Query2<Real>(3,akSTriangle).ToTriangle(rkPoint,0,1,2);
00463
00464 case Query::QT_RATIONAL:
00465 return Query2TRational<Real>(3,akSTriangle).ToTriangle(rkPoint,0,1,2);
00466
00467 case Query::QT_FILTERED:
00468 return Query2Filtered<Real>(3,akSTriangle,fEpsilon).ToTriangle(
00469 rkPoint,0,1,2);
00470 }
00471
00472 assert(false);
00473 return 1;
00474 }
00475
00476 template <class Real>
00477 void TriangulateEC<Real>::CombinePolygons (Query::Type eQueryType,
00478 Real fEpsilon, int iNextElement, const Indices& rkOuter,
00479 const Indices& rkInner, IndexMap& rkMap, Indices& rkCombined)
00480 {
00481 int iOQuantity = (int)rkOuter.size();
00482 int iIQuantity = (int)rkInner.size();
00483
00484
00485 Real fXMax = m_kSPositions[rkInner[0]][0];
00486 int iXMaxIndex = 0;
00487 int i;
00488 for (i = 1; i < iIQuantity; i++)
00489 {
00490 Real fX = m_kSPositions[rkInner[i]][0];
00491 if (fX > fXMax)
00492 {
00493 fXMax = fX;
00494 iXMaxIndex = i;
00495 }
00496 }
00497 Vector2<Real> kM = m_kSPositions[rkInner[iXMaxIndex]];
00498
00499
00500
00501 Vector2<Real> kIntr(Math<Real>::MAX_REAL,kM[1]);
00502 int iV0Min = -1, iV1Min = -1, iEndMin = -1;
00503 int i0, i1;
00504 for (i0 = iOQuantity-1, i1 = 0; i1 < iOQuantity; i0 = i1++)
00505 {
00506
00507
00508 Vector2<Real> kDiff0 = m_kSPositions[rkOuter[i0]] - kM;
00509 if (kDiff0[1] > (Real)0.0)
00510 {
00511 continue;
00512 }
00513 Vector2<Real> kDiff1 = m_kSPositions[rkOuter[i1]] - kM;
00514 if (kDiff1[1] < (Real)0.0)
00515 {
00516 continue;
00517 }
00518
00519
00520 Real fS, fT;
00521 int iCurrentEndMin = -1;
00522 if (kDiff0[1] < (Real)0.0)
00523 {
00524 if (kDiff1[1] > (Real)0.0)
00525 {
00526
00527
00528 fS = kDiff0[1]/(kDiff0[1] - kDiff1[1]);
00529 fT = kDiff0[0] + fS*(kDiff1[0] - kDiff0[0]);
00530 }
00531 else
00532 {
00533
00534
00535 fT = kDiff1[0];
00536 iCurrentEndMin = i1;
00537 }
00538 }
00539 else
00540 {
00541 if (kDiff1[1] > (Real)0.0)
00542 {
00543
00544
00545 fT = kDiff0[0];
00546 iCurrentEndMin = i0;
00547 }
00548 else
00549 {
00550 if (kDiff0[0] < kDiff1[0])
00551 {
00552 fT = kDiff0[0];
00553 iCurrentEndMin = i0;
00554 }
00555 else
00556 {
00557 fT = kDiff1[0];
00558 iCurrentEndMin = i1;
00559 }
00560 }
00561 }
00562
00563 if ((Real)0.0 <= fT && fT < kIntr[0])
00564 {
00565 kIntr[0] = fT;
00566 iV0Min = i0;
00567 iV1Min = i1;
00568 if (iCurrentEndMin == -1)
00569 {
00570
00571 iEndMin = -1;
00572 }
00573 else
00574 {
00575
00576 iEndMin = iCurrentEndMin;
00577 }
00578 }
00579 }
00580
00581 int iMaxCosIndex;
00582 if (iEndMin == -1)
00583 {
00584
00585
00586
00587
00588 Vector2<Real> akSTriangle[3];
00589 int iPIndex;
00590 if (m_kSPositions[rkOuter[iV0Min]][0] >
00591 m_kSPositions[rkOuter[iV1Min]][0])
00592 {
00593 akSTriangle[0] = m_kSPositions[rkOuter[iV0Min]];
00594 akSTriangle[1] = kIntr;
00595 akSTriangle[2] = kM;
00596 iPIndex = iV0Min;
00597 }
00598 else
00599 {
00600 akSTriangle[0] = m_kSPositions[rkOuter[iV1Min]];
00601 akSTriangle[1] = kM;
00602 akSTriangle[2] = kIntr;
00603 iPIndex = iV1Min;
00604 }
00605
00606
00607
00608
00609
00610
00611 Vector2<Real> kDiff = akSTriangle[0] - kM;
00612 Real fMaxSqrLen = kDiff.SquaredLength();
00613 Real fMaxCos = kDiff[0]*kDiff[0]/fMaxSqrLen;
00614 iMaxCosIndex = iPIndex;
00615 for (i = 0; i < iOQuantity; i++)
00616 {
00617 if (i == iPIndex)
00618 {
00619 continue;
00620 }
00621
00622 int iCurr = rkOuter[i];
00623 int iPrev = rkOuter[(i+iOQuantity-1) % iOQuantity];
00624 int iNext = rkOuter[(i+1) % iOQuantity];
00625 if (m_pkQuery->ToLine(iCurr,iPrev,iNext) <= 0
00626 && TriangleQuery(m_kSPositions[iCurr],eQueryType,fEpsilon,
00627 akSTriangle) <= 0)
00628 {
00629
00630 kDiff = m_kSPositions[iCurr] - kM;
00631 Real fSqrLen = kDiff.SquaredLength();
00632 Real fCos = kDiff[0]*kDiff[0]/fSqrLen;
00633 if (fCos > fMaxCos)
00634 {
00635
00636
00637
00638 fMaxSqrLen = fSqrLen;
00639 fMaxCos = fCos;
00640 iMaxCosIndex = i;
00641 }
00642 else if (fCos == fMaxCos && fSqrLen < fMaxSqrLen)
00643 {
00644
00645
00646
00647 fMaxSqrLen = fSqrLen;
00648 iMaxCosIndex = i;
00649 }
00650 }
00651 }
00652 }
00653 else
00654 {
00655 iMaxCosIndex = iEndMin;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665 rkCombined.resize(iOQuantity+iIQuantity+2);
00666 int iCIndex = 0;
00667 for (i = 0; i <= iMaxCosIndex; i++, iCIndex++)
00668 {
00669 rkCombined[iCIndex] = rkOuter[i];
00670 }
00671
00672 for (i = 0; i < iIQuantity; i++, iCIndex++)
00673 {
00674 int j = (iXMaxIndex + i) % iIQuantity;
00675 rkCombined[iCIndex] = rkInner[j];
00676 }
00677
00678 int iInnerIndex = rkInner[iXMaxIndex];
00679 m_kSPositions[iNextElement] = m_kSPositions[iInnerIndex];
00680 rkCombined[iCIndex] = iNextElement;
00681 IndexMap::iterator pkIter = rkMap.find(iInnerIndex);
00682 if (pkIter != rkMap.end())
00683 {
00684 iInnerIndex = pkIter->second;
00685 }
00686 rkMap[iNextElement] = iInnerIndex;
00687 iCIndex++;
00688 iNextElement++;
00689
00690 int iOuterIndex = rkOuter[iMaxCosIndex];
00691 m_kSPositions[iNextElement] = m_kSPositions[iOuterIndex];
00692 rkCombined[iCIndex] = iNextElement;
00693 pkIter = rkMap.find(iOuterIndex);
00694 if (pkIter != rkMap.end())
00695 {
00696 iOuterIndex = pkIter->second;
00697 }
00698 rkMap[iNextElement] = iOuterIndex;
00699 iCIndex++;
00700 iNextElement++;
00701
00702 for (i = iMaxCosIndex+1; i < iOQuantity; i++, iCIndex++)
00703 {
00704 rkCombined[iCIndex] = rkOuter[i];
00705 }
00706 }
00707
00708 template <class Real>
00709 void TriangulateEC<Real>::ProcessOuterAndInners (Query::Type eQueryType,
00710 Real fEpsilon, const Indices& rkOuter, const IndicesArray& rkInners,
00711 int& riNextElement, IndexMap& rkMap, Indices& rkCombined)
00712 {
00713
00714 int iNumInners = (int)rkInners.size();
00715 std::vector<std::pair<Real,int> > kPairs(iNumInners);
00716 int i;
00717 for (i = 0; i < iNumInners; i++)
00718 {
00719 const Indices& rkInner = *rkInners[i];
00720 int iVQuantity = (int)rkInner.size();
00721 Real fXMax = m_kSPositions[rkInner[0]][0];
00722 for (int j = 1; j < iVQuantity; j++)
00723 {
00724 Real fX = m_kSPositions[rkInner[j]][0];
00725 if (fX > fXMax)
00726 {
00727 fXMax = fX;
00728 }
00729 }
00730 kPairs[i].first = fXMax;
00731 kPairs[i].second = i;
00732 }
00733 std::sort(kPairs.begin(),kPairs.end());
00734
00735
00736 Indices kCurrentOuter = rkOuter;
00737 for (i = iNumInners-1; i >= 0; i--)
00738 {
00739 const Indices& rkInner = *rkInners[kPairs[i].second];
00740 Indices kCurrentCombined;
00741 CombinePolygons(eQueryType,fEpsilon,riNextElement,kCurrentOuter,
00742 rkInner,rkMap,kCurrentCombined);
00743 kCurrentOuter = kCurrentCombined;
00744 riNextElement += 2;
00745 }
00746
00747 for (i = 0; i < (int)kCurrentOuter.size(); i++)
00748 {
00749 rkCombined.push_back(kCurrentOuter[i]);
00750 }
00751 }
00752
00753 template <class Real>
00754 void TriangulateEC<Real>::RemapIndices (const IndexMap& rkMap,
00755 Indices& rkTriangles) const
00756 {
00757
00758
00759 for (int i = 0; i < (int)rkTriangles.size(); i++)
00760 {
00761 IndexMap::const_iterator pkIter = rkMap.find(rkTriangles[i]);
00762 if (pkIter != rkMap.end())
00763 {
00764 rkTriangles[i] = pkIter->second;
00765 }
00766 }
00767 }
00768
00769
00770
00771
00772
00773 template <class Real>
00774 typename TriangulateEC<Real>::Vertex& TriangulateEC<Real>::V (int i)
00775 {
00776 return m_kVertex[i];
00777 }
00778
00779 template <class Real>
00780 bool TriangulateEC<Real>::IsConvex (int i)
00781 {
00782 Vertex& rkV = V(i);
00783 int iCurr = rkV.Index;
00784 int iPrev = V(rkV.VPrev).Index;
00785 int iNext = V(rkV.VNext).Index;
00786 rkV.IsConvex = (m_pkQuery->ToLine(iCurr,iPrev,iNext) > 0);
00787 return rkV.IsConvex;
00788 }
00789
00790 template <class Real>
00791 bool TriangulateEC<Real>::IsEar (int i)
00792 {
00793 Vertex& rkV = V(i);
00794
00795 if (m_iRFirst == -1)
00796 {
00797
00798 rkV.IsEar = true;
00799 return true;
00800 }
00801
00802
00803
00804 int iPrev = V(rkV.VPrev).Index;
00805 int iCurr = rkV.Index;
00806 int iNext = V(rkV.VNext).Index;
00807 rkV.IsEar = true;
00808 for (int j = m_iRFirst; j != -1; j = V(j).SNext)
00809 {
00810
00811 if (j == rkV.VPrev || j == i || j == rkV.VNext)
00812 {
00813 continue;
00814 }
00815
00816
00817
00818
00819
00820 int iTest = V(j).Index;
00821 if (m_kSPositions[iTest] == m_kSPositions[iPrev]
00822 || m_kSPositions[iTest] == m_kSPositions[iCurr]
00823 || m_kSPositions[iTest] == m_kSPositions[iNext])
00824 {
00825 continue;
00826 }
00827
00828
00829
00830 if (m_pkQuery->ToTriangle(iTest,iPrev,iCurr,iNext) <= 0)
00831 {
00832 rkV.IsEar = false;
00833 break;
00834 }
00835 }
00836
00837 return rkV.IsEar;
00838 }
00839
00840 template <class Real>
00841 void TriangulateEC<Real>::InsertAfterC (int i)
00842 {
00843 if (m_iCFirst == -1)
00844 {
00845
00846 m_iCFirst = i;
00847 }
00848 else
00849 {
00850 V(m_iCLast).SNext = i;
00851 V(i).SPrev = m_iCLast;
00852 }
00853 m_iCLast = i;
00854 }
00855
00856 template <class Real>
00857 void TriangulateEC<Real>::InsertAfterR (int i)
00858 {
00859 if (m_iRFirst == -1)
00860 {
00861
00862 m_iRFirst = i;
00863 }
00864 else
00865 {
00866 V(m_iRLast).SNext = i;
00867 V(i).SPrev = m_iRLast;
00868 }
00869 m_iRLast = i;
00870 }
00871
00872 template <class Real>
00873 void TriangulateEC<Real>::InsertEndE (int i)
00874 {
00875 if (m_iEFirst == -1)
00876 {
00877
00878 m_iEFirst = i;
00879 m_iELast = i;
00880 }
00881 V(m_iELast).ENext = i;
00882 V(i).EPrev = m_iELast;
00883 m_iELast = i;
00884 }
00885
00886 template <class Real>
00887 void TriangulateEC<Real>::InsertAfterE (int i)
00888 {
00889 Vertex& rkVFirst = V(m_iEFirst);
00890 int iCurrENext = rkVFirst.ENext;
00891 Vertex& rkV = V(i);
00892 rkV.EPrev = m_iEFirst;
00893 rkV.ENext = iCurrENext;
00894 rkVFirst.ENext = i;
00895 V(iCurrENext).EPrev = i;
00896 }
00897
00898 template <class Real>
00899 void TriangulateEC<Real>::InsertBeforeE (int i)
00900 {
00901 Vertex& rkVFirst = V(m_iEFirst);
00902 int iCurrEPrev = rkVFirst.EPrev;
00903 Vertex& rkV = V(i);
00904 rkV.EPrev = iCurrEPrev;
00905 rkV.ENext = m_iEFirst;
00906 rkVFirst.EPrev = i;
00907 V(iCurrEPrev).ENext = i;
00908 }
00909
00910 template <class Real>
00911 void TriangulateEC<Real>::RemoveV (int i)
00912 {
00913 int iCurrVPrev = V(i).VPrev;
00914 int iCurrVNext = V(i).VNext;
00915 V(iCurrVPrev).VNext = iCurrVNext;
00916 V(iCurrVNext).VPrev = iCurrVPrev;
00917 }
00918
00919 template <class Real>
00920 int TriangulateEC<Real>::RemoveE (int i)
00921 {
00922 int iCurrEPrev = V(i).EPrev;
00923 int iCurrENext = V(i).ENext;
00924 V(iCurrEPrev).ENext = iCurrENext;
00925 V(iCurrENext).EPrev = iCurrEPrev;
00926 return iCurrENext;
00927 }
00928
00929 template <class Real>
00930 void TriangulateEC<Real>::RemoveR (int i)
00931 {
00932 assert(m_iRFirst != -1 && m_iRLast != -1);
00933
00934 if (i == m_iRFirst)
00935 {
00936 m_iRFirst = V(i).SNext;
00937 if (m_iRFirst != -1)
00938 {
00939 V(m_iRFirst).SPrev = -1;
00940 }
00941 V(i).SNext = -1;
00942 }
00943 else if (i == m_iRLast)
00944 {
00945 m_iRLast = V(i).SPrev;
00946 if (m_iRLast != -1)
00947 {
00948 V(m_iRLast).SNext = -1;
00949 }
00950 V(i).SPrev = -1;
00951 }
00952 else
00953 {
00954 int iCurrSPrev = V(i).SPrev;
00955 int iCurrSNext = V(i).SNext;
00956 V(iCurrSPrev).SNext = iCurrSNext;
00957 V(iCurrSNext).SPrev = iCurrSPrev;
00958 V(i).SNext = -1;
00959 V(i).SPrev = -1;
00960 }
00961 }
00962
00963
00964
00965
00966
00967 template <class Real>
00968 void TriangulateEC<Real>::Delete (Tree*& rpkRoot)
00969 {
00970 if (rpkRoot)
00971 {
00972 std::queue<Tree*> kQueue;
00973 kQueue.push(rpkRoot);
00974
00975 while (kQueue.size() > 0)
00976 {
00977 Tree* pkTree = kQueue.front();
00978 kQueue.pop();
00979 for (int i = 0; i < (int)pkTree->Child.size(); i++)
00980 {
00981 kQueue.push(pkTree->Child[i]);
00982 }
00983 WM4_DELETE pkTree;
00984 }
00985
00986 rpkRoot = 0;
00987 }
00988 }
00989
00990 template <class Real>
00991 int TriangulateEC<Real>::GetExtraElements (const Tree* pkTree)
00992 {
00993 int iExtraElements = 0;
00994
00995 std::queue<const Tree*> kQueue;
00996 kQueue.push(pkTree);
00997 while (kQueue.size() > 0)
00998 {
00999 const Tree* pkRoot = kQueue.front();
01000 kQueue.pop();
01001 int iNumChildren = (int)pkRoot->Child.size();
01002 iExtraElements += 2*iNumChildren;
01003
01004 for (int i = 0; i < iNumChildren; i++)
01005 {
01006 const Tree* pkChild = pkRoot->Child[i];
01007 int iNumGrandChildren = (int)pkChild->Child.size();
01008 for (int j = 0; j < iNumGrandChildren; j++)
01009 {
01010 kQueue.push(pkChild->Child[j]);
01011 }
01012 }
01013 }
01014
01015 return iExtraElements;
01016 }
01017
01018
01019
01020
01021
01022 template WM4_FOUNDATION_ITEM
01023 class TriangulateEC<float>;
01024
01025 template WM4_FOUNDATION_ITEM
01026 class TriangulateEC<double>;
01027
01028 }