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 <vector>
00029 #endif
00030
00031 #include <Mod/Mesh/App/WildMagic4/Wm4Matrix3.h>
00032 #include <Mod/Mesh/App/WildMagic4/Wm4Vector3.h>
00033
00034 #include "Evaluation.h"
00035 #include "Iterator.h"
00036 #include "Algorithm.h"
00037 #include "Approximation.h"
00038 #include "MeshIO.h"
00039 #include "Helpers.h"
00040 #include "Grid.h"
00041 #include "TopoAlgorithm.h"
00042 #include <Base/Matrix.h>
00043
00044 #include <Base/Sequencer.h>
00045
00046 using namespace MeshCore;
00047
00048
00049 MeshOrientationVisitor::MeshOrientationVisitor() : _nonuniformOrientation(false)
00050 {
00051 }
00052
00053 bool MeshOrientationVisitor::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom,
00054 unsigned long ulFInd, unsigned long ulLevel)
00055 {
00056 if (!rclFrom.HasSameOrientation(rclFacet)) {
00057 _nonuniformOrientation = true;
00058 return false;
00059 }
00060
00061 return true;
00062 }
00063
00064 bool MeshOrientationVisitor::HasNonUnifomOrientedFacets() const
00065 {
00066 return _nonuniformOrientation;
00067 }
00068
00069 MeshOrientationCollector::MeshOrientationCollector(std::vector<unsigned long>& aulIndices, std::vector<unsigned long>& aulComplement)
00070 : _aulIndices(aulIndices), _aulComplement(aulComplement)
00071 {
00072 }
00073
00074 bool MeshOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom,
00075 unsigned long ulFInd, unsigned long ulLevel)
00076 {
00077
00078 if (!rclFacet.HasSameOrientation(rclFrom)) {
00079
00080 if (!rclFrom.IsFlag(MeshFacet::TMP0)) {
00081
00082 rclFacet.SetFlag(MeshFacet::TMP0);
00083 _aulIndices.push_back( ulFInd );
00084 }
00085 else
00086 _aulComplement.push_back( ulFInd );
00087 }
00088 else {
00089
00090
00091 if (rclFrom.IsFlag(MeshFacet::TMP0)) {
00092
00093 rclFacet.SetFlag(MeshFacet::TMP0);
00094 _aulIndices.push_back(ulFInd);
00095 }
00096 else
00097 _aulComplement.push_back( ulFInd );
00098 }
00099
00100 return true;
00101 }
00102
00103 MeshSameOrientationCollector::MeshSameOrientationCollector(std::vector<unsigned long>& aulIndices)
00104 : _aulIndices(aulIndices)
00105 {
00106 }
00107
00108 bool MeshSameOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom,
00109 unsigned long ulFInd, unsigned long ulLevel)
00110 {
00111
00112 if (rclFacet.HasSameOrientation(rclFrom)) {
00113 _aulIndices.push_back(ulFInd);
00114 }
00115
00116 return true;
00117 }
00118
00119
00120
00121 MeshEvalOrientation::MeshEvalOrientation (const MeshKernel& rclM)
00122 : MeshEvaluation( rclM )
00123 {
00124 }
00125
00126 MeshEvalOrientation::~MeshEvalOrientation()
00127 {
00128 }
00129
00130 bool MeshEvalOrientation::Evaluate ()
00131 {
00132 const MeshFacetArray& rFAry = _rclMesh.GetFacets();
00133 MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
00134 MeshFacetArray::_TConstIterator iEnd = rFAry.end();
00135 for (MeshFacetArray::_TConstIterator it = iBeg; it != iEnd; ++it) {
00136 for (int i = 0; i < 3; i++) {
00137 if (it->_aulNeighbours[i] != ULONG_MAX) {
00138 const MeshFacet& rclFacet = iBeg[it->_aulNeighbours[i]];
00139 for (int j = 0; j < 3; j++) {
00140 if (it->_aulPoints[i] == rclFacet._aulPoints[j]) {
00141 if ((it->_aulPoints[(i+1)%3] == rclFacet._aulPoints[(j+1)%3]) ||
00142 (it->_aulPoints[(i+2)%3] == rclFacet._aulPoints[(j+2)%3])) {
00143 return false;
00144 }
00145 }
00146 }
00147 }
00148 }
00149 }
00150
00151 return true;
00152 }
00153
00154 unsigned long MeshEvalOrientation::HasFalsePositives(const std::vector<unsigned long>& inds) const
00155 {
00156
00157
00158
00159
00160
00161
00162 const MeshFacetArray& rFAry = _rclMesh.GetFacets();
00163 MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
00164 for (std::vector<unsigned long>::const_iterator it = inds.begin(); it != inds.end(); ++it) {
00165 const MeshFacet& f = iBeg[*it];
00166 for (int i = 0; i < 3; i++) {
00167 if (f._aulNeighbours[i] != ULONG_MAX) {
00168 const MeshFacet& n = iBeg[f._aulNeighbours[i]];
00169 if (f.IsFlag(MeshFacet::TMP0) && !n.IsFlag(MeshFacet::TMP0)) {
00170 for (int j = 0; j < 3; j++) {
00171 if (f.HasSameOrientation(n)) {
00172
00173 return f._aulNeighbours[i];
00174 }
00175 }
00176 }
00177 }
00178 }
00179 }
00180
00181 return ULONG_MAX;
00182 }
00183
00184 std::vector<unsigned long> MeshEvalOrientation::GetIndices() const
00185 {
00186 unsigned long ulStartFacet, ulVisited;
00187
00188 if (_rclMesh.CountFacets() == 0)
00189 return std::vector<unsigned long>();
00190
00191
00192 MeshAlgorithm cAlg(_rclMesh);
00193 cAlg.ResetFacetFlag(MeshFacet::VISIT);
00194 cAlg.ResetFacetFlag(MeshFacet::TMP0);
00195
00196 const MeshFacetArray& rFAry = _rclMesh.GetFacets();
00197 MeshFacetArray::_TConstIterator iTri = rFAry.begin();
00198 MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
00199 MeshFacetArray::_TConstIterator iEnd = rFAry.end();
00200
00201 ulVisited = 0;
00202 ulStartFacet = 0;
00203
00204 std::vector<unsigned long> uIndices, uComplement;
00205 MeshOrientationCollector clHarmonizer(uIndices, uComplement);
00206
00207 while (ulStartFacet != ULONG_MAX) {
00208 unsigned long wrongFacets = uIndices.size();
00209
00210 uComplement.clear();
00211 uComplement.push_back( ulStartFacet );
00212 ulVisited = _rclMesh.VisitNeighbourFacets(clHarmonizer, ulStartFacet) + 1;
00213
00214
00215
00216
00217 if (uComplement.size() < (unsigned long)(0.4f*(float)ulVisited)) {
00218 uIndices.erase(uIndices.begin()+wrongFacets, uIndices.end());
00219 uIndices.insert(uIndices.end(), uComplement.begin(), uComplement.end());
00220 }
00221
00222
00223
00224
00225 iTri = std::find_if(iTri, iEnd, std::bind2nd(MeshIsNotFlag<MeshFacet>(), MeshFacet::VISIT));
00226
00227 if (iTri < iEnd)
00228 ulStartFacet = iTri - iBeg;
00229 else
00230 ulStartFacet = ULONG_MAX;
00231 }
00232
00233
00234
00235 cAlg.ResetFacetFlag(MeshFacet::TMP0);
00236 cAlg.SetFacetsFlag(uIndices, MeshFacet::TMP0);
00237 ulStartFacet = HasFalsePositives(uIndices);
00238 while (ulStartFacet != ULONG_MAX) {
00239 cAlg.ResetFacetsFlag(uIndices, MeshFacet::VISIT);
00240 std::vector<unsigned long> falsePos;
00241 MeshSameOrientationCollector coll(falsePos);
00242 _rclMesh.VisitNeighbourFacets(coll, ulStartFacet);
00243
00244 std::sort(uIndices.begin(), uIndices.end());
00245 std::sort(falsePos.begin(), falsePos.end());
00246
00247 std::vector<unsigned long> diff;
00248 std::back_insert_iterator<std::vector<unsigned long> > biit(diff);
00249 std::set_difference(uIndices.begin(), uIndices.end(), falsePos.begin(), falsePos.end(), biit);
00250 uIndices = diff;
00251
00252 cAlg.ResetFacetFlag(MeshFacet::TMP0);
00253 cAlg.SetFacetsFlag(uIndices, MeshFacet::TMP0);
00254 unsigned long current = ulStartFacet;
00255 ulStartFacet = HasFalsePositives(uIndices);
00256 if (current == ulStartFacet)
00257 break;
00258 }
00259
00260 return uIndices;
00261 }
00262
00263 MeshFixOrientation::MeshFixOrientation (MeshKernel& rclM)
00264 : MeshValidation( rclM )
00265 {
00266 }
00267
00268 MeshFixOrientation::~MeshFixOrientation()
00269 {
00270 }
00271
00272 bool MeshFixOrientation::Fixup ()
00273 {
00274 MeshTopoAlgorithm(_rclMesh).HarmonizeNormals();
00275 return MeshEvalOrientation(_rclMesh).Evaluate();
00276 }
00277
00278
00279
00280 MeshEvalSolid::MeshEvalSolid (const MeshKernel& rclM)
00281 :MeshEvaluation( rclM )
00282 {
00283 }
00284
00285 MeshEvalSolid::~MeshEvalSolid()
00286 {
00287 }
00288
00289 bool MeshEvalSolid::Evaluate ()
00290 {
00291 std::vector<MeshGeomEdge> edges;
00292 _rclMesh.GetEdges( edges );
00293 for (std::vector<MeshGeomEdge>::iterator it = edges.begin(); it != edges.end(); it++)
00294 {
00295 if (it->_bBorder)
00296 return false;
00297 }
00298
00299 return true;
00300 }
00301
00302
00303
00304 namespace MeshCore {
00305
00306 struct Edge_Index
00307 {
00308 unsigned long p0, p1, f;
00309 };
00310
00311 struct Edge_Less : public std::binary_function<const Edge_Index&,
00312 const Edge_Index&, bool>
00313 {
00314 bool operator()(const Edge_Index& x, const Edge_Index& y) const
00315 {
00316 if (x.p0 < y.p0)
00317 return true;
00318 else if (x.p0 > y.p0)
00319 return false;
00320 else if (x.p1 < y.p1)
00321 return true;
00322 else if (x.p1 > y.p1)
00323 return false;
00324 return false;
00325 }
00326 };
00327
00328 }
00329
00330 bool MeshEvalTopology::Evaluate ()
00331 {
00332
00333
00334 const MeshFacetArray& rclFAry = _rclMesh.GetFacets();
00335 std::vector<Edge_Index> edges;
00336 edges.reserve(3*rclFAry.size());
00337
00338
00339 MeshFacetArray::_TConstIterator pI;
00340 Base::SequencerLauncher seq("Checking topology...", rclFAry.size());
00341 for (pI = rclFAry.begin(); pI != rclFAry.end(); pI++) {
00342 for (int i = 0; i < 3; i++) {
00343 Edge_Index item;
00344 item.p0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00345 item.p1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00346 item.f = pI - rclFAry.begin();
00347 edges.push_back(item);
00348 }
00349
00350 seq.next();
00351 }
00352
00353
00354 std::sort(edges.begin(), edges.end(), Edge_Less());
00355
00356
00357 unsigned long p0 = ULONG_MAX, p1 = ULONG_MAX;
00358 nonManifoldList.clear();
00359 nonManifoldFacets.clear();
00360
00361 int count = 0;
00362 std::vector<unsigned long> facets;
00363 std::vector<Edge_Index>::iterator pE;
00364 for (pE = edges.begin(); pE != edges.end(); pE++) {
00365 if (p0 == pE->p0 && p1 == pE->p1) {
00366 count++;
00367 facets.push_back(pE->f);
00368 }
00369 else {
00370 if (count > 2) {
00371
00372 nonManifoldList.push_back(std::make_pair
00373 <unsigned long, unsigned long>(p0, p1));
00374 nonManifoldFacets.push_back(facets);
00375 }
00376
00377 p0 = pE->p0;
00378 p1 = pE->p1;
00379 facets.clear();
00380 facets.push_back(pE->f);
00381 count = 1;
00382 }
00383 }
00384
00385 return nonManifoldList.empty();
00386 }
00387
00388
00389 void MeshEvalTopology::GetFacetManifolds (std::vector<unsigned long> &raclFacetIndList) const
00390 {
00391 raclFacetIndList.clear();
00392 const MeshFacetArray& rclFAry = _rclMesh.GetFacets();
00393 MeshFacetArray::_TConstIterator pI;
00394
00395 for (pI = rclFAry.begin(); pI != rclFAry.end(); pI++) {
00396 for (int i = 0; i < 3; i++) {
00397 unsigned long ulPt0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00398 unsigned long ulPt1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00399 std::pair<unsigned long, unsigned long> edge = std::make_pair<unsigned long, unsigned long>(ulPt0, ulPt1);
00400
00401 if (std::find(nonManifoldList.begin(), nonManifoldList.end(), edge) != nonManifoldList.end())
00402 raclFacetIndList.push_back(pI - rclFAry.begin());
00403 }
00404 }
00405 }
00406
00407 unsigned long MeshEvalTopology::CountManifolds() const
00408 {
00409 return nonManifoldList.size();
00410 }
00411
00412 bool MeshFixTopology::Fixup ()
00413 {
00414 std::vector<unsigned long> indices;
00415 #if 0
00416 MeshEvalTopology eval(_rclMesh);
00417 if (!eval.Evaluate()) {
00418 eval.GetFacetManifolds(indices);
00419
00420
00421 std::sort(indices.begin(), indices.end());
00422 indices.erase(std::unique(indices.begin(), indices.end()), indices.end());
00423
00424 _rclMesh.DeleteFacets(indices);
00425 }
00426 #else
00427 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00428 indices.reserve(3 * nonManifoldList.size());
00429 std::list<std::vector<unsigned long> >::const_iterator it;
00430 for (it = nonManifoldList.begin(); it != nonManifoldList.end(); ++it) {
00431 std::vector<unsigned long> non_mf;
00432 non_mf.reserve(it->size());
00433 for (std::vector<unsigned long>::const_iterator jt = it->begin(); jt != it->end(); ++jt) {
00434
00435 unsigned short numOpenEdges = rFaces[*jt].CountOpenEdges();
00436 if (numOpenEdges == 2)
00437 non_mf.push_back(*jt);
00438 else if (rFaces[*jt].IsDegenerated())
00439 non_mf.push_back(*jt);
00440 }
00441
00442
00443 if (it->size() - non_mf.size() == 2)
00444 indices.insert(indices.end(), non_mf.begin(), non_mf.end());
00445 else
00446 indices.insert(indices.end(), it->begin(), it->end());
00447 }
00448
00449 if (!indices.empty()) {
00450
00451 std::sort(indices.begin(), indices.end());
00452 indices.erase(std::unique(indices.begin(), indices.end()), indices.end());
00453
00454 _rclMesh.DeleteFacets(indices);
00455 _rclMesh.RebuildNeighbours();
00456 }
00457 #endif
00458
00459 return true;
00460 }
00461
00462
00463
00464 bool MeshEvalSingleFacet::Evaluate ()
00465 {
00466
00467 MeshEvalTopology::Evaluate();
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 return (nonManifoldList.size() == 0);
00524 }
00525
00526 bool MeshFixSingleFacet::Fixup ()
00527 {
00528 std::vector<unsigned long> aulInvalids;
00529
00530 for ( std::vector<std::list<unsigned long> >::const_iterator it=_raclManifoldList.begin();it!=_raclManifoldList.end();++it )
00531 {
00532 for ( std::list<unsigned long>::const_iterator it2 = it->begin(); it2 != it->end(); ++it2 )
00533 {
00534 aulInvalids.push_back(*it2);
00535
00536 }
00537 }
00538
00539 _rclMesh.DeleteFacets(aulInvalids);
00540 return true;
00541 }
00542
00543
00544
00545 bool MeshEvalSelfIntersection::Evaluate ()
00546 {
00547
00548 std::vector<Base::BoundBox3f> boxes;
00549
00550
00551 MeshFacetGrid cMeshFacetGrid(_rclMesh);
00552 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00553 MeshGridIterator clGridIter(cMeshFacetGrid);
00554 unsigned long ulGridX, ulGridY, ulGridZ;
00555 cMeshFacetGrid.GetCtGrids(ulGridX, ulGridY, ulGridZ);
00556
00557 MeshFacetIterator cMFI(_rclMesh);
00558 for (cMFI.Begin(); cMFI.More(); cMFI.Next()) {
00559 boxes.push_back((*cMFI).GetBoundBox());
00560 }
00561
00562
00563 Base::SequencerLauncher seq("Checking for self-intersections...", ulGridX*ulGridY*ulGridZ);
00564 for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
00565
00566 std::vector<unsigned long> aulGridElements;
00567 clGridIter.GetElements(aulGridElements);
00568
00569 seq.next();
00570 if (aulGridElements.size()==0)
00571 continue;
00572
00573 MeshGeomFacet facet1, facet2;
00574 Base::Vector3f pt1, pt2;
00575 for (std::vector<unsigned long>::iterator it = aulGridElements.begin(); it != aulGridElements.end(); ++it) {
00576 const Base::BoundBox3f& box1 = boxes[*it];
00577 cMFI.Set(*it);
00578 facet1 = *cMFI;
00579 const MeshFacet& rface1 = rFaces[*it];
00580 for (std::vector<unsigned long>::iterator jt = it; jt != aulGridElements.end(); ++jt) {
00581 if (jt == it)
00582 continue;
00583
00584
00585
00586 const MeshFacet& rface2 = rFaces[*jt];
00587 if (rface1._aulPoints[0] == rface2._aulPoints[0] ||
00588 rface1._aulPoints[0] == rface2._aulPoints[1] ||
00589 rface1._aulPoints[0] == rface2._aulPoints[2])
00590 continue;
00591 if (rface1._aulPoints[1] == rface2._aulPoints[0] ||
00592 rface1._aulPoints[1] == rface2._aulPoints[1] ||
00593 rface1._aulPoints[1] == rface2._aulPoints[2])
00594 continue;
00595 if (rface1._aulPoints[2] == rface2._aulPoints[0] ||
00596 rface1._aulPoints[2] == rface2._aulPoints[1] ||
00597 rface1._aulPoints[2] == rface2._aulPoints[2])
00598 continue;
00599
00600 const Base::BoundBox3f& box2 = boxes[*jt];
00601 if (box1 && box2) {
00602 cMFI.Set(*jt);
00603 facet2 = *cMFI;
00604 int ret = facet1.IntersectWithFacet(facet2, pt1, pt2);
00605 if (ret == 2) {
00606
00607 return false;
00608 }
00609 }
00610 }
00611 }
00612 }
00613
00614 return true;
00615 }
00616
00617 void MeshEvalSelfIntersection::GetIntersections(const std::vector<std::pair<unsigned long, unsigned long> >& indices,
00618 std::vector<std::pair<Base::Vector3f, Base::Vector3f> >& intersection) const
00619 {
00620 intersection.reserve(indices.size());
00621 MeshFacetIterator cMF1(_rclMesh);
00622 MeshFacetIterator cMF2(_rclMesh);
00623
00624 Base::Vector3f pt1, pt2;
00625 std::vector<std::pair<unsigned long, unsigned long> >::const_iterator it;
00626 for (it = indices.begin(); it != indices.end(); ++it) {
00627 cMF1.Set(it->first);
00628 cMF2.Set(it->second);
00629
00630 Base::BoundBox3f box1 = cMF1->GetBoundBox();
00631 Base::BoundBox3f box2 = cMF2->GetBoundBox();
00632 if (box1 && box2) {
00633 int ret = cMF1->IntersectWithFacet(*cMF2, pt1, pt2);
00634 if (ret == 2) {
00635 intersection.push_back(std::make_pair(pt1, pt2));
00636 }
00637 }
00638 }
00639 }
00640
00641 void MeshEvalSelfIntersection::GetIntersections(std::vector<std::pair<unsigned long, unsigned long> >& intersection) const
00642 {
00643
00644 std::vector<Base::BoundBox3f> boxes;
00645
00646
00647
00648 MeshFacetGrid cMeshFacetGrid(_rclMesh);
00649 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00650 MeshGridIterator clGridIter(cMeshFacetGrid);
00651 unsigned long ulGridX, ulGridY, ulGridZ;
00652 cMeshFacetGrid.GetCtGrids(ulGridX, ulGridY, ulGridZ);
00653
00654 MeshFacetIterator cMFI(_rclMesh);
00655 for(cMFI.Begin(); cMFI.More(); cMFI.Next()) {
00656 boxes.push_back((*cMFI).GetBoundBox());
00657 }
00658
00659
00660 Base::SequencerLauncher seq("Checking for self-intersections...", ulGridX*ulGridY*ulGridZ);
00661 for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
00662
00663 std::vector<unsigned long> aulGridElements;
00664 clGridIter.GetElements(aulGridElements);
00665
00666 seq.next(true);
00667 if (aulGridElements.size()==0)
00668 continue;
00669
00670 MeshGeomFacet facet1, facet2;
00671 Base::Vector3f pt1, pt2;
00672 for (std::vector<unsigned long>::iterator it = aulGridElements.begin(); it != aulGridElements.end(); ++it) {
00673 const Base::BoundBox3f& box1 = boxes[*it];
00674 cMFI.Set(*it);
00675 facet1 = *cMFI;
00676 const MeshFacet& rface1 = rFaces[*it];
00677 for (std::vector<unsigned long>::iterator jt = it; jt != aulGridElements.end(); ++jt) {
00678 if (jt == it)
00679 continue;
00680
00681
00682
00683 const MeshFacet& rface2 = rFaces[*jt];
00684 if (rface1._aulPoints[0] == rface2._aulPoints[0] ||
00685 rface1._aulPoints[0] == rface2._aulPoints[1] ||
00686 rface1._aulPoints[0] == rface2._aulPoints[2])
00687 continue;
00688 if (rface1._aulPoints[1] == rface2._aulPoints[0] ||
00689 rface1._aulPoints[1] == rface2._aulPoints[1] ||
00690 rface1._aulPoints[1] == rface2._aulPoints[2])
00691 continue;
00692 if (rface1._aulPoints[2] == rface2._aulPoints[0] ||
00693 rface1._aulPoints[2] == rface2._aulPoints[1] ||
00694 rface1._aulPoints[2] == rface2._aulPoints[2])
00695 continue;
00696
00697 const Base::BoundBox3f& box2 = boxes[*jt];
00698 if (box1 && box2) {
00699 cMFI.Set(*jt);
00700 facet2 = *cMFI;
00701 int ret = facet1.IntersectWithFacet(facet2, pt1, pt2);
00702 if (ret == 2) {
00703 intersection.push_back(std::make_pair
00704 <unsigned long, unsigned long>(*it,*jt));
00705 }
00706 }
00707 }
00708 }
00709 }
00710 }
00711
00712 bool MeshFixSelfIntersection::Fixup()
00713 {
00714 std::vector<unsigned long> indices;
00715 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00716 for (std::vector<std::pair<unsigned long, unsigned long> >::const_iterator
00717 it = selfIntersectons.begin(); it != selfIntersectons.end(); ++it) {
00718 unsigned short numOpenEdges1 = rFaces[it->first].CountOpenEdges();
00719 unsigned short numOpenEdges2 = rFaces[it->second].CountOpenEdges();
00720
00721
00722
00723 if (numOpenEdges1 == 0 && numOpenEdges2 > 0) {
00724 indices.push_back(it->second);
00725 }
00726 else if (numOpenEdges1 > 0 && numOpenEdges2 == 0) {
00727 indices.push_back(it->first);
00728 }
00729 else {
00730 indices.push_back(it->first);
00731 indices.push_back(it->second);
00732 }
00733 }
00734
00735
00736 std::sort(indices.begin(), indices.end());
00737 indices.erase(std::unique(indices.begin(), indices.end()), indices.end());
00738
00739 _rclMesh.DeleteFacets(indices);
00740
00741 return true;
00742 }
00743
00744
00745
00746 bool MeshEvalNeighbourhood::Evaluate ()
00747 {
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 const MeshFacetArray& rclFAry = _rclMesh.GetFacets();
00759 std::vector<Edge_Index> edges;
00760 edges.reserve(3*rclFAry.size());
00761
00762
00763 MeshFacetArray::_TConstIterator pI;
00764 Base::SequencerLauncher seq("Checking indices...", rclFAry.size());
00765 for (pI = rclFAry.begin(); pI != rclFAry.end(); pI++) {
00766 for (int i = 0; i < 3; i++) {
00767 Edge_Index item;
00768 item.p0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00769 item.p1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00770 item.f = pI - rclFAry.begin();
00771 edges.push_back(item);
00772 }
00773
00774 seq.next();
00775 }
00776
00777
00778 std::sort(edges.begin(), edges.end(), Edge_Less());
00779
00780 unsigned long p0 = ULONG_MAX, p1 = ULONG_MAX;
00781 unsigned long f0 = ULONG_MAX, f1 = ULONG_MAX;
00782 int count = 0;
00783 std::vector<Edge_Index>::iterator pE;
00784 for (pE = edges.begin(); pE != edges.end(); pE++) {
00785 if (p0 == pE->p0 && p1 == pE->p1) {
00786 f1 = pE->f;
00787 count++;
00788 }
00789 else {
00790
00791
00792 if (count == 2) {
00793 const MeshFacet& rFace0 = rclFAry[f0];
00794 const MeshFacet& rFace1 = rclFAry[f1];
00795 unsigned short side0 = rFace0.Side(p0,p1);
00796 unsigned short side1 = rFace1.Side(p0,p1);
00797
00798
00799 if (rFace0._aulNeighbours[side0]!=f1 ||
00800 rFace1._aulNeighbours[side1]!=f0)
00801 return false;
00802 }
00803 else if (count == 1) {
00804 const MeshFacet& rFace = rclFAry[f0];
00805 unsigned short side = rFace.Side(p0,p1);
00806
00807 if (rFace._aulNeighbours[side] != ULONG_MAX)
00808 return false;
00809 }
00810
00811 p0 = pE->p0;
00812 p1 = pE->p1;
00813 f0 = pE->f;
00814 count = 1;
00815 }
00816 }
00817
00818 return true;
00819 }
00820
00821 std::vector<unsigned long> MeshEvalNeighbourhood::GetIndices() const
00822 {
00823 std::vector<unsigned long> inds;
00824 const MeshFacetArray& rclFAry = _rclMesh.GetFacets();
00825 std::vector<Edge_Index> edges;
00826 edges.reserve(3*rclFAry.size());
00827
00828
00829 MeshFacetArray::_TConstIterator pI;
00830 Base::SequencerLauncher seq("Checking indices...", rclFAry.size());
00831 for (pI = rclFAry.begin(); pI != rclFAry.end(); pI++) {
00832 for (int i = 0; i < 3; i++) {
00833 Edge_Index item;
00834 item.p0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00835 item.p1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00836 item.f = pI - rclFAry.begin();
00837 edges.push_back(item);
00838 }
00839
00840 seq.next();
00841 }
00842
00843
00844 std::sort(edges.begin(), edges.end(), Edge_Less());
00845
00846 unsigned long p0 = ULONG_MAX, p1 = ULONG_MAX;
00847 unsigned long f0 = ULONG_MAX, f1 = ULONG_MAX;
00848 int count = 0;
00849 std::vector<Edge_Index>::iterator pE;
00850 for (pE = edges.begin(); pE != edges.end(); pE++) {
00851 if (p0 == pE->p0 && p1 == pE->p1) {
00852 f1 = pE->f;
00853 count++;
00854 }
00855 else {
00856
00857
00858 if (count == 2) {
00859 const MeshFacet& rFace0 = rclFAry[f0];
00860 const MeshFacet& rFace1 = rclFAry[f1];
00861 unsigned short side0 = rFace0.Side(p0,p1);
00862 unsigned short side1 = rFace1.Side(p0,p1);
00863
00864
00865 if (rFace0._aulNeighbours[side0]!=f1 ||
00866 rFace1._aulNeighbours[side1]!=f0) {
00867 inds.push_back(f0);
00868 inds.push_back(f1);
00869 }
00870 }
00871 else if (count == 1) {
00872 const MeshFacet& rFace = rclFAry[f0];
00873 unsigned short side = rFace.Side(p0,p1);
00874
00875 if (rFace._aulNeighbours[side] != ULONG_MAX)
00876 inds.push_back(f0);
00877 }
00878
00879 p0 = pE->p0;
00880 p1 = pE->p1;
00881 f0 = pE->f;
00882 count = 1;
00883 }
00884 }
00885
00886
00887 std::sort(inds.begin(), inds.end());
00888 inds.erase(std::unique(inds.begin(), inds.end()), inds.end());
00889
00890 return inds;
00891 }
00892
00893 bool MeshFixNeighbourhood::Fixup()
00894 {
00895 _rclMesh.RebuildNeighbours();
00896 return true;
00897 }
00898
00899 void MeshKernel::RebuildNeighbours (unsigned long index)
00900 {
00901 std::vector<Edge_Index> edges;
00902 edges.reserve(3 * (this->_aclFacetArray.size() - index));
00903
00904
00905 MeshFacetArray::_TConstIterator pI;
00906 MeshFacetArray::_TConstIterator pB = this->_aclFacetArray.begin();
00907 for (pI = pB + index; pI != this->_aclFacetArray.end(); pI++) {
00908 for (int i = 0; i < 3; i++) {
00909 Edge_Index item;
00910 item.p0 = std::min<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00911 item.p1 = std::max<unsigned long>(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]);
00912 item.f = pI - pB;
00913 edges.push_back(item);
00914 }
00915 }
00916
00917
00918 std::sort(edges.begin(), edges.end(), Edge_Less());
00919
00920 unsigned long p0 = ULONG_MAX, p1 = ULONG_MAX;
00921 unsigned long f0 = ULONG_MAX, f1 = ULONG_MAX;
00922 int count = 0;
00923 std::vector<Edge_Index>::iterator pE;
00924 for (pE = edges.begin(); pE != edges.end(); pE++) {
00925 if (p0 == pE->p0 && p1 == pE->p1) {
00926 f1 = pE->f;
00927 count++;
00928 }
00929 else {
00930
00931
00932 if (count == 2) {
00933 MeshFacet& rFace0 = this->_aclFacetArray[f0];
00934 MeshFacet& rFace1 = this->_aclFacetArray[f1];
00935 unsigned short side0 = rFace0.Side(p0,p1);
00936 unsigned short side1 = rFace1.Side(p0,p1);
00937 rFace0._aulNeighbours[side0] = f1;
00938 rFace1._aulNeighbours[side1] = f0;
00939 }
00940 else if (count == 1) {
00941 MeshFacet& rFace = this->_aclFacetArray[f0];
00942 unsigned short side = rFace.Side(p0,p1);
00943 rFace._aulNeighbours[side] = ULONG_MAX;
00944 }
00945
00946 p0 = pE->p0;
00947 p1 = pE->p1;
00948 f0 = pE->f;
00949 count = 1;
00950 }
00951 }
00952
00953
00954
00955 if (count == 2) {
00956 MeshFacet& rFace0 = this->_aclFacetArray[f0];
00957 MeshFacet& rFace1 = this->_aclFacetArray[f1];
00958 unsigned short side0 = rFace0.Side(p0,p1);
00959 unsigned short side1 = rFace1.Side(p0,p1);
00960 rFace0._aulNeighbours[side0] = f1;
00961 rFace1._aulNeighbours[side1] = f0;
00962 }
00963 else if (count == 1) {
00964 MeshFacet& rFace = this->_aclFacetArray[f0];
00965 unsigned short side = rFace.Side(p0,p1);
00966 rFace._aulNeighbours[side] = ULONG_MAX;
00967 }
00968 }
00969
00970 void MeshKernel::RebuildNeighbours (void)
00971 {
00972
00973 RebuildNeighbours(0);
00974 }
00975
00976
00977
00978 MeshEigensystem::MeshEigensystem (const MeshKernel &rclB)
00979 : MeshEvaluation(rclB), _cU(1.0f, 0.0f, 0.0f), _cV(0.0f, 1.0f, 0.0f), _cW(0.0f, 0.0f, 1.0f)
00980 {
00981
00982 Base::BoundBox3f box = _rclMesh.GetBoundBox();
00983 _fU = box.LengthX();
00984 _fV = box.LengthY();
00985 _fW = box.LengthZ();
00986 }
00987
00988 Base::Matrix4D MeshEigensystem::Transform() const
00989 {
00990
00991
00992
00993
00994
00995
00996
00997 Base::Matrix4D clTMat;
00998
00999 clTMat[0][0] = _cU.x; clTMat[0][1] = _cU.y; clTMat[0][2] = _cU.z; clTMat[0][3] = 0.0f;
01000 clTMat[1][0] = _cV.x; clTMat[1][1] = _cV.y; clTMat[1][2] = _cV.z; clTMat[1][3] = 0.0f;
01001 clTMat[2][0] = _cW.x; clTMat[2][1] = _cW.y; clTMat[2][2] = _cW.z; clTMat[2][3] = 0.0f;
01002 clTMat[3][0] = 0.0f; clTMat[3][1] = 0.0f; clTMat[3][2] = 0.0f; clTMat[3][3] = 1.0f;
01003
01004 Base::Vector3f c(_cC);
01005 c = clTMat * c;
01006
01007
01008 clTMat[0][3] = -c.x; clTMat[1][3] = -c.y; clTMat[2][3] = -c.z;
01009
01010 return clTMat;
01011 }
01012
01013 bool MeshEigensystem::Evaluate()
01014 {
01015 CalculateLocalSystem();
01016
01017 float xmin=0.0f, xmax=0.0f, ymin=0.0f, ymax=0.0f, zmin=0.0f, zmax=0.0f;
01018
01019 Base::Vector3f clVect, clProj;
01020 float fH;
01021
01022 const MeshPointArray& aclPoints = _rclMesh.GetPoints ();
01023 for (MeshPointArray::_TConstIterator it = aclPoints.begin(); it!=aclPoints.end(); ++it) {
01024
01025 clVect = *it - _cC;
01026 clProj.ProjToLine(clVect, _cU);
01027 clVect = clVect + clProj;
01028 fH = clVect.Length();
01029
01030
01031 if ((clVect * _cU) < 0.0f)
01032 fH = -fH;
01033
01034 xmax = std::max<float>(xmax, fH);
01035 xmin = std::min<float>(xmin, fH);
01036
01037
01038 clVect = *it - _cC;
01039 clProj.ProjToLine(clVect, _cV);
01040 clVect = clVect + clProj;
01041 fH = clVect.Length();
01042
01043
01044 if ((clVect * _cV) < 0.0f)
01045 fH = -fH;
01046
01047 ymax = std::max<float>(ymax, fH);
01048 ymin = std::min<float>(ymin, fH);
01049
01050
01051 clVect = *it - _cC;
01052 clProj.ProjToLine(clVect, _cW);
01053 clVect = clVect + clProj;
01054 fH = clVect.Length();
01055
01056
01057 if ((clVect * _cW) < 0.0f)
01058 fH = -fH;
01059
01060 zmax = std::max<float>(zmax, fH);
01061 zmin = std::min<float>(zmin, fH);
01062 }
01063
01064 _fU = xmax - xmin;
01065 _fV = ymax - ymin;
01066 _fW = zmax - zmin;
01067
01068 return false;
01069 }
01070
01071 Base::Vector3f MeshEigensystem::GetBoundings() const
01072 {
01073 return Base::Vector3f ( _fU, _fV, _fW );
01074 }
01075
01076 void MeshEigensystem::CalculateLocalSystem()
01077 {
01078
01079 if (_rclMesh.CountFacets() < 1)
01080 return;
01081
01082 const MeshPointArray& aclPoints = _rclMesh.GetPoints ();
01083 MeshPointArray::_TConstIterator it;
01084
01085 PlaneFit planeFit;
01086 for (it = aclPoints.begin(); it!=aclPoints.end(); ++it)
01087 planeFit.AddPoint(*it);
01088
01089 planeFit.Fit();
01090 _cC = planeFit.GetBase();
01091 _cU = planeFit.GetDirU();
01092 _cV = planeFit.GetDirV();
01093 _cW = planeFit.GetNormal();
01094
01095
01096 float fSumU, fSumV, fSumW;
01097 fSumU = fSumV = fSumW = 0.0f;
01098 for (it = aclPoints.begin(); it!=aclPoints.end(); ++it)
01099 {
01100 float fU = _cU * (*it - _cC);
01101 float fV = _cV * (*it - _cC);
01102 float fW = _cW * (*it - _cC);
01103 fSumU += (fU > 0 ? fU * fU : -fU * fU);
01104 fSumV += (fV > 0 ? fV * fV : -fV * fV);
01105 fSumW += (fW > 0 ? fW * fW : -fW * fW);
01106 }
01107
01108
01109 if (fSumU < 0.0f)
01110 _cU *= -1.0f;
01111 if (fSumV < 0.0f)
01112 _cV *= -1.0f;
01113 if (fSumW < 0.0f)
01114 _cW *= -1.0f;
01115
01116 if ((_cU%_cV)*_cW < 0.0f)
01117 _cW = -_cW;
01118 }