Skip to content

Commit 9d3d889

Browse files
authored
Propagate mimic patch to other functions (#5920)
* Propagate mimic patch to other functions - add `mimic` option to self-intersection fixer - add `mimic` option to degeneracies fixer - allow zero expand for self-intersection fixer * fix comment
1 parent c2c4c36 commit 9d3d889

4 files changed

Lines changed: 47 additions & 11 deletions

File tree

source/MRMesh/MRFixSelfIntersections.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Expected<void> fix( Mesh& mesh, const Settings& settings )
153153
if ( res->none() )
154154
return {};
155155

156-
expand( mesh.topology, *res, settings.maxExpand );
156+
expand( mesh.topology, *res, std::max( settings.maxExpand, 1 ) );
157157

158158
Settings currentSettings = settings;
159159
if ( currentSettings.subdivideEdgeLen < FLT_MAX )
@@ -187,7 +187,8 @@ Expected<void> fix( Mesh& mesh, const Settings& settings )
187187
if ( !res.has_value() )
188188
return unexpected( res.error() );
189189

190-
expand( mesh.topology, *res, settings.maxExpand );
190+
if ( settings.maxExpand > 0 )
191+
expand( mesh.topology, *res, settings.maxExpand );
191192

192193
if ( settings.method == Settings::Method::Relax )
193194
{
@@ -204,6 +205,9 @@ Expected<void> fix( Mesh& mesh, const Settings& settings )
204205
else
205206
{
206207
auto boundaryEdges = mesh.topology.findLeftBdEdges();
208+
Mesh patchRefMesh;
209+
if ( settings.mimicPatch )
210+
patchRefMesh.addMeshPart( { mesh,&*res } );
207211
mesh.topology.deleteFaces( *res );
208212
mesh.topology.deleteFaces( findHoleComplicatingFaces( mesh ) );
209213
mesh.invalidateCaches();
@@ -230,8 +234,22 @@ Expected<void> fix( Mesh& mesh, const Settings& settings )
230234
// Fill hole
231235
// MultipleEdgesResolveMode::Simple should be enough after deleting findHoleComplicatingFaces(...)
232236
// But if multiple edges appear often, could be changed to MultipleEdgesResolveMode::Strong
233-
fillHole( mesh, holes[i].front(), {.metric = getMinAreaMetric(mesh),
234-
.multipleEdgesResolveMode = FillHoleParams::MultipleEdgesResolveMode::Simple });
237+
FillHoleParams fhParams;
238+
if ( settings.mimicPatch )
239+
{
240+
fhParams.metric = mixMetrics(
241+
getMinAreaMetric( mesh ), getCloseSurfaceFillMetric( mesh, patchRefMesh ),
242+
[] ( double a, double b )->double
243+
{
244+
return a + 1000.0 * b;
245+
} );
246+
}
247+
else
248+
{
249+
fhParams.metric = getMinAreaMetric( mesh );
250+
}
251+
fhParams.multipleEdgesResolveMode = FillHoleParams::MultipleEdgesResolveMode::Simple;
252+
fillHole( mesh, holes[i].front(), fhParams );
235253

236254
if ( !reportProgress( sp, float( i + 1 ) / float( holes.size() ) ) )
237255
return unexpectedOperationCanceled();

source/MRMesh/MRFixSelfIntersections.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ struct Settings
2525
Method method = Method::Relax;
2626
/// Maximum relax iterations
2727
int relaxIterations = 5;
28-
/// Maximum expand count (edge steps from self-intersecting faces), should be > 0
28+
/// Maximum expand count (edge steps from self-intersecting faces), should be >= 0
2929
int maxExpand = 3;
3030
/// Edge length for subdivision of holes covers (0.0f means auto)
3131
/// FLT_MAX to disable subdivision
3232
float subdivideEdgeLen = 0.0f;
33+
/// trying to stay close to initial surface when patching
34+
bool mimicPatch = false;
3335
/// Callback function
3436
ProgressCallback callback = {};
3537
};

source/MRMesh/MRMeshFixer.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,20 +250,32 @@ Expected<void> fixMeshDegeneracies( Mesh& mesh, const FixMeshDegeneraciesParams&
250250
{
251251
.triangulateParams =
252252
{
253-
.metric = getUniversalMetric( mesh ),
254253
.multipleEdgesResolveMode = FillHoleParams::MultipleEdgesResolveMode::Strong,
255254
},
256255
.subdivideSettings =
257256
{
258257
.maxEdgeLen = 0.0f, // to use default from `patchMesh`
259258
.maxEdgeSplits = 20'000,
260-
},
261-
.smoothCurvature = true,
262-
.smoothSettings =
263-
{
264-
.edgeWeights = EdgeWeights::Unit // use unit weights to avoid potential laplacian degeneration (which leads to nan coords)
265259
}
266260
};
261+
Mesh patchRefMesh;
262+
if ( params.mimicPatch )
263+
{
264+
patchRefMesh.addMeshPart( { mesh,&*regRes } );
265+
psettings.triangulateParams.metric = mixMetrics(
266+
getCircumscribedMetric( mesh ), getCloseSurfaceFillMetric( mesh, patchRefMesh ),
267+
[] ( double a, double b )->double
268+
{
269+
return a + 100.0 * std::sqrt( b );
270+
} );
271+
psettings.smoothCurvature = false;
272+
}
273+
else
274+
{
275+
psettings.triangulateParams.metric = getUniversalMetric( mesh );
276+
psettings.smoothCurvature = true;
277+
psettings.smoothSettings.edgeWeights = EdgeWeights::Unit; // use unit weights to avoid potential laplacian degeneration (which leads to nan coords)
278+
}
267279

268280
auto newFaces = patchMesh( mesh, *regRes, psettings );
269281

source/MRMesh/MRMeshFixer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ struct FixMeshDegeneraciesParams
6666
RemeshPatch ///< if both decimation and subdivision does not succeed, removes degenerate areas and fills occurred holes
6767
} mode{ Mode::Remesh };
6868

69+
/// trying to stay close to initial surface when patching
70+
/// also disables smoothing on patch
71+
bool mimicPatch = false;
72+
6973
ProgressCallback cb;
7074
};
7175

0 commit comments

Comments
 (0)