00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4Delaunay2.h"
00019 #include "Wm4DelPolygonEdge.h"
00020 #include "Wm4Mapper2.h"
00021 #include "Wm4VEManifoldMesh.h"
00022 #include "Wm4Query2Filtered.h"
00023 #include "Wm4Query2Int64.h"
00024 #include "Wm4Query2TInteger.h"
00025 #include "Wm4Query2TRational.h"
00026
00027 namespace Wm4
00028 {
00029
00030 template <class Real>
00031 Delaunay2<Real>::Delaunay2 (int iVertexQuantity, Vector2<Real>* akVertex,
00032 Real fEpsilon, bool bOwner, Query::Type eQueryType)
00033 :
00034 Delaunay<Real>(iVertexQuantity,fEpsilon,bOwner,eQueryType),
00035 m_kLineOrigin(Vector2<Real>::ZERO),
00036 m_kLineDirection(Vector2<Real>::ZERO)
00037 {
00038 assert(akVertex);
00039 m_akVertex = akVertex;
00040 m_iUniqueVertexQuantity = 0;
00041 m_akSVertex = 0;
00042 m_pkQuery = 0;
00043 m_iPathLast = -1;
00044 m_aiPath = 0;
00045 m_iLastEdgeV0 = -1;
00046 m_iLastEdgeV1 = -1;
00047 m_iLastEdgeOpposite = -1;
00048 m_iLastEdgeOppositeIndex = -1;
00049
00050 Mapper2<Real> kMapper(m_iVertexQuantity,m_akVertex,m_fEpsilon);
00051 if (kMapper.GetDimension() == 0)
00052 {
00053
00054
00055 return;
00056 }
00057
00058 if (kMapper.GetDimension() == 1)
00059 {
00060
00061
00062 m_iDimension = 1;
00063 m_kLineOrigin = kMapper.GetOrigin();
00064 m_kLineDirection = kMapper.GetDirection(0);
00065 return;
00066 }
00067
00068 m_iDimension = 2;
00069
00070
00071
00072 m_akSVertex = WM4_NEW Vector2<Real>[m_iVertexQuantity+3];
00073 int i;
00074
00075 if (eQueryType != Query::QT_RATIONAL && eQueryType != Query::QT_FILTERED)
00076 {
00077
00078 m_kMin = kMapper.GetMin();
00079 m_fScale = ((Real)1.0)/kMapper.GetMaxRange();
00080 for (i = 0; i < m_iVertexQuantity; i++)
00081 {
00082 m_akSVertex[i] = (m_akVertex[i] - m_kMin)*m_fScale;
00083 }
00084
00085
00086 m_aiSV[0] = m_iVertexQuantity++;
00087 m_aiSV[1] = m_iVertexQuantity++;
00088 m_aiSV[2] = m_iVertexQuantity++;
00089 m_akSVertex[m_aiSV[0]] = Vector2<Real>((Real)-1.0,(Real)-1.0);
00090 m_akSVertex[m_aiSV[1]] = Vector2<Real>((Real)+4.0,(Real)-1.0);
00091 m_akSVertex[m_aiSV[2]] = Vector2<Real>((Real)-1.0,(Real)+4.0);
00092
00093 Real fExpand;
00094 if (eQueryType == Query::QT_INT64)
00095 {
00096
00097
00098 fExpand = (Real)(1 << 16);
00099 m_pkQuery = WM4_NEW Query2Int64<Real>(m_iVertexQuantity,
00100 m_akSVertex);
00101 }
00102 else if (eQueryType == Query::QT_INTEGER)
00103 {
00104
00105
00106
00107 fExpand = (Real)(1 << 20);
00108 m_pkQuery = WM4_NEW Query2TInteger<Real>(m_iVertexQuantity,
00109 m_akSVertex);
00110 }
00111 else
00112 {
00113
00114 fExpand = (Real)1.0;
00115 m_pkQuery = WM4_NEW Query2<Real>(m_iVertexQuantity,m_akSVertex);
00116 }
00117
00118 m_fScale *= fExpand;
00119 for (i = 0; i < m_iVertexQuantity; i++)
00120 {
00121 m_akSVertex[i] *= fExpand;
00122 }
00123 }
00124 else
00125 {
00126
00127 m_kMin = Vector2<Real>::ZERO;
00128 m_fScale = (Real)1.0;
00129 size_t uiSize = m_iVertexQuantity*sizeof(Vector2<Real>);
00130 System::Memcpy(m_akSVertex,uiSize,m_akVertex,uiSize);
00131
00132
00133 Vector2<Real> kMin = kMapper.GetMin();
00134 Vector2<Real> kMax = kMapper.GetMax();
00135 Vector2<Real> kDelta = kMax - kMin;
00136 Vector2<Real> kSMin = kMin - kDelta;
00137 Vector2<Real> kSMax = kMax + kDelta*((Real)3.0);
00138 m_aiSV[0] = m_iVertexQuantity++;
00139 m_aiSV[1] = m_iVertexQuantity++;
00140 m_aiSV[2] = m_iVertexQuantity++;
00141 m_akSVertex[m_aiSV[0]] = kSMin;
00142 m_akSVertex[m_aiSV[1]] = Vector2<Real>(kSMax[0],kSMin[1]);
00143 m_akSVertex[m_aiSV[2]] = Vector2<Real>(kSMin[0],kSMax[1]);
00144
00145 if (eQueryType == Query::QT_RATIONAL)
00146 {
00147 m_pkQuery = WM4_NEW Query2TRational<Real>(m_iVertexQuantity,
00148 m_akSVertex);
00149 }
00150 else
00151 {
00152 m_pkQuery = WM4_NEW Query2Filtered<Real>(m_iVertexQuantity,
00153 m_akSVertex,m_fEpsilon);
00154 }
00155 }
00156
00157 DelTriangle<Real>* pkTri = WM4_NEW DelTriangle<Real>(m_aiSV[0],m_aiSV[1],
00158 m_aiSV[2]);
00159 m_kTriangle.insert(pkTri);
00160
00161
00162
00163
00164 std::set<Vector2<Real> > kProcessed;
00165 for (i = 0; i < m_iVertexQuantity-3; i++)
00166 {
00167 if (kProcessed.find(m_akSVertex[i]) == kProcessed.end())
00168 {
00169 Update(i);
00170 kProcessed.insert(m_akSVertex[i]);
00171 }
00172 }
00173 m_iUniqueVertexQuantity = (int)kProcessed.size();
00174
00175
00176 RemoveTriangles();
00177
00178
00179 std::map<DelTriangle<Real>*,int> kPermute;
00180 typename std::set<DelTriangle<Real>*>::iterator pkTIter =
00181 m_kTriangle.begin();
00182 for (i = 0; pkTIter != m_kTriangle.end(); pkTIter++)
00183 {
00184 pkTri = *pkTIter;
00185 kPermute[pkTri] = i++;
00186 }
00187 kPermute[0] = -1;
00188
00189
00190 m_iSimplexQuantity = (int)m_kTriangle.size();
00191 if (m_iSimplexQuantity > 0)
00192 {
00193 m_aiIndex = WM4_NEW int[3*m_iSimplexQuantity];
00194 m_aiAdjacent = WM4_NEW int[3*m_iSimplexQuantity];
00195 i = 0;
00196 pkTIter = m_kTriangle.begin();
00197 for (; pkTIter != m_kTriangle.end(); pkTIter++)
00198 {
00199 pkTri = *pkTIter;
00200 m_aiIndex[i] = pkTri->V[0];
00201 m_aiAdjacent[i++] = kPermute[pkTri->A[0]];
00202 m_aiIndex[i] = pkTri->V[1];
00203 m_aiAdjacent[i++] = kPermute[pkTri->A[1]];
00204 m_aiIndex[i] = pkTri->V[2];
00205 m_aiAdjacent[i++] = kPermute[pkTri->A[2]];
00206 }
00207 assert(i == 3*m_iSimplexQuantity);
00208
00209 m_iPathLast = -1;
00210 m_aiPath = WM4_NEW int[m_iSimplexQuantity+1];
00211 }
00212
00213
00214
00215 m_iVertexQuantity -= 3;
00216
00217 pkTIter = m_kTriangle.begin();
00218 for (; pkTIter != m_kTriangle.end(); ++pkTIter)
00219 {
00220 WM4_DELETE *pkTIter;
00221 }
00222 }
00223
00224 template <class Real>
00225 Delaunay2<Real>::~Delaunay2 ()
00226 {
00227 WM4_DELETE m_pkQuery;
00228 WM4_DELETE[] m_akSVertex;
00229 WM4_DELETE[] m_aiPath;
00230 if (m_bOwner)
00231 {
00232 WM4_DELETE[] m_akVertex;
00233 }
00234 }
00235
00236 template <class Real>
00237 const Vector2<Real>* Delaunay2<Real>::GetVertices () const
00238 {
00239 return m_akVertex;
00240 }
00241
00242 template <class Real>
00243 int Delaunay2<Real>::GetUniqueVertexQuantity () const
00244 {
00245 return m_iUniqueVertexQuantity;
00246 }
00247
00248 template <class Real>
00249 const Vector2<Real>& Delaunay2<Real>::GetLineOrigin () const
00250 {
00251 return m_kLineOrigin;
00252 }
00253
00254 template <class Real>
00255 const Vector2<Real>& Delaunay2<Real>::GetLineDirection () const
00256 {
00257 return m_kLineDirection;
00258 }
00259
00260 template <class Real>
00261 Delaunay1<Real>* Delaunay2<Real>::GetDelaunay1 () const
00262 {
00263 assert(m_iDimension == 1);
00264 if (m_iDimension != 1)
00265 {
00266 return 0;
00267 }
00268
00269 Real* afProjection = WM4_NEW Real[m_iVertexQuantity];
00270 for (int i = 0; i < m_iVertexQuantity; i++)
00271 {
00272 Vector2<Real> kDiff = m_akVertex[i] - m_kLineOrigin;
00273 afProjection[i] = m_kLineDirection.Dot(kDiff);
00274 }
00275
00276 return WM4_NEW Delaunay1<Real>(m_iVertexQuantity,afProjection,m_fEpsilon,
00277 true,m_eQueryType);
00278 }
00279
00280 template <class Real>
00281 bool Delaunay2<Real>::GetHull (int& riEQuantity, int*& raiIndex)
00282 {
00283 assert(m_iDimension == 2);
00284 if (m_iDimension != 2)
00285 {
00286 return false;
00287 }
00288
00289 riEQuantity = 0;
00290 raiIndex = 0;
00291
00292
00293 int i, iAdjQuantity = 3*m_iSimplexQuantity;
00294 for (i = 0; i < iAdjQuantity; i++)
00295 {
00296 if (m_aiAdjacent[i] == -1)
00297 {
00298 riEQuantity++;
00299 }
00300 }
00301 assert(riEQuantity > 0);
00302 if (riEQuantity == 0)
00303 {
00304 return false;
00305 }
00306
00307
00308 raiIndex = WM4_NEW int[2*riEQuantity];
00309 int* piIndex = raiIndex;
00310 for (i = 0; i < iAdjQuantity; i++)
00311 {
00312 if (m_aiAdjacent[i] == -1)
00313 {
00314 int iTri = i/3, j = i%3;
00315 *piIndex++ = m_aiIndex[3*iTri+j];
00316 *piIndex++ = m_aiIndex[3*iTri+((j+1)%3)];
00317 }
00318 }
00319
00320 return true;
00321 }
00322
00323 template <class Real>
00324 int Delaunay2<Real>::GetContainingTriangle (const Vector2<Real>& rkP) const
00325 {
00326 assert(m_iDimension == 2);
00327 if (m_iDimension != 2)
00328 {
00329 return -1;
00330 }
00331
00332
00333 Vector2<Real> kXFrmP = (rkP - m_kMin)*m_fScale;
00334
00335
00336 int iIndex = (m_iPathLast >= 0 ? m_aiPath[m_iPathLast] : 0);
00337 m_iPathLast = -1;
00338 m_iLastEdgeV0 = -1;
00339 m_iLastEdgeV1 = -1;
00340 m_iLastEdgeOpposite = -1;
00341 m_iLastEdgeOppositeIndex = -1;
00342
00343
00344 for (int i = 0; i < m_iSimplexQuantity; i++)
00345 {
00346 m_aiPath[++m_iPathLast] = iIndex;
00347
00348 int* aiV = &m_aiIndex[3*iIndex];
00349
00350 if (m_pkQuery->ToLine(kXFrmP,aiV[0],aiV[1]) > 0)
00351 {
00352 iIndex = m_aiAdjacent[3*iIndex];
00353 if (iIndex == -1)
00354 {
00355 m_iLastEdgeV0 = aiV[0];
00356 m_iLastEdgeV1 = aiV[1];
00357 m_iLastEdgeOpposite = aiV[2];
00358 m_iLastEdgeOppositeIndex = 2;
00359 return -1;
00360 }
00361 continue;
00362 }
00363
00364 if (m_pkQuery->ToLine(kXFrmP,aiV[1],aiV[2]) > 0)
00365 {
00366 iIndex = m_aiAdjacent[3*iIndex+1];
00367 if (iIndex == -1)
00368 {
00369 m_iLastEdgeV0 = aiV[1];
00370 m_iLastEdgeV1 = aiV[2];
00371 m_iLastEdgeOpposite = aiV[0];
00372 m_iLastEdgeOppositeIndex = 0;
00373 return -1;
00374 }
00375 continue;
00376 }
00377
00378 if (m_pkQuery->ToLine(kXFrmP,aiV[2],aiV[0]) > 0)
00379 {
00380 iIndex = m_aiAdjacent[3*iIndex+2];
00381 if (iIndex == -1)
00382 {
00383 m_iLastEdgeV0 = aiV[2];
00384 m_iLastEdgeV1 = aiV[0];
00385 m_iLastEdgeOpposite = aiV[1];
00386 m_iLastEdgeOppositeIndex = 1;
00387 return -1;
00388 }
00389 continue;
00390 }
00391
00392 m_iLastEdgeV0 = -1;
00393 m_iLastEdgeV1 = -1;
00394 m_iLastEdgeOpposite = -1;
00395 m_iLastEdgeOppositeIndex = -1;
00396 return iIndex;
00397 }
00398
00399 return -1;
00400 }
00401
00402 template <class Real>
00403 int Delaunay2<Real>::GetPathLast () const
00404 {
00405 return m_iPathLast;
00406 }
00407
00408 template <class Real>
00409 const int* Delaunay2<Real>::GetPath () const
00410 {
00411 return m_aiPath;
00412 }
00413
00414 template <class Real>
00415 int Delaunay2<Real>::GetLastEdge (int& riV0, int& riV1, int& riV2) const
00416 {
00417 riV0 = m_iLastEdgeV0;
00418 riV1 = m_iLastEdgeV1;
00419 riV2 = m_iLastEdgeOpposite;
00420 return m_iLastEdgeOppositeIndex;
00421 }
00422
00423 template <class Real>
00424 bool Delaunay2<Real>::GetVertexSet (int i, Vector2<Real> akV[3]) const
00425 {
00426 assert(m_iDimension == 2);
00427 if (m_iDimension != 2)
00428 {
00429 return false;
00430 }
00431
00432 if (0 <= i && i < m_iSimplexQuantity)
00433 {
00434 akV[0] = m_akVertex[m_aiIndex[3*i ]];
00435 akV[1] = m_akVertex[m_aiIndex[3*i+1]];
00436 akV[2] = m_akVertex[m_aiIndex[3*i+2]];
00437 return true;
00438 }
00439
00440 return false;
00441 }
00442
00443 template <class Real>
00444 bool Delaunay2<Real>::GetIndexSet (int i, int aiIndex[3]) const
00445 {
00446 assert(m_iDimension == 2);
00447 if (m_iDimension != 2)
00448 {
00449 return false;
00450 }
00451
00452 if (0 <= i && i < m_iSimplexQuantity)
00453 {
00454 aiIndex[0] = m_aiIndex[3*i ];
00455 aiIndex[1] = m_aiIndex[3*i+1];
00456 aiIndex[2] = m_aiIndex[3*i+2];
00457 return true;
00458 }
00459
00460 return false;
00461 }
00462
00463 template <class Real>
00464 bool Delaunay2<Real>::GetAdjacentSet (int i, int aiAdjacent[3]) const
00465 {
00466 assert(m_iDimension == 2);
00467 if (m_iDimension != 2)
00468 {
00469 return false;
00470 }
00471
00472 if (0 <= i && i < m_iSimplexQuantity)
00473 {
00474 aiAdjacent[0] = m_aiAdjacent[3*i ];
00475 aiAdjacent[1] = m_aiAdjacent[3*i+1];
00476 aiAdjacent[2] = m_aiAdjacent[3*i+2];
00477 return true;
00478 }
00479
00480 return false;
00481 }
00482
00483 template <class Real>
00484 bool Delaunay2<Real>::GetBarycentricSet (int i, const Vector2<Real>& rkP,
00485 Real afBary[3]) const
00486 {
00487 assert(m_iDimension == 2);
00488 if (m_iDimension != 2)
00489 {
00490 return false;
00491 }
00492
00493 if (0 <= i && i < m_iSimplexQuantity)
00494 {
00495 Vector2<Real> kV0 = m_akVertex[m_aiIndex[3*i ]];
00496 Vector2<Real> kV1 = m_akVertex[m_aiIndex[3*i+1]];
00497 Vector2<Real> kV2 = m_akVertex[m_aiIndex[3*i+2]];
00498 rkP.GetBarycentrics(kV0,kV1,kV2,afBary);
00499 return true;
00500 }
00501
00502 return false;
00503 }
00504
00505 template <class Real>
00506 void Delaunay2<Real>::Update (int i)
00507 {
00508
00509 DelTriangle<Real>* pkTri = GetContainingTriangle(i);
00510
00511
00512 std::stack<DelTriangle<Real>*> kStack;
00513 VEManifoldMesh kPolygon(0,DelPolygonEdge<Real>::ECreator);
00514 kStack.push(pkTri);
00515 pkTri->OnStack = true;
00516 int j, iV0, iV1;
00517 DelPolygonEdge<Real>* pkEdge;
00518 while (!kStack.empty())
00519 {
00520 pkTri = kStack.top();
00521 kStack.pop();
00522 pkTri->OnStack = false;
00523 for (j = 0; j < 3; j++)
00524 {
00525 DelTriangle<Real>* pkAdj = pkTri->A[j];
00526 if (pkAdj)
00527 {
00528
00529 int iNullIndex = pkTri->DetachFrom(j,pkAdj);
00530
00531 if (pkAdj->IsInsertionComponent(i,pkTri,m_pkQuery,m_aiSV))
00532 {
00533 if (!pkAdj->OnStack)
00534 {
00535
00536 kStack.push(pkAdj);
00537 pkAdj->OnStack = true;
00538 }
00539 }
00540 else
00541 {
00542
00543 iV0 = pkTri->V[j];
00544 iV1 = pkTri->V[(j+1)%3];
00545 pkEdge = (DelPolygonEdge<Real>*)kPolygon.InsertEdge(iV0,
00546 iV1);
00547 pkEdge->NullIndex = iNullIndex;
00548 pkEdge->Tri = pkAdj;
00549 }
00550 }
00551 else
00552 {
00553
00554
00555
00556
00557
00558
00559
00560
00561 iV0 = pkTri->V[j];
00562 if (IsSupervertex(iV0))
00563 {
00564 iV1 = pkTri->V[(j+1)%3];
00565 if (IsSupervertex(iV1))
00566 {
00567 pkEdge = (DelPolygonEdge<Real>*)kPolygon.InsertEdge(
00568 iV0,iV1);
00569 pkEdge->NullIndex = -1;
00570 pkEdge->Tri = 0;
00571 }
00572 }
00573 }
00574 }
00575 m_kTriangle.erase(pkTri);
00576 WM4_DELETE pkTri;
00577 }
00578
00579
00580
00581 const VEManifoldMesh::EMap& rkEMap = kPolygon.GetEdges();
00582 assert(rkEMap.size() >= 3 && kPolygon.IsClosed());
00583 typename VEManifoldMesh::EMapCIterator pkEIter;
00584 for (pkEIter = rkEMap.begin(); pkEIter != rkEMap.end(); pkEIter++)
00585 {
00586 pkEdge = (DelPolygonEdge<Real>*)pkEIter->second;
00587
00588
00589 pkTri = WM4_NEW DelTriangle<Real>(i,pkEdge->V[0],pkEdge->V[1]);
00590 m_kTriangle.insert(pkTri);
00591
00592
00593 pkTri->A[1] = pkEdge->Tri;
00594 if (pkEdge->Tri)
00595 {
00596 pkEdge->Tri->A[pkEdge->NullIndex] = pkTri;
00597 }
00598
00599
00600
00601
00602 pkEdge->Tri = pkTri;
00603 }
00604
00605
00606 DelPolygonEdge<Real>* pkAdjEdge;
00607 for (pkEIter = rkEMap.begin(); pkEIter != rkEMap.end(); pkEIter++)
00608 {
00609 pkEdge = (DelPolygonEdge<Real>*)pkEIter->second;
00610 pkAdjEdge = (DelPolygonEdge<Real>*)pkEdge->E[0];
00611 pkEdge->Tri->A[0] = pkAdjEdge->Tri;
00612 pkAdjEdge = (DelPolygonEdge<Real>*)pkEdge->E[1];
00613 pkEdge->Tri->A[2] = pkAdjEdge->Tri;
00614 }
00615 }
00616
00617 template <class Real>
00618 DelTriangle<Real>* Delaunay2<Real>::GetContainingTriangle (int i) const
00619 {
00620
00621
00622
00623
00624 DelTriangle<Real>* pkTri = *m_kTriangle.begin();
00625 int iTQuantity = (int)m_kTriangle.size();
00626 for (int iT = 0; iT < iTQuantity; iT++)
00627 {
00628 int* aiV = pkTri->V;
00629
00630 if (m_pkQuery->ToLine(i,aiV[0],aiV[1]) > 0)
00631 {
00632 pkTri = pkTri->A[0];
00633 if (!pkTri)
00634 {
00635 break;
00636 }
00637 continue;
00638 }
00639
00640 if (m_pkQuery->ToLine(i,aiV[1],aiV[2]) > 0)
00641 {
00642 pkTri = pkTri->A[1];
00643 if (!pkTri)
00644 {
00645 break;
00646 }
00647 continue;
00648 }
00649
00650 if (m_pkQuery->ToLine(i,aiV[2],aiV[0]) > 0)
00651 {
00652 pkTri = pkTri->A[2];
00653 if (!pkTri)
00654 {
00655 break;
00656 }
00657 continue;
00658 }
00659
00660 return pkTri;
00661 }
00662
00663 assert(false);
00664 return 0;
00665 }
00666
00667 template <class Real>
00668 void Delaunay2<Real>::RemoveTriangles ()
00669 {
00670
00671 std::set<DelTriangle<Real>*> kRemoveTri;
00672 DelTriangle<Real>* pkTri;
00673 typename std::set<DelTriangle<Real>*>::iterator pkTIter =
00674 m_kTriangle.begin();
00675 for (; pkTIter != m_kTriangle.end(); pkTIter++)
00676 {
00677 pkTri = *pkTIter;
00678 for (int j = 0; j < 3; j++)
00679 {
00680 if (IsSupervertex(pkTri->V[j]))
00681 {
00682 kRemoveTri.insert(pkTri);
00683 break;
00684 }
00685 }
00686 }
00687
00688
00689 pkTIter = kRemoveTri.begin();
00690 for (; pkTIter != kRemoveTri.end(); pkTIter++)
00691 {
00692 pkTri = *pkTIter;
00693 for (int j = 0; j < 3; j++)
00694 {
00695
00696 DelTriangle<Real>* pkAdj = pkTri->A[j];
00697 if (pkAdj)
00698 {
00699 for (int k = 0; k < 3; k++)
00700 {
00701 if (pkAdj->A[k] == pkTri)
00702 {
00703 pkAdj->A[k] = 0;
00704 break;
00705 }
00706 }
00707 }
00708 }
00709 m_kTriangle.erase(pkTri);
00710 WM4_DELETE pkTri;
00711 }
00712 }
00713
00714 template <class Real>
00715 bool Delaunay2<Real>::IsSupervertex (int i) const
00716 {
00717 for (int j = 0; j < 3; j++)
00718 {
00719 if (i == m_aiSV[j])
00720 {
00721 return true;
00722 }
00723 }
00724 return false;
00725 }
00726
00727 template <class Real>
00728 Delaunay2<Real>::Delaunay2 (const char* acFilename)
00729 :
00730 Delaunay<Real>(0,(Real)0.0,false,Query::QT_REAL)
00731 {
00732 m_akVertex = 0;
00733 m_akSVertex = 0;
00734 m_pkQuery = 0;
00735 m_aiPath = 0;
00736 bool bLoaded = Load(acFilename);
00737 assert(bLoaded);
00738 (void)bLoaded;
00739 }
00740
00741 template <class Real>
00742 bool Delaunay2<Real>::Load (const char* acFilename)
00743 {
00744 FILE* pkIFile = System::Fopen(acFilename,"rb");
00745 if (!pkIFile)
00746 {
00747 return false;
00748 }
00749
00750 Delaunay<Real>::Load(pkIFile);
00751
00752 WM4_DELETE m_pkQuery;
00753 WM4_DELETE[] m_akSVertex;
00754 WM4_DELETE[] m_aiPath;
00755 if (m_bOwner)
00756 {
00757 WM4_DELETE[] m_akVertex;
00758 }
00759
00760 m_bOwner = true;
00761 m_akVertex = WM4_NEW Vector2<Real>[m_iVertexQuantity];
00762 m_akSVertex = WM4_NEW Vector2<Real>[m_iVertexQuantity+3];
00763 m_aiPath = WM4_NEW int[m_iSimplexQuantity+1];
00764
00765 System::Read4le(pkIFile,1,&m_iUniqueVertexQuantity);
00766 System::Read4le(pkIFile,3,m_aiSV);
00767 System::Read4le(pkIFile,1,&m_iPathLast);
00768 System::Read4le(pkIFile,1,&m_iLastEdgeV0);
00769 System::Read4le(pkIFile,1,&m_iLastEdgeV1);
00770 System::Read4le(pkIFile,1,&m_iLastEdgeOpposite);
00771 System::Read4le(pkIFile,1,&m_iLastEdgeOppositeIndex);
00772 System::Read4le(pkIFile,m_iSimplexQuantity+1,m_aiPath);
00773
00774 size_t uiSize = sizeof(Real);
00775 int iVQ = 2*m_iVertexQuantity, iSVQ = 2*(m_iVertexQuantity + 3);
00776 if (uiSize == 4)
00777 {
00778 System::Read4le(pkIFile,iVQ,m_akVertex);
00779 System::Read4le(pkIFile,iSVQ,m_akSVertex);
00780 System::Read4le(pkIFile,2,(Real*)m_kMin);
00781 System::Read4le(pkIFile,1,&m_fScale);
00782 System::Read4le(pkIFile,2,(Real*)m_kLineOrigin);
00783 System::Read4le(pkIFile,2,(Real*)m_kLineDirection);
00784 }
00785 else
00786 {
00787 System::Read8le(pkIFile,iVQ,m_akVertex);
00788 System::Read8le(pkIFile,iSVQ,m_akSVertex);
00789 System::Read8le(pkIFile,2,(Real*)m_kMin);
00790 System::Read8le(pkIFile,1,&m_fScale);
00791 System::Read8le(pkIFile,2,(Real*)m_kLineOrigin);
00792 System::Read8le(pkIFile,2,(Real*)m_kLineDirection);
00793 }
00794
00795 System::Fclose(pkIFile);
00796
00797 switch (m_eQueryType)
00798 {
00799 case Query::QT_INT64:
00800 m_pkQuery = WM4_NEW Query2Int64<Real>(m_iVertexQuantity,m_akSVertex);
00801 break;
00802 case Query::QT_INTEGER:
00803 m_pkQuery = WM4_NEW Query2TInteger<Real>(m_iVertexQuantity,
00804 m_akSVertex);
00805 break;
00806 case Query::QT_RATIONAL:
00807 m_pkQuery = WM4_NEW Query2TRational<Real>(m_iVertexQuantity,
00808 m_akSVertex);
00809 break;
00810 case Query::QT_REAL:
00811 m_pkQuery = WM4_NEW Query2<Real>(m_iVertexQuantity,m_akSVertex);
00812 break;
00813 case Query::QT_FILTERED:
00814 m_pkQuery = WM4_NEW Query2Filtered<Real>(m_iVertexQuantity,
00815 m_akSVertex,m_fEpsilon);
00816 break;
00817 }
00818
00819 return true;
00820 }
00821
00822 template <class Real>
00823 bool Delaunay2<Real>::Save (const char* acFilename) const
00824 {
00825 FILE* pkOFile = System::Fopen(acFilename,"wb");
00826 if (!pkOFile)
00827 {
00828 return false;
00829 }
00830
00831 Delaunay<Real>::Save(pkOFile);
00832
00833 System::Write4le(pkOFile,1,&m_iUniqueVertexQuantity);
00834 System::Write4le(pkOFile,3,m_aiSV);
00835 System::Write4le(pkOFile,1,&m_iPathLast);
00836 System::Write4le(pkOFile,1,&m_iLastEdgeV0);
00837 System::Write4le(pkOFile,1,&m_iLastEdgeV1);
00838 System::Write4le(pkOFile,1,&m_iLastEdgeOpposite);
00839 System::Write4le(pkOFile,1,&m_iLastEdgeOppositeIndex);
00840 System::Write4le(pkOFile,m_iSimplexQuantity+1,m_aiPath);
00841
00842 size_t uiSize = sizeof(Real);
00843 int iVQ = 2*m_iVertexQuantity, iSVQ = 2*(m_iVertexQuantity + 3);
00844 if (uiSize == 4)
00845 {
00846 System::Write4le(pkOFile,iVQ,m_akVertex);
00847 System::Write4le(pkOFile,iSVQ,m_akSVertex);
00848 System::Write4le(pkOFile,2,(const Real*)m_kMin);
00849 System::Write4le(pkOFile,1,&m_fScale);
00850 System::Write4le(pkOFile,2,(const Real*)m_kLineOrigin);
00851 System::Write4le(pkOFile,2,(const Real*)m_kLineDirection);
00852 }
00853 else
00854 {
00855 System::Write8le(pkOFile,iVQ,m_akVertex);
00856 System::Write8le(pkOFile,iSVQ,m_akSVertex);
00857 System::Write8le(pkOFile,2,(const Real*)m_kMin);
00858 System::Write8le(pkOFile,1,&m_fScale);
00859 System::Write8le(pkOFile,2,(const Real*)m_kLineOrigin);
00860 System::Write8le(pkOFile,2,(const Real*)m_kLineDirection);
00861 }
00862
00863 System::Fclose(pkOFile);
00864 return true;
00865 }
00866
00867
00868
00869
00870
00871 template WM4_FOUNDATION_ITEM
00872 class Delaunay2<float>;
00873
00874 template WM4_FOUNDATION_ITEM
00875 class Delaunay2<double>;
00876
00877 }