diff --git a/src/Mod/Mesh/App/Core/Algorithm.cpp b/src/Mod/Mesh/App/Core/Algorithm.cpp index f86b7cb1fc..b6a80edc07 100644 --- a/src/Mod/Mesh/App/Core/Algorithm.cpp +++ b/src/Mod/Mesh/App/Core/Algorithm.cpp @@ -449,32 +449,87 @@ void MeshAlgorithm::GetFacetBorder(FacetIndex uFacet, std::list& rBo } } + SplitBoundaryFromOpenEdges(openEdges, rBorder); +} + +void MeshAlgorithm::GetFacetsBorders(const std::vector& uFacets, std::list >& rBorders) const +{ + ResetFacetFlag(MeshFacet::TMP0); + SetFacetsFlag(uFacets, MeshFacet::TMP0); + ResetPointFlag(MeshPoint::TMP0); + + const MeshFacetArray &rFAry = _rclMesh._aclFacetArray; + const MeshPointArray &rPAry = _rclMesh._aclPointArray; + std::list > openEdges; + + // add the open edge to the beginning of the list + for (auto it : uFacets) { + const MeshFacet& face = rFAry[it]; + for (int i = 0; i < 3; i++) { + if (face._aulNeighbours[i] == FACET_INDEX_MAX) { + std::pair openEdge = face.GetEdge(i); + openEdges.push_back(openEdge); + // mark all points of open edges of the given facets + rPAry[openEdge.first].SetFlag(MeshPoint::TMP0); + rPAry[openEdge.second].SetFlag(MeshPoint::TMP0); + } + } + } + + if (openEdges.empty()) + return; // none of the facets are border facets + + for (MeshFacetArray::_TConstIterator it = rFAry.begin(); it != rFAry.end(); ++it) { + if (it->IsFlag(MeshFacet::TMP0)) + continue; + for (int i = 0; i < 3; i++) { + if (it->_aulNeighbours[i] == FACET_INDEX_MAX) + openEdges.push_back(it->GetEdge(i)); + } + } + + // if the first element is not an edge of "uFacets" then give up + while (!openEdges.empty()) { + PointIndex first = openEdges.begin()->first; + PointIndex second = openEdges.begin()->second; + if (!rPAry[first].IsFlag(MeshPoint::TMP0)) + break; + if (!rPAry[second].IsFlag(MeshPoint::TMP0)) + break; + + std::list boundary; + SplitBoundaryFromOpenEdges(openEdges, boundary); + rBorders.emplace_back(boundary.begin(), boundary.end()); + } +} + +void MeshAlgorithm::SplitBoundaryFromOpenEdges(std::list >& openEdges, std::list& boundary) const +{ // Start with the edge that is associated to uFacet + if (openEdges.empty()) + return; + PointIndex ulFirst = openEdges.begin()->first; PointIndex ulLast = openEdges.begin()->second; openEdges.erase(openEdges.begin()); - rBorder.push_back(ulFirst); - rBorder.push_back(ulLast); + boundary.push_back(ulFirst); + boundary.push_back(ulLast); - while (ulLast != ulFirst) - { + while (ulLast != ulFirst) { // find adjacent edge std::list >::iterator pEI; - for (pEI = openEdges.begin(); pEI != openEdges.end(); ++pEI) - { - if (pEI->first == ulLast) - { + for (pEI = openEdges.begin(); pEI != openEdges.end(); ++pEI) { + if (pEI->first == ulLast) { ulLast = pEI->second; - rBorder.push_back(ulLast); + boundary.push_back(ulLast); openEdges.erase(pEI); pEI = openEdges.begin(); break; } - else if (pEI->second == ulFirst) - { + else if (pEI->second == ulFirst) { ulFirst = pEI->first; - rBorder.push_front(ulFirst); + boundary.push_front(ulFirst); openEdges.erase(pEI); pEI = openEdges.begin(); break; diff --git a/src/Mod/Mesh/App/Core/Algorithm.h b/src/Mod/Mesh/App/Core/Algorithm.h index 557032dd0e..0c35235f0b 100644 --- a/src/Mod/Mesh/App/Core/Algorithm.h +++ b/src/Mod/Mesh/App/Core/Algorithm.h @@ -155,6 +155,11 @@ public: * boundary is empty. */ void GetFacetBorder(FacetIndex uFacet, std::list& rBorder) const; + /** + * Returns the boundary of the mesh to the facets \a uFacest. If none of the facets have an open edge the returned + * boundary is empty. + */ + void GetFacetsBorders(const std::vector& uFacets, std::list >& rBorders) const; /** * Boundaries that consist of several loops must be split in several independent boundaries * to perform e.g. a polygon triangulation algorithm on them. @@ -316,7 +321,11 @@ protected: /** * Splits the boundary \a rBound in several loops and append this loops to the list of borders. */ - void SplitBoundaryLoops( const std::vector& rBound, std::list >& aBorders ); + void SplitBoundaryLoops(const std::vector& rBound, std::list >& aBorders); + /** + * From the given \a openEdges a boundary is split and added to \a boundary. + */ + void SplitBoundaryFromOpenEdges(std::list >& openEdges, std::list& boundary) const; protected: const MeshKernel &_rclMesh; /**< The mesh kernel. */ diff --git a/src/Mod/Mesh/App/Core/Degeneration.cpp b/src/Mod/Mesh/App/Core/Degeneration.cpp index f352d5d480..321a22259b 100644 --- a/src/Mod/Mesh/App/Core/Degeneration.cpp +++ b/src/Mod/Mesh/App/Core/Degeneration.cpp @@ -1255,12 +1255,7 @@ void MeshFixPointOnEdge::FindBoundaries(std::list >& bor meshalg.GetFacetsFlag(tmp, MeshFacet::TMP0); if (!tmp.empty()) { - //TODO: Implement a method to handle all facets in 'tmp' - std::list border; - meshalg.GetFacetBorder(tmp.front(), border); - if (!border.empty()) { - borderList.emplace_back(border.begin(), border.end()); - } + meshalg.GetFacetsBorders(tmp, borderList); } }