23
#include "PreCompiled.h"
29
#include <Base/Console.h>
30
#include <Base/Sequencer.h>
33
#include "Approximation.h"
37
#include "Triangulation.h"
40
using namespace MeshCore;
41
using Base::BoundBox2d;
42
using Base::BoundBox3f;
46
bool MeshAlgorithm::IsVertexVisible(const Base::Vector3f& rcVertex,
47
const Base::Vector3f& rcView,
48
const MeshFacetGrid& rclGrid) const
50
const float fMaxDistance = 0.001F;
51
Base::Vector3f cDirection = rcVertex - rcView;
52
float fDistance = cDirection.Length();
53
Base::Vector3f cIntsct;
57
if (NearestFacetOnRay(rcView, cDirection, rclGrid, cIntsct, uInd)) {
59
float fLen = Base::Distance(rcView, cIntsct);
60
if (fLen < fDistance) {
62
if (Base::Distance(rcVertex, cIntsct) > fMaxDistance) {
72
bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt,
73
const Base::Vector3f& rclDir,
74
Base::Vector3f& rclRes,
75
FacetIndex& rulFacet) const
77
return NearestFacetOnRay(rclPt, rclDir, Mathf::PI, rclRes, rulFacet);
80
bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt,
81
const Base::Vector3f& rclDir,
83
Base::Vector3f& rclRes,
84
FacetIndex& rulFacet) const
86
Base::Vector3f clProj;
92
MeshFacetIterator clFIter(_rclMesh);
93
for (clFIter.Init(); clFIter.More(); clFIter.Next()) {
94
if (clFIter->Foraminate(rclPt, rclDir, clRes, fMaxAngle)) {
99
ulInd = clFIter.Position();
103
if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) {
105
ulInd = clFIter.Position();
119
bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt,
120
const Base::Vector3f& rclDir,
121
const MeshFacetGrid& rclGrid,
122
Base::Vector3f& rclRes,
123
FacetIndex& rulFacet) const
125
std::vector<FacetIndex> aulFacets;
126
MeshGridIterator clGridIter(rclGrid);
128
if (clGridIter.InitOnRay(rclPt, rclDir, aulFacets)) {
129
if (!RayNearestField(rclPt, rclDir, aulFacets, rclRes, rulFacet)) {
131
while (clGridIter.NextOnRay(aulFacets)) {
132
if (RayNearestField(rclPt, rclDir, aulFacets, rclRes, rulFacet)) {
145
bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt,
146
const Base::Vector3f& rclDir,
147
float fMaxSearchArea,
148
const MeshFacetGrid& rclGrid,
149
Base::Vector3f& rclRes,
150
FacetIndex& rulFacet) const
152
const float fMaxAngle = 1.75F;
153
std::vector<FacetIndex> aulFacets;
154
MeshGridIterator clGridIter(rclGrid);
156
if (clGridIter.InitOnRay(rclPt, rclDir, fMaxSearchArea, aulFacets)) {
157
if (!RayNearestField(rclPt, rclDir, aulFacets, rclRes, rulFacet, fMaxAngle)) {
159
while (clGridIter.NextOnRay(aulFacets)) {
160
if (RayNearestField(rclPt, rclDir, aulFacets, rclRes, rulFacet, fMaxAngle)) {
173
bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt,
174
const Base::Vector3f& rclDir,
175
const std::vector<FacetIndex>& raulFacets,
176
Base::Vector3f& rclRes,
177
FacetIndex& rulFacet) const
179
Base::Vector3f clProj;
180
Base::Vector3f clRes;
182
FacetIndex ulInd = 0;
184
for (FacetIndex index : raulFacets) {
185
MeshGeomFacet rclSFacet = _rclMesh.GetFacet(index);
186
if (rclSFacet.Foraminate(rclPt, rclDir, clRes)) {
193
if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) {
209
bool MeshAlgorithm::RayNearestField(const Base::Vector3f& rclPt,
210
const Base::Vector3f& rclDir,
211
const std::vector<FacetIndex>& raulFacets,
212
Base::Vector3f& rclRes,
213
FacetIndex& rulFacet,
216
Base::Vector3f clProj, clRes;
218
FacetIndex ulInd = 0;
220
for (FacetIndex index : raulFacets) {
221
if (_rclMesh.GetFacet(index).Foraminate(rclPt, rclDir, clRes )) {
228
if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) {
244
bool MeshAlgorithm::FirstFacetToVertex(const Base::Vector3f& rPt,
246
const MeshFacetGrid& rGrid,
247
FacetIndex& uIndex) const
249
const float fEps = 0.001f;
252
std::vector<FacetIndex> facets;
255
rGrid.GetElements(rPt, facets);
258
for (FacetIndex facet : facets) {
259
MeshGeomFacet cFacet = this->_rclMesh.GetFacet(facet);
260
if (cFacet.IsPointOfFace(rPt, fMaxDistance)) {
269
unsigned short uSide {};
270
cFacet.ProjectPointToPlane(rPt, res);
271
cFacet.NearestEdgeToPoint(res, fDist, uSide);
283
float MeshAlgorithm::GetAverageEdgeLength() const
286
MeshFacetIterator cF(_rclMesh);
287
for (cF.Init(); cF.More(); cF.Next()) {
288
for (int i = 0; i < 3; i++) {
289
fLen += Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3]);
293
fLen = fLen / (3.0f * _rclMesh.CountFacets());
297
float MeshAlgorithm::GetMinimumEdgeLength() const
299
float fLen = FLOAT_MAX;
300
MeshFacetIterator cF(_rclMesh);
301
for (cF.Init(); cF.More(); cF.Next()) {
302
for (int i = 0; i < 3; i++) {
303
fLen = std::min(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3]));
310
float MeshAlgorithm::GetMaximumEdgeLength() const
313
MeshFacetIterator cF(_rclMesh);
314
for (cF.Init(); cF.More(); cF.Next()) {
315
for (int i = 0; i < 3; i++) {
316
fLen = std::max(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3]));
323
Base::Vector3f MeshAlgorithm::GetGravityPoint() const
325
Base::Vector3f center;
326
MeshPointIterator cP(_rclMesh);
327
for (cP.Init(); cP.More(); cP.Next()) {
331
return center / static_cast<float>(_rclMesh.CountPoints());
334
void MeshAlgorithm::GetMeshBorders(std::list<std::vector<Base::Vector3f>>& rclBorders) const
336
std::vector<FacetIndex> aulAllFacets(_rclMesh.CountFacets());
338
for (FacetIndex& index : aulAllFacets) {
342
GetFacetBorders(aulAllFacets, rclBorders);
345
void MeshAlgorithm::GetMeshBorders(std::list<std::vector<PointIndex>>& rclBorders) const
347
std::vector<FacetIndex> aulAllFacets(_rclMesh.CountFacets());
349
for (FacetIndex& index : aulAllFacets) {
353
GetFacetBorders(aulAllFacets, rclBorders, true);
356
void MeshAlgorithm::GetFacetBorders(const std::vector<FacetIndex>& raulInd,
357
std::list<std::vector<Base::Vector3f>>& rclBorders) const
359
const MeshPointArray& rclPAry = _rclMesh._aclPointArray;
360
std::list<std::vector<PointIndex>> aulBorders;
362
GetFacetBorders(raulInd, aulBorders, true);
363
for (const auto& border : aulBorders) {
364
std::vector<Base::Vector3f> boundary;
365
boundary.reserve(border.size());
367
for (PointIndex jt : border) {
368
boundary.push_back(rclPAry[jt]);
371
rclBorders.push_back(boundary);
375
void MeshAlgorithm::GetFacetBorders(const std::vector<FacetIndex>& raulInd,
376
std::list<std::vector<PointIndex>>& rclBorders,
377
bool ignoreOrientation) const
379
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
382
ResetFacetFlag(MeshFacet::VISIT);
383
for (FacetIndex it : raulInd) {
384
rclFAry[it].SetFlag(MeshFacet::VISIT);
388
std::list<std::pair<PointIndex, PointIndex>> aclEdges;
389
for (FacetIndex it : raulInd) {
390
const MeshFacet& rclFacet = rclFAry[it];
391
for (unsigned short i = 0; i < 3; i++) {
392
FacetIndex ulNB = rclFacet._aulNeighbours[i];
393
if (ulNB != FACET_INDEX_MAX) {
394
if (rclFAry[ulNB].IsFlag(MeshFacet::VISIT)) {
399
aclEdges.push_back(rclFacet.GetEdge(i));
403
if (aclEdges.empty()) {
408
PointIndex ulFirst {}, ulLast {};
409
std::list<PointIndex> clBorder;
410
ulFirst = aclEdges.begin()->first;
411
ulLast = aclEdges.begin()->second;
413
aclEdges.erase(aclEdges.begin());
414
clBorder.push_back(ulFirst);
415
clBorder.push_back(ulLast);
417
while (!aclEdges.empty()) {
419
std::list<std::pair<PointIndex, PointIndex>>::iterator pEI;
420
for (pEI = aclEdges.begin(); pEI != aclEdges.end(); ++pEI) {
421
if (pEI->first == ulLast) {
422
ulLast = pEI->second;
423
clBorder.push_back(ulLast);
425
pEI = aclEdges.begin();
428
else if (pEI->second == ulFirst) {
429
ulFirst = pEI->first;
430
clBorder.push_front(ulFirst);
432
pEI = aclEdges.begin();
438
else if (pEI->second == ulLast && ignoreOrientation) {
440
clBorder.push_back(ulLast);
442
pEI = aclEdges.begin();
445
else if (pEI->first == ulFirst && ignoreOrientation) {
446
ulFirst = pEI->second;
447
clBorder.push_front(ulFirst);
449
pEI = aclEdges.begin();
456
if ((pEI == aclEdges.end()) || aclEdges.empty() || (ulLast == ulFirst)) {
458
rclBorders.emplace_back(clBorder.begin(), clBorder.end());
461
if (!aclEdges.empty()) {
463
ulFirst = aclEdges.begin()->first;
464
ulLast = aclEdges.begin()->second;
465
aclEdges.erase(aclEdges.begin());
466
clBorder.push_back(ulFirst);
467
clBorder.push_back(ulLast);
473
void MeshAlgorithm::GetFacetBorder(FacetIndex uFacet, std::list<PointIndex>& rBorder) const
475
const MeshFacetArray& rFAry = _rclMesh._aclFacetArray;
476
std::list<std::pair<PointIndex, PointIndex>> openEdges;
477
if (uFacet >= rFAry.size()) {
481
MeshFacetArray::_TConstIterator face = rFAry.begin() + uFacet;
482
for (unsigned short i = 0; i < 3; i++) {
483
if (face->_aulNeighbours[i] == FACET_INDEX_MAX) {
484
openEdges.push_back(face->GetEdge(i));
488
if (openEdges.empty()) {
492
for (MeshFacetArray::_TConstIterator it = rFAry.begin(); it != rFAry.end(); ++it) {
496
for (unsigned short i = 0; i < 3; i++) {
497
if (it->_aulNeighbours[i] == FACET_INDEX_MAX) {
498
openEdges.push_back(it->GetEdge(i));
503
SplitBoundaryFromOpenEdges(openEdges, rBorder);
506
void MeshAlgorithm::GetFacetsBorders(const std::vector<FacetIndex>& uFacets,
507
std::list<std::vector<PointIndex>>& rBorders) const
509
ResetFacetFlag(MeshFacet::TMP0);
510
SetFacetsFlag(uFacets, MeshFacet::TMP0);
511
ResetPointFlag(MeshPoint::TMP0);
513
const MeshFacetArray& rFAry = _rclMesh._aclFacetArray;
514
const MeshPointArray& rPAry = _rclMesh._aclPointArray;
515
std::list<std::pair<PointIndex, PointIndex>> openEdges;
518
for (auto it : uFacets) {
519
const MeshFacet& face = rFAry[it];
520
for (int i = 0; i < 3; i++) {
521
if (face._aulNeighbours[i] == FACET_INDEX_MAX) {
522
std::pair<PointIndex, PointIndex> openEdge = face.GetEdge(i);
523
openEdges.push_back(openEdge);
525
rPAry[openEdge.first].SetFlag(MeshPoint::TMP0);
526
rPAry[openEdge.second].SetFlag(MeshPoint::TMP0);
531
if (openEdges.empty()) {
535
for (const auto& it : rFAry) {
536
if (it.IsFlag(MeshFacet::TMP0)) {
539
for (int i = 0; i < 3; i++) {
540
if (it._aulNeighbours[i] == FACET_INDEX_MAX) {
541
openEdges.push_back(it.GetEdge(i));
547
while (!openEdges.empty()) {
548
PointIndex first = openEdges.begin()->first;
549
PointIndex second = openEdges.begin()->second;
550
if (!rPAry[first].IsFlag(MeshPoint::TMP0)) {
553
if (!rPAry[second].IsFlag(MeshPoint::TMP0)) {
557
std::list<PointIndex> boundary;
558
SplitBoundaryFromOpenEdges(openEdges, boundary);
559
rBorders.emplace_back(boundary.begin(), boundary.end());
563
void MeshAlgorithm::SplitBoundaryFromOpenEdges(
564
std::list<std::pair<PointIndex, PointIndex>>& openEdges,
565
std::list<PointIndex>& boundary) const
568
if (openEdges.empty()) {
572
PointIndex ulFirst = openEdges.begin()->first;
573
PointIndex ulLast = openEdges.begin()->second;
575
openEdges.erase(openEdges.begin());
576
boundary.push_back(ulFirst);
577
boundary.push_back(ulLast);
579
while (ulLast != ulFirst) {
581
std::list<std::pair<PointIndex, PointIndex>>::iterator pEI;
582
for (pEI = openEdges.begin(); pEI != openEdges.end(); ++pEI) {
583
if (pEI->first == ulLast) {
584
ulLast = pEI->second;
585
boundary.push_back(ulLast);
586
openEdges.erase(pEI);
587
pEI = openEdges.begin();
590
else if (pEI->second == ulFirst) {
591
ulFirst = pEI->first;
592
boundary.push_front(ulFirst);
593
openEdges.erase(pEI);
594
pEI = openEdges.begin();
600
if (pEI == openEdges.end()) {
606
void MeshAlgorithm::SplitBoundaryLoops(std::list<std::vector<PointIndex>>& aBorders)
609
std::map<PointIndex, int> openPointDegree;
610
for (const auto& jt : _rclMesh._aclFacetArray) {
611
for (int i = 0; i < 3; i++) {
612
if (jt._aulNeighbours[i] == FACET_INDEX_MAX) {
613
openPointDegree[jt._aulPoints[i]]++;
614
openPointDegree[jt._aulPoints[(i + 1) % 3]]++;
620
std::list<std::vector<PointIndex>> aSplitBorders;
621
for (const auto& aBorder : aBorders) {
623
for (auto jt : aBorder) {
625
if (openPointDegree[jt] > 2) {
632
aSplitBorders.push_back(aBorder);
635
SplitBoundaryLoops(aBorder, aSplitBorders);
639
aBorders = aSplitBorders;
642
void MeshAlgorithm::SplitBoundaryLoops(const std::vector<PointIndex>& rBound,
643
std::list<std::vector<PointIndex>>& aBorders)
645
std::map<PointIndex, int> aPtDegree;
646
std::vector<PointIndex> cBound;
647
for (PointIndex it : rBound) {
648
int deg = (aPtDegree[it]++);
650
for (std::vector<PointIndex>::iterator jt = cBound.begin(); jt != cBound.end(); ++jt) {
652
std::vector<PointIndex> cBoundLoop;
653
cBoundLoop.insert(cBoundLoop.end(), jt, cBound.end());
654
cBoundLoop.push_back(it);
655
cBound.erase(jt, cBound.end());
656
aBorders.push_back(cBoundLoop);
663
cBound.push_back(it);
667
bool MeshAlgorithm::FillupHole(const std::vector<PointIndex>& boundary,
668
AbstractPolygonTriangulator& cTria,
669
MeshFacetArray& rFaces,
670
MeshPointArray& rPoints,
672
const MeshRefPointToFacets* pP2FStructure) const
674
if (boundary.front() == boundary.back()) {
676
if (boundary.size() < 4) {
680
else if (boundary.size() < 3) {
685
MeshGeomFacet rTriangle;
687
PointIndex refPoint0 = *(boundary.begin());
688
PointIndex refPoint1 = *(boundary.begin() + 1);
690
const std::set<FacetIndex>& ring1 = (*pP2FStructure)[refPoint0];
691
const std::set<FacetIndex>& ring2 = (*pP2FStructure)[refPoint1];
692
std::vector<FacetIndex> f_int;
693
std::set_intersection(ring1.begin(),
697
std::back_insert_iterator<std::vector<FacetIndex>>(f_int));
698
if (f_int.size() != 1) {
702
rFace = _rclMesh._aclFacetArray[f_int.front()];
703
rTriangle = _rclMesh.GetFacet(rFace);
707
for (MeshFacetArray::_TConstIterator it = _rclMesh._aclFacetArray.begin();
708
it != _rclMesh._aclFacetArray.end();
710
for (int i = 0; i < 3; i++) {
711
if (((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i + 1) % 3] == refPoint1))
712
|| ((it->_aulPoints[i] == refPoint1)
713
&& (it->_aulPoints[(i + 1) % 3] == refPoint0))) {
715
rTriangle = _rclMesh.GetFacet(*it);
728
std::vector<Base::Vector3f> polygon;
729
for (PointIndex jt : boundary) {
730
polygon.push_back(_rclMesh._aclPointArray[jt]);
731
rPoints.push_back(_rclMesh._aclPointArray[jt]);
735
std::vector<PointIndex> bounds = boundary;
736
if (boundary.front() == boundary.back()) {
746
cTria.SetPolygon(polygon);
747
cTria.SetIndices(bounds);
749
std::vector<Base::Vector3f> surf_pts = cTria.GetPolygon();
750
if (pP2FStructure && level > 0) {
751
std::set<PointIndex> index = pP2FStructure->NeighbourPoints(boundary, level);
752
for (PointIndex it : index) {
753
Base::Vector3f pt(_rclMesh._aclPointArray[it]);
754
surf_pts.push_back(pt);
758
if (cTria.TriangulatePolygon()) {
761
cTria.PostProcessing(surf_pts);
763
rFaces.insert(rFaces.end(), cTria.GetFacets().begin(), cTria.GetFacets().end());
764
std::vector<Base::Vector3f> newVertices = cTria.AddedPoints();
765
for (const auto& vertex : newVertices) {
766
rPoints.push_back(vertex);
772
std::vector<MeshFacet> faces = cTria.GetFacets();
776
if (faces.size() == 1) {
777
MeshFacet first = faces.front();
778
if (cTria.NeedsReindexing()) {
779
first._aulPoints[0] = boundary[first._aulPoints[0]];
780
first._aulPoints[1] = boundary[first._aulPoints[1]];
781
first._aulPoints[2] = boundary[first._aulPoints[2]];
783
if (first.IsEqual(rFace)) {
793
unsigned short ref_side = rFace.Side(refPoint0, refPoint1);
794
unsigned short tri_side = USHRT_MAX;
795
if (cTria.NeedsReindexing()) {
800
if (ref_side < USHRT_MAX) {
801
for (const auto& face : faces) {
802
tri_side = face.Side(refPoint0, refPoint1);
803
if (tri_side < USHRT_MAX) {
811
if (ref_side == USHRT_MAX || tri_side == USHRT_MAX) {
813
"MeshAlgorithm::FillupHole: Expected open edge for facet <%d, %d, %d>\n",
816
rFace._aulPoints[2]);
824
MeshGeomFacet triangle;
825
triangle = cTria.GetTriangle(rPoints, facet);
827
TriangulationVerifier* verifier = cTria.GetVerifier();
835
Base::Vector3f planeNormal = rTriangle.GetNormal()
836
% (rTriangle._aclPoints[(ref_side + 1) % 3] - rTriangle._aclPoints[ref_side]);
837
Base::Vector3f planeBase = rTriangle._aclPoints[ref_side % 3];
838
Base::Vector3f ref_point = rTriangle._aclPoints[(ref_side + 2) % 3];
839
Base::Vector3f tri_point = triangle._aclPoints[(tri_side + 2) % 3];
841
if (!verifier->Accept(planeNormal, planeBase, ref_point, tri_point)) {
849
if (verifier->MustFlip(triangle.GetNormal(), rTriangle.GetNormal())) {
850
for (auto& rFace : rFaces) {
862
void MeshAlgorithm::SetFacetsProperty(const std::vector<FacetIndex>& raulInds,
863
const std::vector<unsigned long>& raulProps) const
865
if (raulInds.size() != raulProps.size()) {
869
std::vector<unsigned long>::const_iterator iP = raulProps.begin();
870
for (std::vector<FacetIndex>::const_iterator i = raulInds.begin(); i != raulInds.end();
872
_rclMesh._aclFacetArray[*i].SetProperty(*iP);
876
void MeshAlgorithm::SetFacetsFlag(const std::vector<FacetIndex>& raulInds,
877
MeshFacet::TFlagType tF) const
879
for (FacetIndex it : raulInds) {
880
_rclMesh._aclFacetArray[it].SetFlag(tF);
884
void MeshAlgorithm::SetPointsFlag(const std::vector<FacetIndex>& raulInds,
885
MeshPoint::TFlagType tF) const
887
for (PointIndex it : raulInds) {
888
_rclMesh._aclPointArray[it].SetFlag(tF);
892
void MeshAlgorithm::GetFacetsFlag(std::vector<FacetIndex>& raulInds, MeshFacet::TFlagType tF) const
894
raulInds.reserve(raulInds.size() + CountFacetFlag(tF));
895
MeshFacetArray::_TConstIterator beg = _rclMesh._aclFacetArray.begin();
896
MeshFacetArray::_TConstIterator end = _rclMesh._aclFacetArray.end();
897
for (MeshFacetArray::_TConstIterator it = beg; it != end; ++it) {
898
if (it->IsFlag(tF)) {
899
raulInds.push_back(it - beg);
904
void MeshAlgorithm::GetPointsFlag(std::vector<PointIndex>& raulInds, MeshPoint::TFlagType tF) const
906
raulInds.reserve(raulInds.size() + CountPointFlag(tF));
907
MeshPointArray::_TConstIterator beg = _rclMesh._aclPointArray.begin();
908
MeshPointArray::_TConstIterator end = _rclMesh._aclPointArray.end();
909
for (MeshPointArray::_TConstIterator it = beg; it != end; ++it) {
910
if (it->IsFlag(tF)) {
911
raulInds.push_back(it - beg);
916
void MeshAlgorithm::ResetFacetsFlag(const std::vector<FacetIndex>& raulInds,
917
MeshFacet::TFlagType tF) const
919
for (FacetIndex it : raulInds) {
920
_rclMesh._aclFacetArray[it].ResetFlag(tF);
924
void MeshAlgorithm::ResetPointsFlag(const std::vector<FacetIndex>& raulInds,
925
MeshPoint::TFlagType tF) const
927
for (PointIndex it : raulInds) {
928
_rclMesh._aclPointArray[it].ResetFlag(tF);
932
void MeshAlgorithm::SetFacetFlag(MeshFacet::TFlagType tF) const
934
_rclMesh._aclFacetArray.SetFlag(tF);
937
void MeshAlgorithm::SetPointFlag(MeshPoint::TFlagType tF) const
939
_rclMesh._aclPointArray.SetFlag(tF);
942
void MeshAlgorithm::ResetFacetFlag(MeshFacet::TFlagType tF) const
944
_rclMesh._aclFacetArray.ResetFlag(tF);
947
void MeshAlgorithm::ResetPointFlag(MeshPoint::TFlagType tF) const
949
_rclMesh._aclPointArray.ResetFlag(tF);
952
unsigned long MeshAlgorithm::CountFacetFlag(MeshFacet::TFlagType tF) const
954
MeshIsFlag<MeshFacet> flag;
955
return std::count_if(_rclMesh._aclFacetArray.begin(),
956
_rclMesh._aclFacetArray.end(),
957
[flag, tF](const MeshFacet& f) {
962
unsigned long MeshAlgorithm::CountPointFlag(MeshPoint::TFlagType tF) const
964
MeshIsFlag<MeshPoint> flag;
965
return std::count_if(_rclMesh._aclPointArray.begin(),
966
_rclMesh._aclPointArray.end(),
967
[flag, tF](const MeshPoint& f) {
972
void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh,
973
const Base::Vector3f& rcDir,
974
std::vector<FacetIndex>& raclCutted) const
976
MeshFacetIterator cFIt(_rclMesh);
977
MeshFacetIterator cTIt(rToolMesh);
979
BoundBox3f cBB = rToolMesh.GetBoundBox();
981
Base::SequencerLauncher seq("Check facets...", _rclMesh.CountFacets());
985
for (cFIt.Init(); cFIt.More(); cFIt.Next()) {
987
for (const auto& pnt : cFIt->_aclPoints) {
989
if (cBB.IsInBox(pnt)) {
993
for (cTIt.Init(); cTIt.More(); cTIt.Next()) {
994
if (cTIt->IsPointOfFace(pnt, MeshPoint::epsilon())) {
998
else if (cTIt->Foraminate(pnt, rcDir, tmp)) {
1001
if ((tmp - pnt) * rcDir > 0) {
1009
raclCutted.push_back(cFIt.Position());
1019
void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh,
1020
const Base::Vector3f& rcDir,
1021
const MeshFacetGrid& rGrid,
1022
std::vector<FacetIndex>& raclCutted) const
1025
MeshGridIterator clGridIter(rGrid);
1026
BoundBox3f cBB = rToolMesh.GetBoundBox();
1029
MeshFacetIterator cFIt(_rclMesh);
1030
MeshFacetIterator cTIt(rToolMesh);
1031
MeshAlgorithm cToolAlg(rToolMesh);
1040
std::vector<FacetIndex> aulInds;
1041
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
1042
int ret = cToolAlg.Surround(clGridIter.GetBoundBox(), rcDir);
1047
clGridIter.GetElements(raclCutted);
1050
else if (ret == 0) {
1052
clGridIter.GetElements(aulInds);
1056
else if (ret == -1) {
1058
clGridIter.GetElements(aulInds);
1063
std::sort(aulInds.begin(), aulInds.end());
1064
aulInds.erase(std::unique(aulInds.begin(), aulInds.end()), aulInds.end());
1065
std::sort(raclCutted.begin(), raclCutted.end());
1066
raclCutted.erase(std::unique(raclCutted.begin(), raclCutted.end()), raclCutted.end());
1068
Base::SequencerLauncher seq("Check facets...", aulInds.size());
1071
for (FacetIndex it : aulInds) {
1075
for (auto point : cFIt->_aclPoints) {
1077
if (cBB.IsInBox(point)) {
1081
for (cTIt.Init(); cTIt.More(); cTIt.Next()) {
1082
if (cTIt->IsPointOfFace(point, MeshPoint::epsilon())) {
1086
else if (cTIt->Foraminate(point, rcDir, tmp)) {
1089
if ((tmp - point) * rcDir > 0) {
1097
raclCutted.push_back(cFIt.Position());
1107
std::sort(raclCutted.begin(), raclCutted.end());
1108
raclCutted.erase(std::unique(raclCutted.begin(), raclCutted.end()), raclCutted.end());
1111
int MeshAlgorithm::Surround(const Base::BoundBox3f& rBox, const Base::Vector3f& rcDir)
1113
Base::Vector3f pt1, pt2, tmp;
1114
const BoundBox3f& cBB = _rclMesh.GetBoundBox();
1119
Base::Vector3f cCorner[8] = {Base::Vector3f(rBox.MinX, rBox.MinY, rBox.MinZ),
1120
Base::Vector3f(rBox.MaxX, rBox.MinY, rBox.MinZ),
1121
Base::Vector3f(rBox.MaxX, rBox.MaxY, rBox.MinZ),
1122
Base::Vector3f(rBox.MinX, rBox.MaxY, rBox.MinZ),
1123
Base::Vector3f(rBox.MinX, rBox.MinY, rBox.MaxZ),
1124
Base::Vector3f(rBox.MaxX, rBox.MinY, rBox.MaxZ),
1125
Base::Vector3f(rBox.MaxX, rBox.MaxY, rBox.MaxZ),
1126
Base::Vector3f(rBox.MinX, rBox.MaxY, rBox.MaxZ)};
1128
MeshFacetIterator cTIt(_rclMesh);
1131
int triangles[36] = {0, 1, 2, 0, 2, 3, 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3,
1132
6, 7, 4, 6, 4, 5, 6, 2, 3, 6, 3, 7, 6, 1, 2, 6, 5, 1};
1134
std::vector<MeshGeomFacet> cFacet(12);
1136
for (size_t ii = 0; ii < 12; ii++) {
1137
cFacet[ii]._aclPoints[0] = cCorner[triangles[id++]];
1138
cFacet[ii]._aclPoints[1] = cCorner[triangles[id++]];
1139
cFacet[ii]._aclPoints[2] = cCorner[triangles[id++]];
1143
for (const auto& it : cFacet) {
1144
for (cTIt.Init(); cTIt.More(); cTIt.Next()) {
1145
int ret = cTIt->IntersectWithFacet(it, pt1, pt2);
1158
for (cTIt.Init(); cTIt.More(); cTIt.Next()) {
1159
if (cTIt->IsPointOfFace(cCorner[0], MeshPoint::epsilon())) {
1163
else if (cTIt->Foraminate(cCorner[0], rcDir, tmp)) {
1165
if ((tmp - cCorner[0]) * rcDir > 0) {
1173
return (ct % 2 == 1) ? 1 : -1;
1180
void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid,
1181
const Base::ViewProjMethod* pclProj,
1182
const Base::Polygon2d& rclPoly,
1184
std::vector<FacetIndex>& raulFacets) const
1186
std::vector<FacetIndex>::iterator it;
1187
MeshFacetIterator clIter(_rclMesh, 0);
1188
Base::Vector3f clPt2d;
1189
Base::Vector3f clGravityOfFacet;
1190
bool bNoPointInside {};
1192
Base::ViewProjMatrix fixedProj(pclProj->getComposedProjectionMatrix());
1194
Base::BoundBox2d clPolyBBox = rclPoly.CalcBoundBox();
1198
BoundBox3f clBBox3d;
1199
BoundBox2d clViewBBox;
1200
std::vector<FacetIndex> aulAllElements;
1202
MeshGridIterator clGridIter(rclGrid);
1203
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
1204
clBBox3d = clGridIter.GetBoundBox();
1205
clViewBBox = clBBox3d.ProjectBox(&fixedProj);
1206
if (clViewBBox.Intersect(clPolyBBox)) {
1208
clGridIter.GetElements(aulAllElements);
1213
std::sort(aulAllElements.begin(), aulAllElements.end());
1214
aulAllElements.erase(std::unique(aulAllElements.begin(), aulAllElements.end()),
1215
aulAllElements.end());
1217
Base::SequencerLauncher seq("Check facets", aulAllElements.size());
1219
for (it = aulAllElements.begin(); it != aulAllElements.end(); ++it) {
1220
bNoPointInside = true;
1221
clGravityOfFacet.Set(0.0f, 0.0f, 0.0f);
1222
MeshGeomFacet rclFacet = _rclMesh.GetFacet(*it);
1223
for (const auto& pnt : rclFacet._aclPoints) {
1224
clPt2d = fixedProj(pnt);
1225
clGravityOfFacet += clPt2d;
1226
if (clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))
1227
&& rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))) {
1228
raulFacets.push_back(*it);
1229
bNoPointInside = false;
1235
if (bNoPointInside) {
1236
clGravityOfFacet *= 1.0f / 3.0f;
1238
if (clPolyBBox.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y))
1239
&& rclPoly.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y))) {
1240
raulFacets.push_back(*it);
1249
Base::SequencerLauncher seq("Check facets", _rclMesh.CountFacets());
1250
for (clIter.Init(); clIter.More(); clIter.Next()) {
1251
for (const auto& pnt : clIter->_aclPoints) {
1252
clPt2d = fixedProj(pnt);
1253
if ((clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))
1254
&& !rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)))) {
1255
raulFacets.push_back(clIter.Position());
1264
void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj,
1265
const Base::Polygon2d& rclPoly,
1267
std::vector<FacetIndex>& raulFacets) const
1269
const MeshPointArray& p = _rclMesh.GetPoints();
1270
const MeshFacetArray& f = _rclMesh.GetFacets();
1271
Base::Vector3f pt2d;
1273
Base::BoundBox2d bb = rclPoly.CalcBoundBox();
1275
Base::ViewProjMatrix fixedProj(pclProj->getComposedProjectionMatrix());
1277
FacetIndex index = 0;
1278
for (MeshFacetArray::_TConstIterator it = f.begin(); it != f.end(); ++it, ++index) {
1279
for (PointIndex ptIndex : it->_aulPoints) {
1280
pt2d = fixedProj(p[ptIndex]);
1283
if ((bb.Contains(Base::Vector2d(pt2d.x, pt2d.y))
1284
&& rclPoly.Contains(Base::Vector2d(pt2d.x, pt2d.y)))
1286
raulFacets.push_back(index);
1293
float MeshAlgorithm::Surface() const
1295
float fTotal = 0.0f;
1296
MeshFacetIterator clFIter(_rclMesh);
1298
for (clFIter.Init(); clFIter.More(); clFIter.Next()) {
1299
fTotal += clFIter->Area();
1305
void MeshAlgorithm::SubSampleByDist(float fDist, std::vector<Base::Vector3f>& rclPoints) const
1308
MeshFacetIterator clFIter(_rclMesh);
1309
for (clFIter.Init(); clFIter.More(); clFIter.Next()) {
1310
size_t k = rclPoints.size();
1311
clFIter->SubSample(fDist, rclPoints);
1312
if (rclPoints.size() == k) {
1313
rclPoints.push_back(clFIter->GetGravityPoint());
1318
void MeshAlgorithm::SubSampleAllPoints(std::vector<Base::Vector3f>& rclPoints) const
1324
MeshPointIterator clPIter(_rclMesh);
1325
for (clPIter.Init(); clPIter.More(); clPIter.Next()) {
1326
rclPoints.push_back(*clPIter);
1330
void MeshAlgorithm::SubSampleByCount(unsigned long ulCtPoints,
1331
std::vector<Base::Vector3f>& rclPoints) const
1333
float fDist = float(sqrt(Surface() / float(ulCtPoints)));
1334
SubSampleByDist(fDist, rclPoints);
1337
void MeshAlgorithm::SearchFacetsFromPolyline(const std::vector<Base::Vector3f>& rclPolyline,
1339
const MeshFacetGrid& rclGrid,
1340
std::vector<FacetIndex>& rclResultFacetsIndices) const
1342
rclResultFacetsIndices.clear();
1343
if (rclPolyline.size() < 3) {
1347
std::set<FacetIndex> aclFacets;
1348
for (std::vector<Base::Vector3f>::const_iterator pV = rclPolyline.begin();
1349
pV < (rclPolyline.end() - 1);
1351
const Base::Vector3f &rclP0 = *pV, &rclP1 = *(pV + 1);
1354
BoundBox3f clSegmBB(rclP0.x, rclP0.y, rclP0.z, rclP0.x, rclP0.y, rclP0.z);
1355
clSegmBB.Add(rclP1);
1356
clSegmBB.Enlarge(fRadius);
1358
std::vector<FacetIndex> aclBBFacets;
1359
unsigned long k = rclGrid.Inside(clSegmBB, aclBBFacets, false);
1360
for (unsigned long i = 0; i < k; i++) {
1361
if (_rclMesh.GetFacet(aclBBFacets[i]).DistanceToLineSegment(rclP0, rclP1) < fRadius) {
1362
aclFacets.insert(aclBBFacets[i]);
1367
rclResultFacetsIndices.insert(rclResultFacetsIndices.begin(),
1372
void MeshAlgorithm::CutBorderFacets(std::vector<FacetIndex>& raclFacetIndices,
1373
unsigned short usLevel) const
1375
std::vector<FacetIndex> aclToDelete;
1377
CheckBorderFacets(raclFacetIndices, aclToDelete, usLevel);
1380
std::vector<FacetIndex> aclResult;
1381
std::set<FacetIndex> aclTmp(aclToDelete.begin(), aclToDelete.end());
1383
for (FacetIndex facetIndex : raclFacetIndices) {
1384
if (aclTmp.find(facetIndex) == aclTmp.end()) {
1385
aclResult.push_back(facetIndex);
1389
raclFacetIndices = aclResult;
1392
unsigned long MeshAlgorithm::CountBorderEdges() const
1394
unsigned long cnt = 0;
1395
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
1396
MeshFacetArray::_TConstIterator end = rclFAry.end();
1397
for (MeshFacetArray::_TConstIterator it = rclFAry.begin(); it != end; ++it) {
1398
for (FacetIndex facetIndex : it->_aulNeighbours) {
1399
if (facetIndex == FACET_INDEX_MAX) {
1408
void MeshAlgorithm::CheckBorderFacets(const std::vector<FacetIndex>& raclFacetIndices,
1409
std::vector<FacetIndex>& raclResultIndices,
1410
unsigned short usLevel) const
1412
ResetFacetFlag(MeshFacet::TMP0);
1413
SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0);
1415
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
1417
for (unsigned short usL = 0; usL < usLevel; usL++) {
1418
for (FacetIndex facetIndex : raclFacetIndices) {
1419
for (FacetIndex ulNB : rclFAry[facetIndex]._aulNeighbours) {
1420
if (ulNB == FACET_INDEX_MAX) {
1421
raclResultIndices.push_back(facetIndex);
1422
rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0);
1425
if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) {
1426
raclResultIndices.push_back(facetIndex);
1427
rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0);
1435
void MeshAlgorithm::GetBorderPoints(const std::vector<FacetIndex>& raclFacetIndices,
1436
std::set<PointIndex>& raclResultPointsIndices) const
1438
ResetFacetFlag(MeshFacet::TMP0);
1439
SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0);
1441
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
1443
for (FacetIndex facetIndex : raclFacetIndices) {
1444
for (int i = 0; i < 3; i++) {
1445
const MeshFacet& rclFacet = rclFAry[facetIndex];
1446
FacetIndex ulNB = rclFacet._aulNeighbours[i];
1447
if (ulNB == FACET_INDEX_MAX) {
1448
raclResultPointsIndices.insert(rclFacet._aulPoints[i]);
1449
raclResultPointsIndices.insert(rclFacet._aulPoints[(i + 1) % 3]);
1452
if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) {
1453
raclResultPointsIndices.insert(rclFacet._aulPoints[i]);
1454
raclResultPointsIndices.insert(rclFacet._aulPoints[(i + 1) % 3]);
1461
bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt,
1462
FacetIndex& rclResFacetIndex,
1463
Base::Vector3f& rclResPoint) const
1465
if (_rclMesh.CountFacets() == 0) {
1470
float fMinDist = FLOAT_MAX;
1471
FacetIndex ulInd = FACET_INDEX_MAX;
1472
MeshFacetIterator pF(_rclMesh);
1473
for (pF.Init(); pF.More(); pF.Next()) {
1474
float fDist = pF->DistanceToPoint(rclPt);
1475
if (fDist < fMinDist) {
1477
ulInd = pF.Position();
1481
MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd);
1482
rclSFacet.DistanceToPoint(rclPt, rclResPoint);
1483
rclResFacetIndex = ulInd;
1488
bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt,
1489
const MeshFacetGrid& rclGrid,
1490
FacetIndex& rclResFacetIndex,
1491
Base::Vector3f& rclResPoint) const
1493
FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt);
1495
if (ulInd == FACET_INDEX_MAX) {
1499
MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd);
1500
rclSFacet.DistanceToPoint(rclPt, rclResPoint);
1501
rclResFacetIndex = ulInd;
1506
bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt,
1507
const MeshFacetGrid& rclGrid,
1508
float fMaxSearchArea,
1509
FacetIndex& rclResFacetIndex,
1510
Base::Vector3f& rclResPoint) const
1512
FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt, fMaxSearchArea);
1514
if (ulInd == FACET_INDEX_MAX) {
1518
MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd);
1519
rclSFacet.DistanceToPoint(rclPt, rclResPoint);
1520
rclResFacetIndex = ulInd;
1525
bool MeshAlgorithm::CutWithPlane(const Base::Vector3f& clBase,
1526
const Base::Vector3f& clNormal,
1527
const MeshFacetGrid& rclGrid,
1528
std::list<std::vector<Base::Vector3f>>& rclResult,
1530
bool bConnectPolygons) const
1532
std::vector<FacetIndex> aulFacets;
1535
MeshGridIterator clGridIter(rclGrid);
1536
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
1538
if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) {
1539
clGridIter.GetElements(aulFacets);
1544
std::sort(aulFacets.begin(), aulFacets.end());
1545
aulFacets.erase(std::unique(aulFacets.begin(), aulFacets.end()), aulFacets.end());
1548
std::list<std::pair<Base::Vector3f, Base::Vector3f>>
1551
for (FacetIndex facetIndex : aulFacets) {
1552
Base::Vector3f clE1, clE2;
1553
const MeshGeomFacet clF(_rclMesh.GetFacet(facetIndex));
1556
if (clF.IntersectWithPlane(clBase, clNormal, clE1, clE2)) {
1557
clTempPoly.emplace_back(clE1, clE2);
1561
if (bConnectPolygons) {
1563
std::list<std::pair<Base::Vector3f, Base::Vector3f>> rclResultLines(clTempPoly.begin(),
1565
std::list<std::vector<Base::Vector3f>> tempList;
1566
ConnectLines(clTempPoly, tempList, fMinEps);
1567
ConnectPolygons(tempList, clTempPoly);
1569
for (auto& iter : clTempPoly) {
1570
rclResultLines.push_front(iter);
1573
return ConnectLines(rclResultLines, rclResult, fMinEps);
1576
return ConnectLines(clTempPoly, rclResult, fMinEps);
1579
bool MeshAlgorithm::ConnectLines(std::list<std::pair<Base::Vector3f, Base::Vector3f>>& rclLines,
1580
std::list<std::vector<Base::Vector3f>>& rclPolylines,
1581
float fMinEps) const
1583
using TCIter = std::list<std::pair<Base::Vector3f, Base::Vector3f>>::iterator;
1587
fMinEps = fMinEps * fMinEps;
1590
std::list<TCIter> _clToDelete;
1591
float fToDelDist = fMinEps / 10.0f;
1592
for (TCIter pF = rclLines.begin(); pF != rclLines.end(); ++pF) {
1593
if (Base::DistanceP2(pF->first, pF->second) < fToDelDist) {
1594
_clToDelete.push_back(pF);
1598
for (auto& pI : _clToDelete) {
1602
while (!rclLines.empty()) {
1606
std::list<Base::Vector3f> clPoly;
1609
Base::Vector3f clFront = rclLines.begin()->first;
1610
Base::Vector3f clEnd = rclLines.begin()->second;
1611
clPoly.push_back(clFront);
1612
clPoly.push_back(clEnd);
1613
rclLines.erase(rclLines.begin());
1616
TCIter pFront, pEnd;
1619
float fFrontMin = fMinEps, fEndMin = fMinEps;
1620
bool bFrontFirst = false, bEndFirst = false;
1622
pFront = rclLines.end();
1623
pEnd = rclLines.end();
1626
for (pF = rclLines.begin(); pF != rclLines.end(); ++pF) {
1627
if (Base::DistanceP2(clFront, pF->first) < fFrontMin) {
1628
fFrontMin = Base::DistanceP2(clFront, pF->first);
1632
else if (Base::DistanceP2(clEnd, pF->first) < fEndMin) {
1633
fEndMin = Base::DistanceP2(clEnd, pF->first);
1637
else if (Base::DistanceP2(clFront, pF->second) < fFrontMin) {
1638
fFrontMin = Base::DistanceP2(clFront, pF->second);
1640
bFrontFirst = false;
1642
else if (Base::DistanceP2(clEnd, pF->second) < fEndMin) {
1643
fEndMin = Base::DistanceP2(clEnd, pF->second);
1649
if (pFront != rclLines.end()) {
1652
clPoly.push_front(pFront->second);
1653
clFront = pFront->second;
1656
clPoly.push_front(pFront->first);
1657
clFront = pFront->first;
1660
rclLines.erase(pFront);
1663
if (pEnd != rclLines.end()) {
1666
clPoly.push_back(pEnd->second);
1667
clEnd = pEnd->second;
1670
clPoly.push_back(pEnd->first);
1671
clEnd = pEnd->first;
1674
rclLines.erase(pEnd);
1676
} while (bFoundLine);
1678
rclPolylines.emplace_back(clPoly.begin(), clPoly.end());
1682
using TPIter = std::list<std::vector<Base::Vector3f>>::iterator;
1683
std::list<TPIter> _clPolyToDelete;
1684
for (TPIter pJ = rclPolylines.begin(); pJ != rclPolylines.end(); ++pJ) {
1685
if (pJ->size() == 2) {
1686
if (Base::DistanceP2(*pJ->begin(), *(pJ->begin() + 1)) <= fMinEps) {
1687
_clPolyToDelete.push_back(pJ);
1692
for (auto& pK : _clPolyToDelete) {
1693
rclPolylines.erase(pK);
1699
bool MeshAlgorithm::ConnectPolygons(
1700
std::list<std::vector<Base::Vector3f>>& clPolyList,
1701
std::list<std::pair<Base::Vector3f, Base::Vector3f>>& rclLines) const
1704
for (std::list<std::vector<Base::Vector3f>>::iterator OutIter = clPolyList.begin();
1705
OutIter != clPolyList.end();
1707
if (OutIter->empty()) {
1710
std::pair<Base::Vector3f, Base::Vector3f> currentSort;
1711
float fDist = Base::Distance(OutIter->front(), OutIter->back());
1712
currentSort.first = OutIter->front();
1713
currentSort.second = OutIter->back();
1715
for (std::list<std::vector<Base::Vector3f>>::iterator InnerIter = clPolyList.begin();
1716
InnerIter != clPolyList.end();
1718
if (OutIter == InnerIter) {
1722
if (Base::Distance(OutIter->front(), InnerIter->front()) < fDist) {
1723
currentSort.second = InnerIter->front();
1724
fDist = Base::Distance(OutIter->front(), InnerIter->front());
1727
if (Base::Distance(OutIter->front(), InnerIter->back()) < fDist) {
1728
currentSort.second = InnerIter->back();
1729
fDist = Base::Distance(OutIter->front(), InnerIter->back());
1733
rclLines.push_front(currentSort);
1739
void MeshAlgorithm::GetFacetsFromPlane(const MeshFacetGrid& rclGrid,
1740
const Base::Vector3f& clNormal,
1742
const Base::Vector3f& rclLeft,
1743
const Base::Vector3f& rclRight,
1744
std::vector<FacetIndex>& rclRes) const
1746
std::vector<FacetIndex> aulFacets;
1748
Base::Vector3f clBase = d * clNormal;
1750
Base::Vector3f clPtNormal(rclLeft - rclRight);
1751
clPtNormal.Normalize();
1754
MeshGridIterator clGridIter(rclGrid);
1755
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) {
1757
if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) {
1758
clGridIter.GetElements(aulFacets);
1763
for (FacetIndex facetIndex : aulFacets) {
1764
MeshGeomFacet clSFacet = _rclMesh.GetFacet(facetIndex);
1765
if (clSFacet.IntersectWithPlane(clBase, clNormal)) {
1766
bool bInner = false;
1767
for (int i = 0; (i < 3) && !bInner; i++) {
1768
Base::Vector3f clPt = clSFacet._aclPoints[i];
1769
if ((clPt.DistanceToPlane(rclLeft, clPtNormal) <= 0.0f)
1770
&& (clPt.DistanceToPlane(rclRight, clPtNormal) >= 0.0f)) {
1776
rclRes.push_back(facetIndex);
1782
void MeshAlgorithm::PointsFromFacetsIndices(const std::vector<FacetIndex>& rvecIndices,
1783
std::vector<Base::Vector3f>& rvecPoints) const
1785
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
1786
const MeshPointArray& rclPAry = _rclMesh._aclPointArray;
1788
std::set<PointIndex> setPoints;
1790
for (FacetIndex facetIndex : rvecIndices) {
1791
for (PointIndex pointIndex : rclFAry[facetIndex]._aulPoints) {
1792
setPoints.insert(pointIndex);
1797
for (PointIndex pointIndex : setPoints) {
1798
rvecPoints.push_back(rclPAry[pointIndex]);
1802
bool MeshAlgorithm::Distance(const Base::Vector3f& rclPt,
1803
FacetIndex ulFacetIdx,
1805
float& rfDistance) const
1807
const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray;
1808
const MeshPointArray& rclPAry = _rclMesh._aclPointArray;
1809
const PointIndex* pulIdx = rclFAry[ulFacetIdx]._aulPoints;
1812
clBB.Add(rclPAry[*(pulIdx++)]);
1813
clBB.Add(rclPAry[*(pulIdx++)]);
1814
clBB.Add(rclPAry[*pulIdx]);
1815
clBB.Enlarge(fMaxDistance);
1817
if (!clBB.IsInBox(rclPt)) {
1821
rfDistance = _rclMesh.GetFacet(ulFacetIdx).DistanceToPoint(rclPt);
1823
return rfDistance < fMaxDistance;
1826
float MeshAlgorithm::CalculateMinimumGridLength(float fLength,
1827
const Base::BoundBox3f& rBBox,
1828
unsigned long maxElements) const
1831
float fMaxGridElements = static_cast<float>(maxElements);
1834
float fMinGridLen = static_cast<float>(
1835
pow((rBBox.LengthX() * rBBox.LengthY() * rBBox.LengthZ() / fMaxGridElements), 0.3333f));
1836
return std::max<float>(fMinGridLen, fLength);
1841
void MeshRefPointToFacets::Rebuild()
1845
const MeshPointArray& rPoints = _rclMesh.GetPoints();
1846
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
1847
_map.resize(rPoints.size());
1849
MeshFacetArray::_TConstIterator pFBegin = rFacets.begin();
1850
for (MeshFacetArray::_TConstIterator pFIter = rFacets.begin(); pFIter != rFacets.end();
1852
_map[pFIter->_aulPoints[0]].insert(pFIter - pFBegin);
1853
_map[pFIter->_aulPoints[1]].insert(pFIter - pFBegin);
1854
_map[pFIter->_aulPoints[2]].insert(pFIter - pFBegin);
1858
Base::Vector3f MeshRefPointToFacets::GetNormal(PointIndex pos) const
1860
const std::set<FacetIndex>& n = _map[pos];
1861
Base::Vector3f normal;
1863
for (FacetIndex it : n) {
1864
f = _rclMesh.GetFacet(it);
1865
normal += f.Area() * f.GetNormal();
1872
std::set<PointIndex> MeshRefPointToFacets::NeighbourPoints(const std::vector<PointIndex>& pt,
1875
std::set<PointIndex> cp, nb, lp;
1876
cp.insert(pt.begin(), pt.end());
1877
lp.insert(pt.begin(), pt.end());
1878
MeshFacetArray::_TConstIterator f_it = _rclMesh.GetFacets().begin();
1879
for (int i = 0; i < level; i++) {
1880
std::set<PointIndex> cur;
1881
for (PointIndex it : lp) {
1882
const std::set<FacetIndex>& ft = (*this)[it];
1883
for (FacetIndex jt : ft) {
1884
for (PointIndex index : f_it[jt]._aulPoints) {
1885
if (cp.find(index) == cp.end() && nb.find(index) == nb.end()) {
1901
std::set<PointIndex> MeshRefPointToFacets::NeighbourPoints(PointIndex pos) const
1903
std::set<PointIndex> p;
1904
const std::set<FacetIndex>& vf = _map[pos];
1905
for (FacetIndex it : vf) {
1906
PointIndex p1 {}, p2 {}, p3 {};
1907
_rclMesh.GetFacetPoints(it, p1, p2, p3);
1922
void MeshRefPointToFacets::Neighbours(FacetIndex ulFacetInd,
1924
MeshCollector& collect) const
1926
std::set<FacetIndex> visited;
1927
Base::Vector3f clCenter = _rclMesh.GetFacet(ulFacetInd).GetGravityPoint();
1929
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
1930
SearchNeighbours(rFacets, ulFacetInd, clCenter, fMaxDist * fMaxDist, visited, collect);
1933
void MeshRefPointToFacets::SearchNeighbours(const MeshFacetArray& rFacets,
1935
const Base::Vector3f& rclCenter,
1937
std::set<FacetIndex>& visited,
1938
MeshCollector& collect) const
1940
if (visited.find(index) != visited.end()) {
1944
const MeshFacet& face = rFacets[index];
1945
if (Base::DistanceP2(rclCenter, _rclMesh.GetFacet(face).GetGravityPoint()) > fMaxDist2) {
1949
visited.insert(index);
1950
collect.Append(_rclMesh, index);
1951
for (PointIndex ptIndex : face._aulPoints) {
1952
const std::set<FacetIndex>& f = (*this)[ptIndex];
1954
for (FacetIndex j : f) {
1955
SearchNeighbours(rFacets, j, rclCenter, fMaxDist2, visited, collect);
1960
MeshFacetArray::_TConstIterator MeshRefPointToFacets::GetFacet(FacetIndex index) const
1962
return _rclMesh.GetFacets().begin() + index;
1965
const std::set<FacetIndex>& MeshRefPointToFacets::operator[](PointIndex pos) const
1970
std::vector<FacetIndex> MeshRefPointToFacets::GetIndices(PointIndex pos1, PointIndex pos2) const
1972
std::vector<FacetIndex> intersection;
1973
std::back_insert_iterator<std::vector<FacetIndex>> result(intersection);
1974
const std::set<FacetIndex>& set1 = _map[pos1];
1975
const std::set<FacetIndex>& set2 = _map[pos2];
1976
std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result);
1977
return intersection;
1980
std::vector<FacetIndex>
1981
MeshRefPointToFacets::GetIndices(PointIndex pos1, PointIndex pos2, PointIndex pos3) const
1983
std::vector<FacetIndex> intersection;
1984
std::back_insert_iterator<std::vector<FacetIndex>> result(intersection);
1985
std::vector<FacetIndex> set1 = GetIndices(pos1, pos2);
1986
const std::set<FacetIndex>& set2 = _map[pos3];
1987
std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result);
1988
return intersection;
1991
void MeshRefPointToFacets::AddNeighbour(PointIndex pos, FacetIndex facet)
1993
_map[pos].insert(facet);
1996
void MeshRefPointToFacets::RemoveNeighbour(PointIndex pos, FacetIndex facet)
1998
_map[pos].erase(facet);
2001
void MeshRefPointToFacets::RemoveFacet(FacetIndex facetIndex)
2003
PointIndex p0 {}, p1 {}, p2 {};
2004
_rclMesh.GetFacetPoints(facetIndex, p0, p1, p2);
2006
_map[p0].erase(facetIndex);
2007
_map[p1].erase(facetIndex);
2008
_map[p2].erase(facetIndex);
2013
void MeshRefFacetToFacets::Rebuild()
2017
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
2018
_map.resize(rFacets.size());
2020
MeshRefPointToFacets vertexFace(_rclMesh);
2021
MeshFacetArray::_TConstIterator pFBegin = rFacets.begin();
2022
for (MeshFacetArray::_TConstIterator pFIter = pFBegin; pFIter != rFacets.end(); ++pFIter) {
2023
for (PointIndex ptIndex : pFIter->_aulPoints) {
2024
const std::set<FacetIndex>& faces = vertexFace[ptIndex];
2025
for (FacetIndex face : faces) {
2026
_map[pFIter - pFBegin].insert(face);
2032
const std::set<FacetIndex>& MeshRefFacetToFacets::operator[](FacetIndex pos) const
2037
std::vector<FacetIndex> MeshRefFacetToFacets::GetIndices(FacetIndex pos1, FacetIndex pos2) const
2039
std::vector<FacetIndex> intersection;
2040
std::back_insert_iterator<std::vector<FacetIndex>> result(intersection);
2041
const std::set<FacetIndex>& set1 = _map[pos1];
2042
const std::set<FacetIndex>& set2 = _map[pos2];
2043
std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result);
2044
return intersection;
2049
void MeshRefPointToPoints::Rebuild()
2053
const MeshPointArray& rPoints = _rclMesh.GetPoints();
2054
_map.resize(rPoints.size());
2056
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
2057
for (const auto& rFacet : rFacets) {
2058
PointIndex ulP0 = rFacet._aulPoints[0];
2059
PointIndex ulP1 = rFacet._aulPoints[1];
2060
PointIndex ulP2 = rFacet._aulPoints[2];
2062
_map[ulP0].insert(ulP1);
2063
_map[ulP0].insert(ulP2);
2064
_map[ulP1].insert(ulP0);
2065
_map[ulP1].insert(ulP2);
2066
_map[ulP2].insert(ulP0);
2067
_map[ulP2].insert(ulP1);
2071
Base::Vector3f MeshRefPointToPoints::GetNormal(PointIndex pos) const
2073
const MeshPointArray& rPoints = _rclMesh.GetPoints();
2074
MeshCore::PlaneFit pf;
2075
pf.AddPoint(rPoints[pos]);
2076
MeshCore::MeshPoint center = rPoints[pos];
2077
const std::set<PointIndex>& cv = _map[pos];
2078
for (PointIndex cv_it : cv) {
2079
pf.AddPoint(rPoints[cv_it]);
2080
center += rPoints[cv_it];
2085
Base::Vector3f normal = pf.GetNormal();
2090
float MeshRefPointToPoints::GetAverageEdgeLength(PointIndex index) const
2092
const MeshPointArray& rPoints = _rclMesh.GetPoints();
2094
const std::set<PointIndex>& n = (*this)[index];
2095
const Base::Vector3f& p = rPoints[index];
2096
for (PointIndex it : n) {
2097
len += Base::Distance(p, rPoints[it]);
2099
return (len / n.size());
2102
const std::set<PointIndex>& MeshRefPointToPoints::operator[](PointIndex pos) const
2107
void MeshRefPointToPoints::AddNeighbour(PointIndex pos, PointIndex facet)
2109
_map[pos].insert(facet);
2112
void MeshRefPointToPoints::RemoveNeighbour(PointIndex pos, PointIndex facet)
2114
_map[pos].erase(facet);
2119
void MeshRefEdgeToFacets::Rebuild()
2123
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
2124
FacetIndex index = 0;
2125
for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ++index) {
2126
for (int i = 0; i < 3; i++) {
2128
e.first = it->_aulPoints[i];
2129
e.second = it->_aulPoints[(i + 1) % 3];
2130
std::map<MeshEdge, MeshFacetPair, EdgeOrder>::iterator jt = _map.find(e);
2131
if (jt == _map.end()) {
2132
_map[e].first = index;
2133
_map[e].second = FACET_INDEX_MAX;
2136
_map[e].second = index;
2142
const std::pair<FacetIndex, FacetIndex>& MeshRefEdgeToFacets::operator[](const MeshEdge& edge) const
2144
return _map.find(edge)->second;
2149
void MeshRefNormalToPoints::Rebuild()
2153
const MeshPointArray& rPoints = _rclMesh.GetPoints();
2154
_norm.resize(rPoints.size());
2156
const MeshFacetArray& rFacets = _rclMesh.GetFacets();
2157
for (const auto& rFacet : rFacets) {
2158
const MeshPoint& p0 = rPoints[rFacet._aulPoints[0]];
2159
const MeshPoint& p1 = rPoints[rFacet._aulPoints[1]];
2160
const MeshPoint& p2 = rPoints[rFacet._aulPoints[2]];
2161
float l2p01 = Base::DistanceP2(p0, p1);
2162
float l2p12 = Base::DistanceP2(p1, p2);
2163
float l2p20 = Base::DistanceP2(p2, p0);
2165
Base::Vector3f facenormal = _rclMesh.GetFacet(rFacet).GetNormal();
2166
_norm[rFacet._aulPoints[0]] += facenormal * (1.0f / (l2p01 * l2p20));
2167
_norm[rFacet._aulPoints[1]] += facenormal * (1.0f / (l2p12 * l2p01));
2168
_norm[rFacet._aulPoints[2]] += facenormal * (1.0f / (l2p20 * l2p12));
2170
for (auto& it : _norm) {
2175
const Base::Vector3f& MeshRefNormalToPoints::operator[](PointIndex pos) const