Skip to content

Commit 7b951fc

Browse files
authored
Fix incorrect verts duplication in uniteCloseVertices (#4593)
* Fix incorrect verts duplication in uniteCloseVertices * fixes * CR Fix2
1 parent 21a6972 commit 7b951fc

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

source/MRMesh/MRMeshBuilder.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ void extractClosedPath( std::vector<VertId>& path, std::vector<VertId>& closedPa
709709
}
710710

711711
// for all vertices get over all incident vertices to find connected sequences
712-
size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region, std::vector<VertDuplication>* dups )
712+
size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region, std::vector<VertDuplication>* dups, VertId lastValidVert )
713713
{
714714
MR_TIMER;
715715
if ( t.empty() )
@@ -718,11 +718,12 @@ size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region, std
718718
std::vector<IncidentVert> incidentItemsVector;
719719
preprocessTriangles( t, region, incidentItemsVector );
720720

721-
auto lastUsedVertId = incidentItemsVector.back().srcVert;
721+
if ( !lastValidVert )
722+
lastValidVert = incidentItemsVector.back().srcVert;
722723

723724
std::vector<VertId> path;
724725
std::vector<VertId> closedPath;
725-
VertBitSet visitedVertices(lastUsedVertId);
726+
VertBitSet visitedVertices( incidentItemsVector.back().srcVert ); // explicitly not `lastValidVert` but last vert used in triangulation
726727
size_t duplicatedVerticesCnt = 0;
727728
size_t posBegin = 0, posEnd = 0;
728729
while ( posEnd != incidentItemsVector.size() )
@@ -767,7 +768,7 @@ size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region, std
767768
{
768769
if ( foundChains )
769770
{
770-
incidentItems.duplicateVertex( path, lastUsedVertId, dups );
771+
incidentItems.duplicateVertex( path, lastValidVert, dups );
771772
++duplicatedVerticesCnt;
772773
}
773774
++foundChains;
@@ -787,7 +788,7 @@ size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region, std
787788

788789
if ( foundChains )
789790
{
790-
incidentItems.duplicateVertex( closedPath, lastUsedVertId, dups );
791+
incidentItems.duplicateVertex( closedPath, lastValidVert, dups );
791792
++duplicatedVerticesCnt;
792793
}
793794
++foundChains;
@@ -873,6 +874,7 @@ int uniteCloseVertices( Mesh& mesh, const UniteCloseParams& params /*= {} */ )
873874
if ( numChanged <= 0 )
874875
return numChanged;
875876

877+
auto lastValidVert = mesh.topology.lastValidVert(); // need to take it before removing faces
876878
Triangulation t( mesh.topology.faceSize() );
877879
FaceBitSet region( mesh.topology.faceSize() );
878880
for ( auto f : mesh.topology.getValidFaces() )
@@ -891,10 +893,11 @@ int uniteCloseVertices( Mesh& mesh, const UniteCloseParams& params /*= {} */ )
891893
if ( params.duplicateNonManifold )
892894
{
893895
std::vector<MeshBuilder::VertDuplication> localDups;
894-
duplicateNonManifoldVertices( t, &region, &localDups );
896+
duplicateNonManifoldVertices( t, &region, &localDups, lastValidVert );
895897
if ( !localDups.empty() )
896898
{
897-
mesh.points.resize( localDups.back().dupVert + 1 );
899+
mesh.points.resizeNoInit( localDups.back().dupVert + 1 );
900+
mesh.topology.vertResize( mesh.points.size() );
898901
for ( auto [org, dup] : localDups )
899902
mesh.points[dup] = mesh.points[org];
900903
if ( params.optionalDuplications )

source/MRMesh/MRMeshBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ struct VertDuplication
4343
};
4444

4545
// resolve non-manifold vertices by creating duplicate vertices in the triangulation (which is modified)
46+
// `lastValidVert` is needed if `region` or `t` does not contain full mesh, then first duplicated vertex will have `lastValidVert+1` index
4647
// return number of duplicated vertices
4748
MRMESH_API size_t duplicateNonManifoldVertices( Triangulation & t, FaceBitSet * region = nullptr,
48-
std::vector<VertDuplication>* dups = nullptr );
49+
std::vector<VertDuplication>* dups = nullptr, VertId lastValidVert = {} );
4950

5051
// construct mesh topology from a set of triangles with given ids;
5152
// unlike simple fromTriangles() it tries to resolve non-manifold vertices by creating duplicate vertices;

0 commit comments

Comments
 (0)