Skip to content

Commit efacbd7

Browse files
authored
Update fix creases logic (#4559)
1 parent cc8718f commit efacbd7

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

source/MRMesh/MRMeshFixer.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -687,22 +687,18 @@ void fixMeshCreases( Mesh& mesh, const FixCreasesParams& params )
687687
FaceBitSet fixFacesBuffer( mesh.topology.getValidFaces().size() );
688688
for ( auto ue : creases )
689689
{
690-
auto creaseEdge = EdgeId( ue );
691-
if ( mesh.topology.getOrgDegree( creaseEdge ) < mesh.topology.getOrgDegree( creaseEdge.sym() ) )
692-
creaseEdge = creaseEdge.sym(); // important part to triangulate worse end of the edge (mb we should change degree check to area check?)
693-
694-
fixFacesBuffer.reset();
695-
696-
auto findBadFaces = [&] ( bool left )
690+
if ( mesh.topology.isLoneEdge( EdgeId( ue ) ) )
691+
continue;
692+
auto findBadFaces = [&] ( EdgeId ce, bool left )
697693
{
698-
for ( auto e = creaseEdge;; )
694+
for ( auto e = ce;; )
699695
{
700696
auto f = left ? mesh.topology.left( e ) : mesh.topology.right( e );
701697
if ( !f )
702698
return;
703699
fixFacesBuffer.autoResizeSet( f ); // as far as we triangulate holes - new faces might appear, so we need to resize
704700
e = left ? mesh.topology.next( e ) : mesh.topology.prev( e );
705-
if ( e == creaseEdge )
701+
if ( e == ce )
706702
return; // full cycle
707703
auto nextF = left ? mesh.topology.left( e ) : mesh.topology.right( e );
708704
if ( !nextF )
@@ -716,12 +712,33 @@ void fixMeshCreases( Mesh& mesh, const FixCreasesParams& params )
716712
return; // stop propagation on sharp angle
717713
}
718714
};
719-
findBadFaces( true );
720-
findBadFaces( false );
715+
716+
int numIncidentLCreases = 0;
717+
int numIncidentRCreases = 0;
718+
auto creaseEdge = EdgeId( ue );
719+
for ( auto e : orgRing( mesh.topology, creaseEdge ) )
720+
{
721+
if ( creases.test( e.undirected() ) )
722+
numIncidentLCreases++;
723+
}
724+
for ( auto e : orgRing( mesh.topology, creaseEdge.sym() ) )
725+
{
726+
if ( creases.test( e.undirected() ) )
727+
numIncidentRCreases++;
728+
}
729+
if ( ( numIncidentRCreases > numIncidentLCreases )
730+
|| ( numIncidentRCreases == numIncidentLCreases &&
731+
mesh.topology.getOrgDegree( creaseEdge ) < mesh.topology.getOrgDegree( creaseEdge.sym() ) ) )
732+
{
733+
creaseEdge = creaseEdge.sym();// important part to triangulate worse end of the edge (mb we should change degree check to area check?)
734+
}
735+
fixFacesBuffer.reset();
736+
findBadFaces( creaseEdge, true );
737+
findBadFaces( creaseEdge, false );
721738
if ( fixFacesBuffer.none() )
722739
continue;
723740

724-
auto loops = delRegionKeepBd( mesh, fixFacesBuffer );
741+
auto loops = delRegionKeepBd( mesh, fixFacesBuffer, true );
725742
for ( const auto& loop : loops )
726743
{
727744
int i = 0;

source/MRMesh/MRRegionBoundary.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ std::vector<EdgeLoop> findLeftBoundary( const MeshTopology& topology, const Face
9494
return findRegionBoundary( topology, region, true );
9595
}
9696

97-
std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet * region /*= nullptr */ )
97+
std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet * region /*= nullptr */, bool keepLoneHoles )
9898
{
9999
MR_TIMER;
100100

@@ -104,7 +104,7 @@ std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet * region /*
104104
filteredBds.reserve( bds.size() );
105105
for ( auto & bd : bds )
106106
{
107-
if ( std::all_of( bd.begin(), bd.end(), [&]( EdgeId e ) { return !mesh.topology.right( e ); } ) )
107+
if ( !keepLoneHoles && std::all_of( bd.begin(), bd.end(), [&]( EdgeId e ) { return !mesh.topology.right( e ); } ) )
108108
continue; // delete boundary loops not having any single triangle outside of region
109109
for ( auto e : bd )
110110
uset.set( e );

source/MRMesh/MRRegionBoundary.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ namespace MR
3131
{ return findRightBoundary( topology, &region ); }
3232

3333
/// deletes all region faces, inner edges and vertices, but keeps boundary edges and vertices of the region (or whole mesh if region is null);
34+
/// if `keepLoneHoles` is set - keeps boundary even if it has no valid faces on other side
3435
/// returns edge loops, each having deleted region faces on the left, and not-region faces or holes on the right
35-
MRMESH_API std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet * region = nullptr );
36-
inline std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet & region )
37-
{ return delRegionKeepBd( mesh, &region ); }
36+
MRMESH_API std::vector<EdgeLoop> delRegionKeepBd( Mesh& mesh, const FaceBitSet* region = nullptr, bool keepLoneHoles = false );
37+
inline std::vector<EdgeLoop> delRegionKeepBd( Mesh & mesh, const FaceBitSet & region, bool keepLoneHoles = false )
38+
{ return delRegionKeepBd( mesh, &region, keepLoneHoles ); }
3839

3940
/// returns all region boundary paths;
4041
/// every path has region faces on the left, and valid not-region faces on the right

0 commit comments

Comments
 (0)