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 <map>
00029 #endif
00030
00031 #include "Degeneration.h"
00032 #include "Definitions.h"
00033 #include "Iterator.h"
00034 #include "Helpers.h"
00035 #include "MeshKernel.h"
00036 #include "Algorithm.h"
00037 #include "Info.h"
00038 #include "Grid.h"
00039 #include "TopoAlgorithm.h"
00040
00041 #include <Base/Sequencer.h>
00042
00043 using namespace MeshCore;
00044
00045 bool MeshEvalInvalids::Evaluate()
00046 {
00047 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00048 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it )
00049 {
00050 if ( !it->IsValid() )
00051 return false;
00052 }
00053
00054 const MeshPointArray& rPoints = _rclMesh.GetPoints();
00055 for ( MeshPointArray::_TConstIterator jt = rPoints.begin(); jt != rPoints.end(); ++jt )
00056 {
00057 if ( !jt->IsValid() )
00058 return false;
00059 }
00060
00061 return true;
00062 }
00063
00064 std::vector<unsigned long> MeshEvalInvalids::GetIndices() const
00065 {
00066 std::vector<unsigned long> aInds;
00067 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00068 const MeshPointArray& rPoints = _rclMesh.GetPoints();
00069 unsigned long ind=0;
00070 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ )
00071 {
00072 if ( !it->IsValid() )
00073 aInds.push_back(ind);
00074 else if ( !rPoints[it->_aulPoints[0]].IsValid() )
00075 aInds.push_back(ind);
00076 else if ( !rPoints[it->_aulPoints[1]].IsValid() )
00077 aInds.push_back(ind);
00078 else if ( !rPoints[it->_aulPoints[2]].IsValid() )
00079 aInds.push_back(ind);
00080 }
00081
00082 return aInds;
00083 }
00084
00085 bool MeshFixInvalids::Fixup()
00086 {
00087 _rclMesh.RemoveInvalids();
00088 return true;
00089 }
00090
00091
00092
00093 namespace MeshCore {
00094
00095 typedef MeshPointArray::_TConstIterator VertexIterator;
00096
00097
00098
00099
00100
00101
00102
00103 struct Vertex_EqualTo : public std::binary_function<const VertexIterator&,
00104 const VertexIterator&, bool>
00105 {
00106 bool operator()(const VertexIterator& x,
00107 const VertexIterator& y) const
00108 {
00109 if ( (*x) < (*y) )
00110 return false;
00111 else if ( (*y) < (*x) )
00112 return false;
00113 return true;
00114 }
00115 };
00116
00117 struct Vertex_Less : public std::binary_function<const VertexIterator&,
00118 const VertexIterator&, bool>
00119 {
00120 bool operator()(const VertexIterator& x,
00121 const VertexIterator& y) const
00122 {
00123 return (*x) < (*y);
00124 }
00125 };
00126
00127 }
00128
00129 bool MeshEvalDuplicatePoints::Evaluate()
00130 {
00131
00132
00133 const MeshPointArray& rPoints = _rclMesh.GetPoints();
00134 std::vector<VertexIterator> vertices;
00135 vertices.reserve(rPoints.size());
00136 for (MeshPointArray::_TConstIterator it = rPoints.begin(); it != rPoints.end(); ++it) {
00137 vertices.push_back(it);
00138 }
00139
00140
00141 std::sort(vertices.begin(), vertices.end(), Vertex_Less());
00142 if (std::adjacent_find(vertices.begin(), vertices.end(), Vertex_EqualTo()) < vertices.end() )
00143 return false;
00144 return true;
00145 }
00146
00147 std::vector<unsigned long> MeshEvalDuplicatePoints::GetIndices() const
00148 {
00149
00150
00151
00152 const MeshPointArray& rPoints = _rclMesh.GetPoints();
00153 std::vector<VertexIterator> vertices;
00154 vertices.reserve(rPoints.size());
00155 for (MeshPointArray::_TConstIterator it = rPoints.begin(); it != rPoints.end(); ++it) {
00156 vertices.push_back(it);
00157 }
00158
00159
00160 std::vector<unsigned long> aInds;
00161 Vertex_EqualTo pred;
00162 std::sort(vertices.begin(), vertices.end(), Vertex_Less());
00163
00164 std::vector<VertexIterator>::iterator vt = vertices.begin();
00165 while (vt < vertices.end()) {
00166
00167 vt = std::adjacent_find(vt, vertices.end(), pred);
00168 if (vt < vertices.end()) {
00169 vt++;
00170 aInds.push_back(*vt - rPoints.begin());
00171 }
00172 }
00173
00174 return aInds;
00175 }
00176
00177 bool MeshFixDuplicatePoints::Fixup()
00178 {
00179
00180
00181
00182 const MeshPointArray& rPoints = _rclMesh.GetPoints();
00183 std::vector<VertexIterator> vertices;
00184 vertices.reserve(rPoints.size());
00185 for (MeshPointArray::_TConstIterator it = rPoints.begin(); it != rPoints.end(); ++it) {
00186 vertices.push_back(it);
00187 }
00188
00189
00190 std::vector<unsigned long> aInds;
00191 std::sort(vertices.begin(), vertices.end(), Vertex_Less());
00192
00193 Vertex_EqualTo pred;
00194 std::vector<VertexIterator>::iterator next = vertices.begin();
00195 std::map<unsigned long, unsigned long> mapPointIndex;
00196 std::vector<unsigned long> pointIndices;
00197 while (next < vertices.end()) {
00198 next = std::adjacent_find(next, vertices.end(), pred);
00199 if (next < vertices.end()) {
00200 std::vector<VertexIterator>::iterator first = next;
00201 unsigned long first_index = *first - rPoints.begin();
00202 next++;
00203 while (next < vertices.end() && pred(*first, *next)) {
00204 unsigned long next_index = *next - rPoints.begin();
00205 mapPointIndex[next_index] = first_index;
00206 pointIndices.push_back(next_index);
00207 next++;
00208 }
00209 }
00210 }
00211
00212
00213 MeshFacetArray& rFacets = _rclMesh._aclFacetArray;
00214 for (MeshFacetArray::_TIterator it = rFacets.begin(); it != rFacets.end(); ++it) {
00215 for (int i=0; i<3; i++) {
00216 std::map<unsigned long, unsigned long>::iterator pt = mapPointIndex.find(it->_aulPoints[i]);
00217 if (pt != mapPointIndex.end())
00218 it->_aulPoints[i] = pt->second;
00219 }
00220 }
00221
00222
00223 _rclMesh.DeletePoints(pointIndices);
00224 _rclMesh.RebuildNeighbours();
00225
00226 return true;
00227 }
00228
00229
00230
00231 namespace MeshCore {
00232
00233 typedef MeshFacetArray::_TConstIterator FaceIterator;
00234
00235
00236
00237 struct MeshFacet_Less : public std::binary_function<const FaceIterator&,
00238 const FaceIterator&, bool>
00239 {
00240 bool operator()(const FaceIterator& x,
00241 const FaceIterator& y) const
00242 {
00243 unsigned long tmp;
00244 unsigned long x0 = x->_aulPoints[0];
00245 unsigned long x1 = x->_aulPoints[1];
00246 unsigned long x2 = x->_aulPoints[2];
00247 unsigned long y0 = y->_aulPoints[0];
00248 unsigned long y1 = y->_aulPoints[1];
00249 unsigned long y2 = y->_aulPoints[2];
00250
00251 if (x0 > x1)
00252 { tmp = x0; x0 = x1; x1 = tmp; }
00253 if (x0 > x2)
00254 { tmp = x0; x0 = x2; x2 = tmp; }
00255 if (x1 > x2)
00256 { tmp = x1; x1 = x2; x2 = tmp; }
00257 if (y0 > y1)
00258 { tmp = y0; y0 = y1; y1 = tmp; }
00259 if (y0 > y2)
00260 { tmp = y0; y0 = y2; y2 = tmp; }
00261 if (y1 > y2)
00262 { tmp = y1; y1 = y2; y2 = tmp; }
00263
00264 if (x0 < y0) return true;
00265 else if (x0 > y0) return false;
00266 else if (x1 < y1) return true;
00267 else if (x1 > y1) return false;
00268 else if (x2 < y2) return true;
00269 else return false;
00270 }
00271 };
00272
00273 }
00274
00275
00276
00277
00278
00279 struct MeshFacet_EqualTo : public std::binary_function<const FaceIterator&,
00280 const FaceIterator&, bool>
00281 {
00282 bool operator()(const FaceIterator& x,
00283 const FaceIterator& y) const
00284 {
00285 for (int i=0; i<3; i++ ) {
00286 if (x->_aulPoints[0] == y->_aulPoints[i]) {
00287 if (x->_aulPoints[1] == y->_aulPoints[(i+1)%3] &&
00288 x->_aulPoints[2] == y->_aulPoints[(i+2)%3])
00289 return true;
00290 else if (x->_aulPoints[1] == y->_aulPoints[(i+2)%3] &&
00291 x->_aulPoints[2] == y->_aulPoints[(i+1)%3])
00292 return true;
00293 }
00294 }
00295
00296 return false;
00297 }
00298 };
00299
00300 bool MeshEvalDuplicateFacets::Evaluate()
00301 {
00302 std::set<FaceIterator, MeshFacet_Less> aFaces;
00303 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00304 for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it)
00305 {
00306 std::pair<std::set<FaceIterator, MeshFacet_Less>::iterator, bool>
00307 pI = aFaces.insert(it);
00308 if (!pI.second)
00309 return false;
00310 }
00311
00312 return true;
00313 }
00314
00315 std::vector<unsigned long> MeshEvalDuplicateFacets::GetIndices() const
00316 {
00317 #if 1
00318 const MeshFacetArray& rFacets = _rclMesh.GetFacets();
00319 std::vector<FaceIterator> faces;
00320 faces.reserve(rFacets.size());
00321 for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it) {
00322 faces.push_back(it);
00323 }
00324
00325
00326 std::vector<unsigned long> aInds;
00327 MeshFacet_EqualTo pred;
00328 std::sort(faces.begin(), faces.end(), MeshFacet_Less());
00329
00330 std::vector<FaceIterator>::iterator ft = faces.begin();
00331 while (ft < faces.end()) {
00332
00333 ft = std::adjacent_find(ft, faces.end(), pred);
00334 if (ft < faces.end()) {
00335 ft++;
00336 aInds.push_back(*ft - rFacets.begin());
00337 }
00338 }
00339
00340 return aInds;
00341 #else
00342 std::vector<unsigned long> aInds;
00343 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00344 unsigned long uIndex=0;
00345
00346
00347 std::set<FaceIterator, MeshFacet_Less > aFaceSet;
00348 for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++)
00349 {
00350 std::pair<std::set<FaceIterator, MeshFacet_Less>::iterator, bool>
00351 pI = aFaceSet.insert(it);
00352 if (!pI.second)
00353 aInds.push_back(uIndex);
00354 }
00355
00356 return aInds;
00357 #endif
00358 }
00359
00360 bool MeshFixDuplicateFacets::Fixup()
00361 {
00362 unsigned long uIndex=0;
00363 std::vector<unsigned long> aRemoveFaces;
00364 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00365
00366
00367 std::set<FaceIterator, MeshFacet_Less > aFaceSet;
00368 for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++) {
00369 std::pair<std::set<FaceIterator, MeshFacet_Less>::iterator, bool>
00370 pI = aFaceSet.insert(it);
00371 if (!pI.second)
00372 aRemoveFaces.push_back(uIndex);
00373 }
00374
00375 _rclMesh.DeleteFacets(aRemoveFaces);
00376 _rclMesh.RebuildNeighbours();
00377
00378 return true;
00379 }
00380
00381
00382
00383 bool MeshEvalDegeneratedFacets::Evaluate()
00384 {
00385 MeshFacetIterator it(_rclMesh);
00386 for ( it.Init(); it.More(); it.Next() )
00387 {
00388 if ( it->IsDegenerated() )
00389 return false;
00390 }
00391
00392 return true;
00393 }
00394
00395 unsigned long MeshEvalDegeneratedFacets::CountEdgeTooSmall (float fMinEdgeLength) const
00396 {
00397 MeshFacetIterator clFIter(_rclMesh);
00398 unsigned long k = 0;
00399
00400 while (clFIter.EndReached() == false)
00401 {
00402 for ( int i = 0; i < 3; i++)
00403 {
00404 if (Base::Distance(clFIter->_aclPoints[i], clFIter->_aclPoints[(i+1)%3]) < fMinEdgeLength)
00405 k++;
00406 }
00407 ++clFIter;
00408 }
00409
00410 return k;
00411 }
00412
00413 std::vector<unsigned long> MeshEvalDegeneratedFacets::GetIndices() const
00414 {
00415 std::vector<unsigned long> aInds;
00416 MeshFacetIterator it(_rclMesh);
00417 for ( it.Init(); it.More(); it.Next() )
00418 {
00419 if ( it->IsDegenerated() )
00420 aInds.push_back(it.Position());
00421 }
00422
00423 return aInds;
00424 }
00425
00426 bool MeshFixDegeneratedFacets::Fixup()
00427 {
00428 MeshTopoAlgorithm cTopAlg(_rclMesh);
00429
00430 MeshFacetIterator it(_rclMesh);
00431 for ( it.Init(); it.More(); it.Next() )
00432 {
00433 if ( it->IsDegenerated() )
00434 {
00435 unsigned long uCt = _rclMesh.CountFacets();
00436 unsigned long uId = it.Position();
00437 cTopAlg.RemoveDegeneratedFacet(uId);
00438 if ( uCt != _rclMesh.CountFacets() )
00439 {
00440
00441 it.Set(uId-1);
00442 }
00443 }
00444 }
00445
00446 return true;
00447 }
00448
00449 unsigned long MeshFixDegeneratedFacets::RemoveEdgeTooSmall (float fMinEdgeLength, float fMinEdgeAngle)
00450 {
00451 unsigned long ulCtLastLoop, ulCtFacets = _rclMesh.CountFacets();
00452
00453 MeshFacetArray &rclFAry = _rclMesh._aclFacetArray;
00454 MeshPointArray &rclPAry = _rclMesh._aclPointArray;
00455 MeshFacetArray::_TConstIterator f_beg = rclFAry.begin();
00456
00457
00458 do {
00459 MeshRefPointToFacets clPt2Facets(_rclMesh);
00460
00461 rclFAry.ResetInvalid();
00462 rclPAry.ResetInvalid();
00463 rclPAry.ResetFlag(MeshPoint::VISIT);
00464
00465 std::set<std::pair<unsigned long, unsigned long> > aclPtDelList;
00466
00467 MeshFacetIterator clFIter(_rclMesh), clFN0(_rclMesh), clFN1(_rclMesh), clFN2(_rclMesh);
00468 for (clFIter.Init(); clFIter.More(); clFIter.Next()) {
00469 MeshGeomFacet clSFacet = *clFIter;
00470 Base::Vector3f clP0 = clSFacet._aclPoints[0];
00471 Base::Vector3f clP1 = clSFacet._aclPoints[1];
00472 Base::Vector3f clP2 = clSFacet._aclPoints[2];
00473 Base::Vector3f clE01 = clP1 - clP0;
00474 Base::Vector3f clE12 = clP2 - clP1;
00475 Base::Vector3f clE20 = clP2 - clP0;
00476 MeshFacet clFacet = clFIter.GetIndices();
00477 unsigned long ulP0 = clFacet._aulPoints[0];
00478 unsigned long ulP1 = clFacet._aulPoints[1];
00479 unsigned long ulP2 = clFacet._aulPoints[2];
00480
00481 if ((Base::Distance(clP0, clP1) < fMinEdgeLength) ||
00482 (clE20.GetAngle(-clE12) < fMinEdgeAngle)) {
00483
00484 aclPtDelList.insert(std::make_pair
00485 (std::min<unsigned long>(ulP1, ulP0), std::max<unsigned long>(ulP1, ulP0)));
00486 }
00487 else if ((Base::Distance(clP1, clP2) < fMinEdgeLength) ||
00488 (clE01.GetAngle(-clE20) < fMinEdgeAngle)) {
00489
00490 aclPtDelList.insert(std::make_pair
00491 (std::min<unsigned long>(ulP2, ulP1), std::max<unsigned long>(ulP2, ulP1)));
00492 }
00493 else if ((Base::Distance(clP2, clP0) < fMinEdgeLength) ||
00494 (clE12.GetAngle(-clE01) < fMinEdgeAngle)) {
00495
00496 aclPtDelList.insert(std::make_pair
00497 (std::min<unsigned long>(ulP0, ulP2), std::max<unsigned long>(ulP0, ulP2)));
00498 }
00499 }
00500
00501
00502 for (std::set<std::pair<unsigned long, unsigned long> >::iterator pI = aclPtDelList.begin();
00503 pI != aclPtDelList.end(); pI++) {
00504
00505 if ((rclPAry[pI->first].IsFlag(MeshPoint::VISIT) == true) ||
00506 (rclPAry[pI->second].IsFlag(MeshPoint::VISIT) == true))
00507 continue;
00508
00509 rclPAry[pI->first].SetFlag(MeshPoint::VISIT);
00510 rclPAry[pI->second].SetFlag(MeshPoint::VISIT);
00511 rclPAry[pI->second].SetInvalid();
00512
00513
00514
00515 const std::set<unsigned long>& faces = clPt2Facets[pI->second];
00516 for (std::set<unsigned long>::const_iterator pF = faces.begin(); pF != faces.end(); ++pF) {
00517 const MeshFacet &rclF = f_beg[*pF];
00518
00519 for (int i = 0; i < 3; i++) {
00520
00521
00522 }
00523
00524
00525 if ((rclF._aulPoints[0] == rclF._aulPoints[1]) ||
00526 (rclF._aulPoints[0] == rclF._aulPoints[2]) ||
00527 (rclF._aulPoints[1] == rclF._aulPoints[2])) {
00528 rclF.SetInvalid();
00529 }
00530 }
00531 }
00532
00533 ulCtLastLoop = _rclMesh.CountFacets();
00534 _rclMesh.RemoveInvalids();
00535 }
00536 while (ulCtLastLoop > _rclMesh.CountFacets());
00537
00538 _rclMesh.RebuildNeighbours();
00539
00540 return ulCtFacets - _rclMesh.CountFacets();
00541 }
00542
00543
00544
00545 bool MeshEvalDeformedFacets::Evaluate()
00546 {
00547 MeshFacetIterator it(_rclMesh);
00548 for ( it.Init(); it.More(); it.Next() )
00549 {
00550 if ( it->IsDeformed() )
00551 return false;
00552 }
00553
00554 return true;
00555 }
00556
00557 std::vector<unsigned long> MeshEvalDeformedFacets::GetIndices() const
00558 {
00559 std::vector<unsigned long> aInds;
00560 MeshFacetIterator it(_rclMesh);
00561 for ( it.Init(); it.More(); it.Next() )
00562 {
00563 if ( it->IsDeformed() )
00564 aInds.push_back(it.Position());
00565 }
00566
00567 return aInds;
00568 }
00569
00570 bool MeshFixDeformedFacets::Fixup()
00571 {
00572 Base::Vector3f u,v;
00573 MeshTopoAlgorithm cTopAlg(_rclMesh);
00574
00575 MeshFacetIterator it(_rclMesh);
00576 for ( it.Init(); it.More(); it.Next() )
00577 {
00578
00579 if ( !it->IsDegenerated() )
00580 {
00581
00582 float fCosAngles[3];
00583 bool done=false;
00584
00585
00586 for (int i=0; i<3; i++)
00587 {
00588 u = it->_aclPoints[(i+1)%3]-it->_aclPoints[i];
00589 v = it->_aclPoints[(i+2)%3]-it->_aclPoints[i];
00590 u.Normalize();
00591 v.Normalize();
00592
00593 float fCosAngle = u * v;
00594 fCosAngles[i] = fCosAngle;
00595
00596 if (fCosAngle < -0.5f) {
00597 const MeshFacet& face = it.GetReference();
00598 unsigned long uNeighbour = face._aulNeighbours[(i+1)%3];
00599 if (uNeighbour!=ULONG_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxAngle)) {
00600 cTopAlg.SwapEdge(it.Position(), uNeighbour);
00601 done = true;
00602 }
00603 break;
00604 }
00605 }
00606
00607
00608 if (done)
00609 continue;
00610
00611
00612 for (int j=0; j<3; j++)
00613 {
00614 float fCosAngle = fCosAngles[j];
00615 if (fCosAngle > 0.86f) {
00616 const MeshFacet& face = it.GetReference();
00617
00618 unsigned long uNeighbour = face._aulNeighbours[j];
00619 if (uNeighbour!=ULONG_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxAngle)) {
00620 cTopAlg.SwapEdge(it.Position(), uNeighbour);
00621 break;
00622 }
00623 uNeighbour = face._aulNeighbours[(j+2)%3];
00624 if (uNeighbour!=ULONG_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxAngle)) {
00625 cTopAlg.SwapEdge(it.Position(), uNeighbour);
00626 break;
00627 }
00628 }
00629 }
00630 }
00631 }
00632
00633 return true;
00634 }
00635
00636
00637
00638 bool MeshEvalFoldsOnSurface::Evaluate()
00639 {
00640 this->indices.clear();
00641 MeshRefPointToFacets clPt2Facets(_rclMesh);
00642 const MeshPointArray& rPntAry = _rclMesh.GetPoints();
00643 MeshFacetArray::_TConstIterator f_beg = _rclMesh.GetFacets().begin();
00644
00645 MeshGeomFacet rTriangle;
00646 Base::Vector3f tmp;
00647 unsigned long ctPoints = _rclMesh.CountPoints();
00648 for (unsigned long index=0; index < ctPoints; index++) {
00649 std::vector<unsigned long> point;
00650 point.push_back(index);
00651
00652
00653 std::set<unsigned long> nb = clPt2Facets.NeighbourPoints(point,1);
00654 const std::set<unsigned long>& faces = clPt2Facets[index];
00655
00656 for (std::set<unsigned long>::iterator pt = nb.begin(); pt != nb.end(); ++pt) {
00657 const MeshPoint& mp = rPntAry[*pt];
00658 for (std::set<unsigned long>::const_iterator
00659 ft = faces.begin(); ft != faces.end(); ++ft) {
00660
00661 if (f_beg[*ft]._aulPoints[0] == *pt)
00662 continue;
00663 if (f_beg[*ft]._aulPoints[1] == *pt)
00664 continue;
00665 if (f_beg[*ft]._aulPoints[2] == *pt)
00666 continue;
00667
00668 rTriangle = _rclMesh.GetFacet(f_beg[*ft]);
00669 if (rTriangle.IntersectWithLine(mp,rTriangle.GetNormal(),tmp)) {
00670 const std::set<unsigned long>& f = clPt2Facets[*pt];
00671 this->indices.insert(this->indices.end(), f.begin(), f.end());
00672 break;
00673 }
00674 }
00675 }
00676 }
00677
00678
00679 std::sort(this->indices.begin(), this->indices.end());
00680 this->indices.erase(std::unique(this->indices.begin(),
00681 this->indices.end()), this->indices.end());
00682
00683 return this->indices.empty();
00684 }
00685
00686 std::vector<unsigned long> MeshEvalFoldsOnSurface::GetIndices() const
00687 {
00688 return this->indices;
00689 }
00690
00691 bool MeshFixFoldsOnSurface::Fixup()
00692 {
00693 MeshEvalFoldsOnSurface eval(_rclMesh);
00694 if (!eval.Evaluate()) {
00695 std::vector<unsigned long> inds = eval.GetIndices();
00696 _rclMesh.DeleteFacets(inds);
00697 }
00698
00699 return true;
00700 }
00701
00702
00703
00704 bool MeshEvalFoldsOnBoundary::Evaluate()
00705 {
00706
00707
00708 this->indices.clear();
00709 const MeshFacetArray& rFacAry = _rclMesh.GetFacets();
00710 for (MeshFacetArray::_TConstIterator it = rFacAry.begin(); it != rFacAry.end(); ++it) {
00711 if (it->CountOpenEdges() == 2) {
00712 for (int i=0; i<3; i++) {
00713 if (it->_aulNeighbours[i] != ULONG_MAX) {
00714 MeshGeomFacet f1 = _rclMesh.GetFacet(*it);
00715 MeshGeomFacet f2 = _rclMesh.GetFacet(it->_aulNeighbours[i]);
00716 float cos_angle = f1.GetNormal() * f2.GetNormal();
00717 if (cos_angle <= 0.5f)
00718 indices.push_back(it-rFacAry.begin());
00719 }
00720 }
00721 }
00722 }
00723
00724 return this->indices.empty();
00725 }
00726
00727 std::vector<unsigned long> MeshEvalFoldsOnBoundary::GetIndices() const
00728 {
00729 return this->indices;
00730 }
00731
00732 bool MeshFixFoldsOnBoundary::Fixup()
00733 {
00734 MeshEvalFoldsOnBoundary eval(_rclMesh);
00735 if (!eval.Evaluate()) {
00736 std::vector<unsigned long> inds = eval.GetIndices();
00737 _rclMesh.DeleteFacets(inds);
00738 }
00739
00740 return true;
00741 }
00742
00743
00744
00745 bool MeshEvalFoldOversOnSurface::Evaluate()
00746 {
00747 this->indices.clear();
00748 const MeshCore::MeshFacetArray& facets = _rclMesh.GetFacets();
00749 MeshCore::MeshFacetArray::_TConstIterator f_it,
00750 f_beg = facets.begin(), f_end = facets.end();
00751
00752 Base::Vector3f n1, n2;
00753 for (f_it = facets.begin(); f_it != f_end; ++f_it) {
00754 for (int i=0; i<3; i++) {
00755 unsigned long index1 = f_it->_aulNeighbours[i];
00756 unsigned long index2 = f_it->_aulNeighbours[(i+1)%3];
00757 if (index1 != ULONG_MAX && index2 != ULONG_MAX) {
00758
00759
00760 if (f_it->HasSameOrientation(f_beg[index1]) &&
00761 f_it->HasSameOrientation(f_beg[index2])) {
00762 n1 = _rclMesh.GetFacet(index1).GetNormal();
00763 n2 = _rclMesh.GetFacet(index2).GetNormal();
00764 if (n1 * n2 < -0.5f) {
00765 this->indices.push_back(f_it-f_beg);
00766 break;
00767 }
00768 }
00769 }
00770 }
00771 }
00772
00773 return this->indices.empty();
00774 }
00775
00776
00777
00778 bool MeshEvalBorderFacet::Evaluate()
00779 {
00780 const MeshCore::MeshFacetArray& facets = _rclMesh.GetFacets();
00781 MeshCore::MeshFacetArray::_TConstIterator f_it,
00782 f_beg = facets.begin(), f_end = facets.end();
00783 MeshCore::MeshRefPointToPoints vv_it(_rclMesh);
00784 MeshCore::MeshRefPointToFacets vf_it(_rclMesh);
00785
00786 for (f_it = facets.begin(); f_it != f_end; ++f_it) {
00787 bool ok = true;
00788 for (int i=0; i<3; i++) {
00789 unsigned long index = f_it->_aulPoints[i];
00790 if (vv_it[index].size() == vf_it[index].size()) {
00791 ok = false;
00792 break;
00793 }
00794 }
00795
00796 if (ok)
00797 _facets.push_back(f_it-f_beg);
00798 }
00799
00800 return _facets.empty();
00801 }
00802
00803
00804
00805 bool MeshEvalRangeFacet::Evaluate()
00806 {
00807 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00808 unsigned long ulCtFacets = rFaces.size();
00809
00810 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
00811 for ( int i = 0; i < 3; i++ ) {
00812 if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
00813 return false;
00814 }
00815 }
00816 }
00817
00818 return true;
00819 }
00820
00821 std::vector<unsigned long> MeshEvalRangeFacet::GetIndices() const
00822 {
00823 std::vector<unsigned long> aInds;
00824 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00825 unsigned long ulCtFacets = rFaces.size();
00826
00827 unsigned long ind=0;
00828 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ )
00829 {
00830 for ( int i = 0; i < 3; i++ ) {
00831 if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
00832 aInds.push_back(ind);
00833 break;
00834 }
00835 }
00836 }
00837
00838 return aInds;
00839 }
00840
00841 bool MeshFixRangeFacet::Fixup()
00842 {
00843 return false;
00844 }
00845
00846
00847
00848 bool MeshEvalRangePoint::Evaluate()
00849 {
00850 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00851 unsigned long ulCtPoints = _rclMesh.CountPoints();
00852
00853 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
00854 if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
00855 return false;
00856 }
00857
00858 return true;
00859 }
00860
00861 std::vector<unsigned long> MeshEvalRangePoint::GetIndices() const
00862 {
00863 std::vector<unsigned long> aInds;
00864 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00865 unsigned long ulCtPoints = _rclMesh.CountPoints();
00866
00867 unsigned long ind=0;
00868 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ )
00869 {
00870 if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
00871 aInds.push_back(ind);
00872 }
00873
00874 return aInds;
00875 }
00876
00877 bool MeshFixRangePoint::Fixup()
00878 {
00879 return false;
00880 }
00881
00882
00883
00884 bool MeshEvalCorruptedFacets::Evaluate()
00885 {
00886 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00887
00888 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
00889
00890 if ((it->_aulPoints[0] == it->_aulPoints[1]) ||
00891 (it->_aulPoints[1] == it->_aulPoints[2]) ||
00892 (it->_aulPoints[2] == it->_aulPoints[0]))
00893 return false;
00894 }
00895
00896 return true;
00897 }
00898
00899 std::vector<unsigned long> MeshEvalCorruptedFacets::GetIndices() const
00900 {
00901 std::vector<unsigned long> aInds;
00902 const MeshFacetArray& rFaces = _rclMesh.GetFacets();
00903 unsigned long ind=0;
00904
00905 for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ ) {
00906 if ((it->_aulPoints[0] == it->_aulPoints[1]) ||
00907 (it->_aulPoints[1] == it->_aulPoints[2]) ||
00908 (it->_aulPoints[2] == it->_aulPoints[0]))
00909 aInds.push_back(ind);
00910 }
00911
00912 return aInds;
00913 }
00914
00915 bool MeshFixCorruptedFacets::Fixup()
00916 {
00917 MeshTopoAlgorithm cTopAlg(_rclMesh);
00918
00919 MeshFacetIterator it(_rclMesh);
00920 for ( it.Init(); it.More(); it.Next() )
00921 {
00922 if ( it->Area() <= FLOAT_EPS )
00923 {
00924 unsigned long uId = it.Position();
00925 cTopAlg.RemoveCorruptedFacet(uId);
00926
00927 it.Set(uId-1);
00928 }
00929 }
00930
00931 return true;
00932 }
00933