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
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 # include <stdexcept>
00029 # include <map>
00030 # include <queue>
00031 #endif
00032
00033 #include <Base/Exception.h>
00034 #include <Base/Sequencer.h>
00035 #include <Base/Stream.h>
00036 #include <Base/Swap.h>
00037
00038 #include "Algorithm.h"
00039 #include "Approximation.h"
00040 #include "Helpers.h"
00041 #include "MeshKernel.h"
00042 #include "Iterator.h"
00043 #include "Evaluation.h"
00044 #include "Builder.h"
00045 #include "Smoothing.h"
00046
00047 using namespace MeshCore;
00048
00049 MeshKernel::MeshKernel (void)
00050 : _bValid(true)
00051 {
00052 _clBoundBox.Flush();
00053 }
00054
00055 MeshKernel::MeshKernel (const MeshKernel &rclMesh)
00056 {
00057 *this = rclMesh;
00058 }
00059
00060 MeshKernel& MeshKernel::operator = (const MeshKernel &rclMesh)
00061 {
00062 if (this != &rclMesh) {
00063 this->_aclPointArray = rclMesh._aclPointArray;
00064 this->_aclFacetArray = rclMesh._aclFacetArray;
00065 this->_clBoundBox = rclMesh._clBoundBox;
00066 this->_bValid = rclMesh._bValid;
00067 }
00068 return *this;
00069 }
00070
00071 MeshKernel& MeshKernel::operator = (const std::vector<MeshGeomFacet> &rclFAry)
00072 {
00073 MeshBuilder builder(*this);
00074 builder.Initialize(rclFAry.size());
00075
00076 for (std::vector<MeshGeomFacet>::const_iterator it = rclFAry.begin(); it != rclFAry.end(); it++)
00077 builder.AddFacet(*it);
00078
00079 builder.Finish();
00080
00081 return *this;
00082 }
00083
00084 void MeshKernel::Assign(const MeshPointArray& rPoints, const MeshFacetArray& rFacets, bool checkNeighbourHood)
00085 {
00086 _aclPointArray = rPoints;
00087 _aclFacetArray = rFacets;
00088 RecalcBoundBox();
00089 if (checkNeighbourHood)
00090 RebuildNeighbours();
00091 }
00092
00093 void MeshKernel::Adopt(MeshPointArray& rPoints, MeshFacetArray& rFacets, bool checkNeighbourHood)
00094 {
00095 _aclPointArray.swap(rPoints);
00096 _aclFacetArray.swap(rFacets);
00097 RecalcBoundBox();
00098 if (checkNeighbourHood)
00099 RebuildNeighbours();
00100 }
00101
00102 void MeshKernel::Swap(MeshKernel& mesh)
00103 {
00104 this->_aclPointArray.swap(mesh._aclPointArray);
00105 this->_aclFacetArray.swap(mesh._aclFacetArray);
00106 this->_clBoundBox = mesh._clBoundBox;
00107 }
00108
00109 MeshKernel& MeshKernel::operator += (const MeshGeomFacet &rclSFacet)
00110 {
00111 this->AddFacet(rclSFacet);
00112 return *this;
00113 }
00114
00115 void MeshKernel::AddFacet(const MeshGeomFacet &rclSFacet)
00116 {
00117 unsigned long i;
00118 MeshFacet clFacet;
00119
00120
00121 for (i = 0; i < 3; i++) {
00122 _clBoundBox &= rclSFacet._aclPoints[i];
00123 clFacet._aulPoints[i] = _aclPointArray.GetOrAddIndex(rclSFacet._aclPoints[i]);
00124 }
00125
00126
00127 AdjustNormal(clFacet, rclSFacet.GetNormal());
00128
00129 unsigned long ulCt = _aclFacetArray.size();
00130
00131
00132 unsigned long ulP0 = clFacet._aulPoints[0];
00133 unsigned long ulP1 = clFacet._aulPoints[1];
00134 unsigned long ulP2 = clFacet._aulPoints[2];
00135 unsigned long ulCC = 0;
00136 for (TMeshFacetArray::iterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); pF++, ulCC++) {
00137 for (int i=0; i<3;i++) {
00138 unsigned long ulP = pF->_aulPoints[i];
00139 unsigned long ulQ = pF->_aulPoints[(i+1)%3];
00140 if (ulQ == ulP0 && ulP == ulP1) {
00141 clFacet._aulNeighbours[0] = ulCC;
00142 pF->_aulNeighbours[i] = ulCt;
00143 }
00144 else if (ulQ == ulP1 && ulP == ulP2) {
00145 clFacet._aulNeighbours[1] = ulCC;
00146 pF->_aulNeighbours[i] = ulCt;
00147 }
00148 else if (ulQ == ulP2 && ulP == ulP0) {
00149 clFacet._aulNeighbours[2] = ulCC;
00150 pF->_aulNeighbours[i] = ulCt;
00151 }
00152 }
00153 }
00154
00155
00156 _aclFacetArray.push_back(clFacet);
00157 }
00158
00159 MeshKernel& MeshKernel::operator += (const std::vector<MeshGeomFacet> &rclFAry)
00160 {
00161 this->AddFacets(rclFAry);
00162 return *this;
00163 }
00164
00165 void MeshKernel::AddFacets(const std::vector<MeshGeomFacet> &rclFAry)
00166 {
00167
00168
00169
00170 MeshKernel tmp;
00171 tmp = rclFAry;
00172 Merge(tmp);
00173 }
00174
00175 unsigned long MeshKernel::AddFacets(const std::vector<MeshFacet> &rclFAry)
00176 {
00177
00178 #ifdef FC_DEBUG
00179 unsigned long countPoints = CountPoints();
00180 #endif
00181 this->_aclPointArray.ResetInvalid();
00182 unsigned long k = CountFacets();
00183 std::map<std::pair<unsigned long, unsigned long>, std::list<unsigned long> > edgeMap;
00184 for (std::vector<MeshFacet>::const_iterator pF = rclFAry.begin(); pF != rclFAry.end(); pF++, k++) {
00185
00186 pF->ResetFlag(MeshFacet::INVALID);
00187 for (int i=0; i<3; i++) {
00188 #ifdef FC_DEBUG
00189 assert( pF->_aulPoints[i] < countPoints );
00190 #endif
00191 this->_aclPointArray[pF->_aulPoints[i]].SetFlag(MeshPoint::INVALID);
00192 unsigned long ulT0 = pF->_aulPoints[i];
00193 unsigned long ulT1 = pF->_aulPoints[(i+1)%3];
00194 unsigned long ulP0 = std::min<unsigned long>(ulT0, ulT1);
00195 unsigned long ulP1 = std::max<unsigned long>(ulT0, ulT1);
00196 edgeMap[std::make_pair<unsigned long, unsigned long>(ulP0, ulP1)].push_front(k);
00197 }
00198 }
00199
00200
00201 k=0;
00202 for (MeshFacetArray::_TIterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); pF++, k++) {
00203
00204 if (!this->_aclPointArray[pF->_aulPoints[0]].IsFlag(MeshPoint::INVALID) &&
00205 !this->_aclPointArray[pF->_aulPoints[1]].IsFlag(MeshPoint::INVALID) &&
00206 !this->_aclPointArray[pF->_aulPoints[2]].IsFlag(MeshPoint::INVALID))
00207 continue;
00208 for (int i=0; i<3; i++) {
00209 unsigned long ulT0 = pF->_aulPoints[i];
00210 unsigned long ulT1 = pF->_aulPoints[(i+1)%3];
00211 unsigned long ulP0 = std::min<unsigned long>(ulT0, ulT1);
00212 unsigned long ulP1 = std::max<unsigned long>(ulT0, ulT1);
00213 std::pair<unsigned long, unsigned long> edge = std::make_pair<unsigned long, unsigned long>(ulP0, ulP1);
00214 std::map<std::pair<unsigned long, unsigned long>, std::list<unsigned long> >::iterator pI = edgeMap.find(edge);
00215
00216 if (pI != edgeMap.end()) {
00217 pI->second.push_front(k);
00218 }
00219 }
00220 }
00221
00222 this->_aclPointArray.ResetInvalid();
00223
00224
00225 unsigned long countFacets = CountFacets();
00226 std::map<std::pair<unsigned long, unsigned long>, std::list<unsigned long> >::iterator pE;
00227 for (pE = edgeMap.begin(); pE != edgeMap.end(); ++pE)
00228 {
00229 if (pE->second.size() > 2)
00230 {
00231 for (std::list<unsigned long>::iterator it = pE->second.begin(); it != pE->second.end(); ++it)
00232 {
00233 if (*it >= countFacets) {
00234
00235 unsigned long index = *it - countFacets;
00236 rclFAry[index].SetFlag(MeshFacet::INVALID);
00237 }
00238 }
00239 }
00240 }
00241
00242
00243
00244 unsigned long countValid = std::count_if(rclFAry.begin(), rclFAry.end(),
00245 std::bind2nd(MeshIsNotFlag<MeshFacet>(), MeshFacet::INVALID));
00246 _aclFacetArray.reserve( _aclFacetArray.size() + countValid );
00247
00248 unsigned long startIndex = CountFacets();
00249 for (std::vector<MeshFacet>::const_iterator pF = rclFAry.begin(); pF != rclFAry.end(); pF++) {
00250 if (!pF->IsFlag(MeshFacet::INVALID)) {
00251 _aclFacetArray.push_back(*pF);
00252 pF->SetProperty(startIndex++);
00253 }
00254 }
00255
00256
00257 for (pE = edgeMap.begin(); pE != edgeMap.end(); pE++)
00258 {
00259 unsigned long ulP0 = pE->first.first;
00260 unsigned long ulP1 = pE->first.second;
00261 if (pE->second.size() == 1)
00262 {
00263 unsigned long ulF0 = pE->second.front();
00264 if (ulF0 >= countFacets) {
00265 ulF0 -= countFacets;
00266 std::vector<MeshFacet>::const_iterator pF = rclFAry.begin() + ulF0;
00267 if (!pF->IsFlag(MeshFacet::INVALID))
00268 ulF0 = pF->_ulProp;
00269 else
00270 ulF0 = ULONG_MAX;
00271 }
00272
00273 if (ulF0 != ULONG_MAX) {
00274 unsigned short usSide = _aclFacetArray[ulF0].Side(ulP0, ulP1);
00275 assert(usSide != USHRT_MAX);
00276 _aclFacetArray[ulF0]._aulNeighbours[usSide] = ULONG_MAX;
00277 }
00278 }
00279 else if (pE->second.size() == 2)
00280 {
00281
00282 unsigned long ulF0 = pE->second.front();
00283 if (ulF0 >= countFacets) {
00284 ulF0 -= countFacets;
00285 std::vector<MeshFacet>::const_iterator pF = rclFAry.begin() + ulF0;
00286 if (!pF->IsFlag(MeshFacet::INVALID))
00287 ulF0 = pF->_ulProp;
00288 else
00289 ulF0 = ULONG_MAX;
00290 }
00291 unsigned long ulF1 = pE->second.back();
00292 if (ulF1 >= countFacets) {
00293 ulF1 -= countFacets;
00294 std::vector<MeshFacet>::const_iterator pF = rclFAry.begin() + ulF1;
00295 if (!pF->IsFlag(MeshFacet::INVALID))
00296 ulF1 = pF->_ulProp;
00297 else
00298 ulF1 = ULONG_MAX;
00299 }
00300
00301 if (ulF0 != ULONG_MAX) {
00302 unsigned short usSide = _aclFacetArray[ulF0].Side(ulP0, ulP1);
00303 assert(usSide != USHRT_MAX);
00304 _aclFacetArray[ulF0]._aulNeighbours[usSide] = ulF1;
00305 }
00306
00307 if (ulF1 != ULONG_MAX) {
00308 unsigned short usSide = _aclFacetArray[ulF1].Side(ulP0, ulP1);
00309 assert(usSide != USHRT_MAX);
00310 _aclFacetArray[ulF1]._aulNeighbours[usSide] = ulF0;
00311 }
00312 }
00313 }
00314
00315 return _aclFacetArray.size();
00316 }
00317
00318 unsigned long MeshKernel::AddFacets(const std::vector<MeshFacet> &rclFAry, const std::vector<Base::Vector3f>& rclPAry)
00319 {
00320 for (std::vector<Base::Vector3f>::const_iterator it = rclPAry.begin(); it != rclPAry.end(); ++it)
00321 _clBoundBox &= *it;
00322 this->_aclPointArray.insert(this->_aclPointArray.end(), rclPAry.begin(), rclPAry.end());
00323 return this->AddFacets(rclFAry);
00324 }
00325
00326 void MeshKernel::Merge(const MeshKernel& rKernel)
00327 {
00328 if (this != &rKernel) {
00329 const MeshPointArray& rPoints = rKernel._aclPointArray;
00330 const MeshFacetArray& rFacets = rKernel._aclFacetArray;
00331 Merge(rPoints, rFacets);
00332 }
00333 }
00334
00335 void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFaces)
00336 {
00337 if (rPoints.empty() || rFaces.empty())
00338 return;
00339 std::vector<unsigned long> increments(rPoints.size());
00340
00341 unsigned long countFacets = this->_aclFacetArray.size();
00342
00343 this->_aclFacetArray.reserve(this->_aclFacetArray.size() + rFaces.size());
00344
00345
00346 MeshFacet face;
00347 for(MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) {
00348 face = *it;
00349 for (int i=0; i<3; i++) {
00350 increments[it->_aulPoints[i]]++;
00351 }
00352
00353
00354 this->_aclFacetArray.push_back(face);
00355 }
00356
00357 unsigned long countNewPoints = std::count_if(increments.begin(), increments.end(),
00358 std::bind2nd(std::greater<unsigned long>(), 0));
00359
00360 unsigned long index = this->_aclPointArray.size();
00361 this->_aclPointArray.reserve(this->_aclPointArray.size() + countNewPoints);
00362
00363
00364 for (std::vector<unsigned long>::iterator it = increments.begin(); it != increments.end(); ++it) {
00365 if (*it > 0) {
00366
00367 *it = index++;
00368 const MeshPoint& rPt = rPoints[it-increments.begin()];
00369 this->_aclPointArray.push_back(rPt);
00370 _clBoundBox &= rPt;
00371 }
00372 }
00373
00374 for (MeshFacetArray::_TIterator pF = this->_aclFacetArray.begin()+countFacets;
00375 pF != this->_aclFacetArray.end(); ++pF) {
00376 for (int i=0; i<3; i++) {
00377 pF->_aulPoints[i] = increments[pF->_aulPoints[i]];
00378 }
00379 }
00380
00381
00382
00383
00384
00385 RebuildNeighbours(countFacets);
00386 }
00387
00388 void MeshKernel::Clear (void)
00389 {
00390 _aclPointArray.clear();
00391 _aclFacetArray.clear();
00392
00393
00394 MeshPointArray().swap(_aclPointArray);
00395 MeshFacetArray().swap(_aclFacetArray);
00396
00397 _clBoundBox.Flush();
00398 }
00399
00400 bool MeshKernel::DeleteFacet (const MeshFacetIterator &rclIter)
00401 {
00402 unsigned long i, j, ulNFacet, ulInd;
00403
00404 if (rclIter._clIter >= _aclFacetArray.end())
00405 return false;
00406
00407
00408 ulInd = rclIter._clIter - _aclFacetArray.begin();
00409
00410
00411 for (i = 0; i < 3; i++) {
00412 ulNFacet = rclIter._clIter->_aulNeighbours[i];
00413 if (ulNFacet != ULONG_MAX) {
00414 for (j = 0; j < 3; j++) {
00415 if (_aclFacetArray[ulNFacet]._aulNeighbours[j] == ulInd) {
00416 _aclFacetArray[ulNFacet]._aulNeighbours[j] = ULONG_MAX;
00417 break;
00418 }
00419 }
00420 }
00421 }
00422
00423
00424 for (i = 0; i < 3; i++) {
00425 if ((rclIter._clIter->_aulNeighbours[i] == ULONG_MAX) &&
00426 (rclIter._clIter->_aulNeighbours[(i+1)%3] == ULONG_MAX)) {
00427
00428 ErasePoint(rclIter._clIter->_aulPoints[(i+1)%3], ulInd);
00429 }
00430 }
00431
00432
00433 _aclFacetArray.Erase(_aclFacetArray.begin() + rclIter.Position());
00434
00435 return true;
00436 }
00437
00438 bool MeshKernel::DeleteFacet (unsigned long ulInd)
00439 {
00440 if (ulInd >= _aclFacetArray.size())
00441 return false;
00442
00443 MeshFacetIterator clIter(*this);
00444 clIter.Set(ulInd);
00445
00446 return DeleteFacet(clIter);
00447 }
00448
00449 void MeshKernel::DeleteFacets (const std::vector<unsigned long> &raulFacets)
00450 {
00451 _aclPointArray.SetProperty(0);
00452
00453
00454 for (MeshFacetArray::_TConstIterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); pF++) {
00455 _aclPointArray[pF->_aulPoints[0]]._ulProp++;
00456 _aclPointArray[pF->_aulPoints[1]]._ulProp++;
00457 _aclPointArray[pF->_aulPoints[2]]._ulProp++;
00458 }
00459
00460
00461 _aclFacetArray.ResetInvalid();
00462 for (std::vector<unsigned long>::const_iterator pI = raulFacets.begin(); pI != raulFacets.end(); pI++) {
00463 MeshFacet &rclFacet = _aclFacetArray[*pI];
00464 rclFacet.SetInvalid();
00465 _aclPointArray[rclFacet._aulPoints[0]]._ulProp--;
00466 _aclPointArray[rclFacet._aulPoints[1]]._ulProp--;
00467 _aclPointArray[rclFacet._aulPoints[2]]._ulProp--;
00468 }
00469
00470
00471 _aclPointArray.ResetInvalid();
00472 for (MeshPointArray::_TIterator pP = _aclPointArray.begin(); pP != _aclPointArray.end(); pP++) {
00473 if (pP->_ulProp == 0)
00474 pP->SetInvalid();
00475 }
00476
00477 RemoveInvalids();
00478 RecalcBoundBox();
00479 }
00480
00481 bool MeshKernel::DeletePoint (unsigned long ulInd)
00482 {
00483 if (ulInd >= _aclPointArray.size())
00484 return false;
00485
00486 MeshPointIterator clIter(*this);
00487 clIter.Set(ulInd);
00488
00489 return DeletePoint(clIter);
00490 }
00491
00492 bool MeshKernel::DeletePoint (const MeshPointIterator &rclIter)
00493 {
00494 MeshFacetIterator pFIter(*this), pFEnd(*this);
00495 std::vector<MeshFacetIterator> clToDel;
00496 unsigned long i, ulInd;
00497
00498
00499 ulInd = rclIter._clIter - _aclPointArray.begin();
00500
00501 pFIter.Begin();
00502 pFEnd.End();
00503
00504
00505 while (pFIter < pFEnd) {
00506 for (i = 0; i < 3; i++) {
00507 if (ulInd == pFIter._clIter->_aulPoints[i])
00508 clToDel.push_back(pFIter);
00509 }
00510 ++pFIter;
00511 }
00512
00513
00514 std::sort(clToDel.begin(), clToDel.end());
00515
00516
00517
00518 for (i = clToDel.size(); i > 0; i--)
00519 DeleteFacet(clToDel[i-1]);
00520 return true;
00521 }
00522
00523 void MeshKernel::DeletePoints (const std::vector<unsigned long> &raulPoints)
00524 {
00525 _aclPointArray.ResetInvalid();
00526 for (std::vector<unsigned long>::const_iterator pI = raulPoints.begin(); pI != raulPoints.end(); pI++)
00527 _aclPointArray[*pI].SetInvalid();
00528
00529
00530 _aclPointArray.SetProperty(0);
00531 for (MeshFacetArray::_TIterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); pF++) {
00532 MeshPoint &rclP0 = _aclPointArray[pF->_aulPoints[0]];
00533 MeshPoint &rclP1 = _aclPointArray[pF->_aulPoints[1]];
00534 MeshPoint &rclP2 = _aclPointArray[pF->_aulPoints[2]];
00535
00536 if ((rclP0.IsValid() == false) || (rclP1.IsValid() == false) || (rclP2.IsValid() == false)) {
00537 pF->SetInvalid();
00538 }
00539 else {
00540 pF->ResetInvalid();
00541 rclP0._ulProp++;
00542 rclP1._ulProp++;
00543 rclP2._ulProp++;
00544 }
00545 }
00546
00547
00548 for (MeshPointArray::_TIterator pP = _aclPointArray.begin(); pP != _aclPointArray.end(); pP++) {
00549 if (pP->_ulProp == 0)
00550 pP->SetInvalid();
00551 }
00552
00553 RemoveInvalids();
00554 RecalcBoundBox();
00555 }
00556
00557 void MeshKernel::ErasePoint (unsigned long ulIndex, unsigned long ulFacetIndex, bool bOnlySetInvalid)
00558 {
00559 unsigned long i;
00560 std::vector<MeshFacet>::iterator pFIter, pFEnd, pFNot;
00561
00562 pFIter = _aclFacetArray.begin();
00563 pFNot = _aclFacetArray.begin() + ulFacetIndex;
00564 pFEnd = _aclFacetArray.end();
00565
00566
00567 while (pFIter < pFNot) {
00568 for (i = 0; i < 3; i++) {
00569 if (pFIter->_aulPoints[i] == ulIndex)
00570 return;
00571 }
00572 pFIter++;
00573 }
00574
00575 pFIter++;
00576 while (pFIter < pFEnd) {
00577 for (i = 0; i < 3; i++) {
00578 if (pFIter->_aulPoints[i] == ulIndex)
00579 return;
00580 }
00581 pFIter++;
00582 }
00583
00584
00585 if (bOnlySetInvalid == false) {
00586
00587 _aclPointArray.erase(_aclPointArray.begin() + ulIndex);
00588
00589
00590 pFIter = _aclFacetArray.begin();
00591 while (pFIter < pFEnd) {
00592 for (i = 0; i < 3; i++) {
00593 if (pFIter->_aulPoints[i] > ulIndex)
00594 pFIter->_aulPoints[i]--;
00595 }
00596 pFIter++;
00597 }
00598 }
00599 else
00600 _aclPointArray[ulIndex].SetInvalid();
00601 }
00602
00603 void MeshKernel::RemoveInvalids ()
00604 {
00605 std::vector<unsigned long> aulDecrements;
00606 std::vector<unsigned long>::iterator pDIter;
00607 unsigned long ulDec, i, k;
00608 MeshPointArray::_TIterator pPIter, pPEnd;
00609 MeshFacetArray::_TIterator pFIter, pFEnd;
00610
00611
00612 aulDecrements.resize(_aclPointArray.size());
00613 pDIter = aulDecrements.begin();
00614 ulDec = 0;
00615 pPEnd = _aclPointArray.end();
00616 for (pPIter = _aclPointArray.begin(); pPIter != pPEnd; pPIter++) {
00617 *pDIter++ = ulDec;
00618 if (pPIter->IsValid() == false)
00619 ulDec++;
00620 }
00621
00622
00623 pFEnd = _aclFacetArray.end();
00624 for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; pFIter++) {
00625 if (pFIter->IsValid() == true) {
00626 pFIter->_aulPoints[0] -= aulDecrements[pFIter->_aulPoints[0]];
00627 pFIter->_aulPoints[1] -= aulDecrements[pFIter->_aulPoints[1]];
00628 pFIter->_aulPoints[2] -= aulDecrements[pFIter->_aulPoints[2]];
00629 }
00630 }
00631
00632
00633 unsigned long ulNewPts = std::count_if(_aclPointArray.begin(), _aclPointArray.end(),
00634 std::mem_fun_ref(&MeshPoint::IsValid));
00635
00636 MeshPointArray aclTempPt(ulNewPts);
00637 MeshPointArray::_TIterator pPTemp = aclTempPt.begin();
00638 pPEnd = _aclPointArray.end();
00639 for (pPIter = _aclPointArray.begin(); pPIter != pPEnd; pPIter++) {
00640 if (pPIter->IsValid() == true)
00641 *pPTemp++ = *pPIter;
00642 }
00643
00644
00645
00646
00647 _aclPointArray.swap(aclTempPt);
00648 MeshPointArray().swap(aclTempPt);
00649
00650
00651 aulDecrements.resize(_aclFacetArray.size());
00652 pDIter = aulDecrements.begin();
00653 ulDec = 0;
00654 pFEnd = _aclFacetArray.end();
00655 for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; pFIter++, pDIter++) {
00656 *pDIter = ulDec;
00657 if (pFIter->IsValid() == false)
00658 ulDec++;
00659 }
00660
00661
00662 pFEnd = _aclFacetArray.end();
00663 for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; pFIter++) {
00664 if (pFIter->IsValid() == true) {
00665 for (i = 0; i < 3; i++) {
00666 k = pFIter->_aulNeighbours[i];
00667 if (k != ULONG_MAX) {
00668 if (_aclFacetArray[k].IsValid() == true)
00669 pFIter->_aulNeighbours[i] -= aulDecrements[k];
00670 else
00671 pFIter->_aulNeighbours[i] = ULONG_MAX;
00672 }
00673 }
00674 }
00675 }
00676
00677
00678 unsigned long ulDelFacets = std::count_if(_aclFacetArray.begin(), _aclFacetArray.end(),
00679 std::mem_fun_ref(&MeshFacet::IsValid));
00680 MeshFacetArray aclFArray(ulDelFacets);
00681 MeshFacetArray::_TIterator pFTemp = aclFArray.begin();
00682 pFEnd = _aclFacetArray.end();
00683 for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; pFIter++) {
00684 if (pFIter->IsValid() == true)
00685 *pFTemp++ = *pFIter;
00686 }
00687
00688
00689
00690 _aclFacetArray.swap(aclFArray);
00691 }
00692
00693 void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclProj,
00694 const Base::Polygon2D& rclPoly, bool bCutInner, std::vector<MeshGeomFacet> &raclFacets)
00695 {
00696 std::vector<unsigned long> aulFacets;
00697
00698 MeshAlgorithm(*this).CheckFacets(rclGrid, pclProj, rclPoly, bCutInner, aulFacets );
00699
00700 for (std::vector<unsigned long>::iterator i = aulFacets.begin(); i != aulFacets.end(); i++)
00701 raclFacets.push_back(GetFacet(*i));
00702
00703 DeleteFacets(aulFacets);
00704 }
00705
00706 void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclProj,
00707 const Base::Polygon2D& rclPoly, bool bInner, std::vector<unsigned long> &raclCutted)
00708 {
00709 MeshAlgorithm(*this).CheckFacets(rclGrid, pclProj, rclPoly, bInner, raclCutted);
00710 DeleteFacets(raclCutted);
00711 }
00712
00713 std::vector<unsigned long> MeshKernel::GetFacetPoints(const std::vector<unsigned long>& facets) const
00714 {
00715 std::vector<unsigned long> points;
00716 for (std::vector<unsigned long>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
00717 unsigned long p0, p1, p2;
00718 GetFacetPoints(*it, p0, p1, p2);
00719 points.push_back(p0);
00720 points.push_back(p1);
00721 points.push_back(p2);
00722 }
00723
00724 std::sort(points.begin(), points.end());
00725 points.erase(std::unique(points.begin(), points.end()), points.end());
00726 return points;
00727 }
00728
00729 std::vector<unsigned long> MeshKernel::HasFacets (const MeshPointIterator &rclIter) const
00730 {
00731 unsigned long i, ulPtInd = rclIter.Position();
00732 std::vector<MeshFacet>::const_iterator pFIter = _aclFacetArray.begin();
00733 std::vector<MeshFacet>::const_iterator pFBegin = _aclFacetArray.begin();
00734 std::vector<MeshFacet>::const_iterator pFEnd = _aclFacetArray.end();
00735 std::vector<unsigned long> aulBelongs;
00736
00737 while (pFIter < pFEnd) {
00738 for (i = 0; i < 3; i++) {
00739 if (pFIter->_aulPoints[i] == ulPtInd) {
00740 aulBelongs.push_back(pFIter - pFBegin);
00741 break;
00742 }
00743 }
00744 pFIter++;
00745 }
00746
00747 return aulBelongs;
00748 }
00749
00750 MeshFacetArray MeshKernel::GetFacets(const std::vector<unsigned long>& indices) const
00751 {
00752 MeshFacetArray ary;
00753 ary.reserve(indices.size());
00754 for (std::vector<unsigned long>::const_iterator it = indices.begin(); it != indices.end(); ++it)
00755 ary.push_back(this->_aclFacetArray[*it]);
00756 return ary;
00757 }
00758
00759 void MeshKernel::Write (std::ostream &rclOut) const
00760 {
00761 if (!rclOut || rclOut.bad())
00762 return;
00763
00764 Base::OutputStream str(rclOut);
00765
00766
00767 str << (uint32_t)0xA0B0C0D0;
00768 str << (uint32_t)0x010000;
00769
00770 char szInfo[257];
00771 strcpy(szInfo, "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-"
00772 "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-"
00773 "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-"
00774 "MESH-MESH-MESH-\n");
00775 rclOut.write(szInfo, 256);
00776
00777
00778 str << (uint32_t)CountPoints() << (uint32_t)CountFacets();
00779
00780
00781 for (MeshPointArray::_TConstIterator it = _aclPointArray.begin(); it != _aclPointArray.end(); ++it) {
00782 str << it->x << it->y << it->z;
00783 }
00784
00785 for (MeshFacetArray::_TConstIterator it = _aclFacetArray.begin(); it != _aclFacetArray.end(); ++it) {
00786 str << (uint32_t)it->_aulPoints[0]
00787 << (uint32_t)it->_aulPoints[1]
00788 << (uint32_t)it->_aulPoints[2];
00789 str << (uint32_t)it->_aulNeighbours[0]
00790 << (uint32_t)it->_aulNeighbours[1]
00791 << (uint32_t)it->_aulNeighbours[2];
00792 }
00793
00794 str << _clBoundBox.MinX << _clBoundBox.MaxX;
00795 str << _clBoundBox.MinY << _clBoundBox.MaxY;
00796 str << _clBoundBox.MinZ << _clBoundBox.MaxZ;
00797 }
00798
00799 void MeshKernel::Read (std::istream &rclIn)
00800 {
00801 if (!rclIn || rclIn.bad())
00802 return;
00803
00804
00805 Base::InputStream str(rclIn);
00806
00807
00808 uint32_t magic, version, swap_magic, swap_version;
00809 str >> magic >> version;
00810 swap_magic = magic; Base::SwapEndian(swap_magic);
00811 swap_version = version; Base::SwapEndian(swap_version);
00812
00813
00814 bool new_format = false;
00815 if (magic == 0xA0B0C0D0 && version == 0x010000) {
00816 new_format = true;
00817 }
00818 else if (swap_magic == 0xA0B0C0D0 && swap_version == 0x010000) {
00819 new_format = true;
00820 str.setByteOrder(Base::Stream::BigEndian);
00821 }
00822
00823 if (new_format) {
00824 char szInfo[256];
00825 rclIn.read(szInfo, 256);
00826
00827
00828 uint32_t uCtPts=0, uCtFts=0;
00829 str >> uCtPts >> uCtFts;
00830
00831 try {
00832
00833 MeshPointArray pointArray;
00834 pointArray.resize(uCtPts);
00835 for (MeshPointArray::_TIterator it = pointArray.begin(); it != pointArray.end(); ++it) {
00836 str >> it->x >> it->y >> it->z;
00837 }
00838
00839 MeshFacetArray facetArray;
00840 facetArray.resize(uCtFts);
00841
00842 uint32_t v1, v2, v3;
00843 for (MeshFacetArray::_TIterator it = facetArray.begin(); it != facetArray.end(); ++it) {
00844 str >> v1 >> v2 >> v3;
00845 it->_aulPoints[0] = v1;
00846 it->_aulPoints[1] = v2;
00847 it->_aulPoints[2] = v3;
00848
00849 str >> v1 >> v2 >> v3;
00850 it->_aulNeighbours[0] = v1;
00851 it->_aulNeighbours[1] = v2;
00852 it->_aulNeighbours[2] = v3;
00853 }
00854
00855 str >> _clBoundBox.MinX >> _clBoundBox.MaxX;
00856 str >> _clBoundBox.MinY >> _clBoundBox.MaxY;
00857 str >> _clBoundBox.MinZ >> _clBoundBox.MaxZ;
00858
00859
00860 _aclPointArray.swap(pointArray);
00861 _aclFacetArray.swap(facetArray);
00862 }
00863 catch (std::exception&) {
00864
00865 throw Base::Exception("Reading from stream failed");
00866 }
00867 }
00868 else {
00869
00870 unsigned long uCtPts=magic, uCtFts=version;
00871
00872
00873 if ( uCtPts > 0 ) {
00874 _aclPointArray.resize(uCtPts);
00875 rclIn.read((char*)&(_aclPointArray[0]), uCtPts*sizeof(MeshPoint));
00876 }
00877 if ( uCtFts > 0 ) {
00878 _aclFacetArray.resize(uCtFts);
00879 rclIn.read((char*)&(_aclFacetArray[0]), uCtFts*sizeof(MeshFacet));
00880 }
00881 rclIn.read((char*)&_clBoundBox, sizeof(Base::BoundBox3f));
00882 }
00883 }
00884
00885 void MeshKernel::operator *= (const Base::Matrix4D &rclMat)
00886 {
00887 this->Transform(rclMat);
00888 }
00889
00890 void MeshKernel::Transform (const Base::Matrix4D &rclMat)
00891 {
00892 MeshPointArray::_TIterator clPIter = _aclPointArray.begin(), clPEIter = _aclPointArray.end();
00893 Base::Matrix4D clMatrix(rclMat);
00894
00895 _clBoundBox.Flush();
00896 while (clPIter < clPEIter) {
00897 *clPIter *= clMatrix;
00898 _clBoundBox &= *clPIter;
00899 clPIter++;
00900 }
00901 }
00902
00903 void MeshKernel::Smooth(int iterations, float stepsize)
00904 {
00905 LaplaceSmoothing(*this).Smooth(iterations);
00906 }
00907
00908 void MeshKernel::RecalcBoundBox (void)
00909 {
00910 _clBoundBox.Flush();
00911 for (MeshPointArray::_TConstIterator pI = _aclPointArray.begin(); pI != _aclPointArray.end(); pI++)
00912 _clBoundBox &= *pI;
00913 }
00914
00915 std::vector<Base::Vector3f> MeshKernel::CalcVertexNormals() const
00916 {
00917 std::vector<Base::Vector3f> normals;
00918
00919 normals.resize(CountPoints());
00920
00921 unsigned long p1,p2,p3;
00922 unsigned int ct = CountFacets();
00923 for (unsigned int pFIter = 0;pFIter < ct; pFIter++) {
00924 GetFacetPoints(pFIter,p1,p2,p3);
00925 Base::Vector3f Norm = (GetPoint(p2)-GetPoint(p1)) % (GetPoint(p3)-GetPoint(p1));
00926
00927 normals[p1] += Norm;
00928 normals[p2] += Norm;
00929 normals[p3] += Norm;
00930 }
00931
00932 return normals;
00933 }
00934
00935
00936 float MeshKernel::GetSurface() const
00937 {
00938 float fSurface = 0.0;
00939 MeshFacetIterator cIter(*this);
00940 for (cIter.Init(); cIter.More(); cIter.Next())
00941 fSurface += cIter->Area();
00942
00943 return fSurface;
00944 }
00945
00946 float MeshKernel::GetSurface( const std::vector<unsigned long>& aSegment ) const
00947 {
00948 float fSurface = 0.0;
00949 MeshFacetIterator cIter(*this);
00950
00951 for (std::vector<unsigned long>::const_iterator it = aSegment.begin(); it != aSegment.end(); ++it) {
00952 cIter.Set(*it);
00953 fSurface += cIter->Area();
00954 }
00955
00956 return fSurface;
00957 }
00958
00959 float MeshKernel::GetVolume() const
00960 {
00961 MeshEvalSolid cSolid(*this);
00962 if ( !cSolid.Evaluate() )
00963 return 0.0f;
00964
00965 float fVolume = 0.0;
00966 MeshFacetIterator cIter(*this);
00967 Base::Vector3f p1,p2,p3;
00968 for (cIter.Init(); cIter.More(); cIter.Next()) {
00969 const MeshGeomFacet& rclF = *cIter;
00970 p1 = rclF._aclPoints[0];
00971 p2 = rclF._aclPoints[1];
00972 p3 = rclF._aclPoints[2];
00973
00974 fVolume += (-p3.x*p2.y*p1.z + p2.x*p3.y*p1.z + p3.x*p1.y*p2.z - p1.x*p3.y*p2.z - p2.x*p1.y*p3.z + p1.x*p2.y*p3.z);
00975 }
00976
00977 fVolume /= 6.0;
00978 fVolume = (float)fabs(fVolume);
00979
00980 return fVolume;
00981 }
00982
00983 bool MeshKernel::HasOpenEdges() const
00984 {
00985 MeshEvalSolid eval(*this);
00986 return !eval.Evaluate();
00987 }
00988
00989 bool MeshKernel::HasNonManifolds() const
00990 {
00991 MeshEvalTopology eval(*this);
00992 return !eval.Evaluate();
00993 }
00994
00995 bool MeshKernel::HasSelfIntersections() const
00996 {
00997 MeshEvalSelfIntersection eval(*this);
00998 return !eval.Evaluate();
00999 }
01000
01001
01002 MeshFacetIterator MeshKernel::FacetIterator() const
01003 {
01004 MeshFacetIterator it(*this);
01005 it.Begin(); return it;
01006 }
01007
01008 MeshPointIterator MeshKernel::PointIterator() const
01009 {
01010 MeshPointIterator it(*this);
01011 it.Begin(); return it;
01012 }
01013
01014 void MeshKernel::GetEdges (std::vector<MeshGeomEdge>& edges) const
01015 {
01016 std::set<MeshBuilder::Edge> tmp;
01017
01018 for (MeshFacetArray::_TConstIterator it = _aclFacetArray.begin(); it != _aclFacetArray.end(); it++) {
01019 for (int i = 0; i < 3; i++) {
01020 tmp.insert(MeshBuilder::Edge(it->_aulPoints[i], it->_aulPoints[(i+1)%3], it->_aulNeighbours[i]));
01021 }
01022 }
01023
01024 edges.reserve(tmp.size());
01025 for (std::set<MeshBuilder::Edge>::iterator it2 = tmp.begin(); it2 != tmp.end(); it2++) {
01026 MeshGeomEdge edge;
01027 edge._aclPoints[0] = this->_aclPointArray[it2->pt1];
01028 edge._aclPoints[1] = this->_aclPointArray[it2->pt2];
01029 edge._bBorder = it2->facetIdx == ULONG_MAX;
01030
01031 edges.push_back(edge);
01032 }
01033 }
01034
01035 unsigned long MeshKernel::CountEdges (void) const
01036 {
01037 unsigned long openEdges = 0, closedEdges = 0;
01038
01039 for (MeshFacetArray::_TConstIterator it = _aclFacetArray.begin(); it != _aclFacetArray.end(); it++) {
01040 for (int i = 0; i < 3; i++) {
01041 if (it->_aulNeighbours[i] == ULONG_MAX)
01042 openEdges++;
01043 else
01044 closedEdges++;
01045 }
01046 }
01047
01048 return (openEdges + (closedEdges / 2));
01049 }
01050