Skip to content

Commit 7182702

Browse files
authored
Introduce uniteComponents function (#6365)
1 parent 71a96fd commit 7182702

2 files changed

Lines changed: 79 additions & 3 deletions

File tree

source/MRMesh/MRUniteManyMeshes.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "MRMeshCollidePrecise.h"
1010
#include "MRBox.h"
1111
#include "MRParallelFor.h"
12+
#include "MRMeshComponents.h"
13+
#include "MRBitSetParallelFor.h"
1214
#include <random>
1315

1416
namespace MR
@@ -347,4 +349,56 @@ Expected<Mesh> uniteManyMeshes(
347349
return reducer.resultMesh;
348350
}
349351

352+
Expected<Mesh> uniteComponents( const Mesh& mesh, const UniteComponentsParams& params )
353+
{
354+
MR_TIMER;
355+
if ( !mesh.topology.isClosed() )
356+
{
357+
assert( !"uniteComponents: require closed mesh" );
358+
return unexpected( "Mesh is not closed." );
359+
}
360+
auto mapAndNum = MeshComponents::getAllComponentsMap( mesh );
361+
if ( !reportProgress( params.baseParams.progressCb, 0.1f ) )
362+
return unexpectedOperationCanceled();
363+
std::vector<Mesh> components( mapAndNum.second );
364+
std::vector<const Mesh*> meshPtrs( mapAndNum.second );
365+
auto keepGoing = ParallelFor( components, [&] ( size_t i )
366+
{
367+
FaceBitSet compBs( mesh.topology.faceSize() );
368+
BitSetParallelFor( mesh.topology.getValidFaces(), [&] ( FaceId f )
369+
{
370+
if ( RegionId( i ) == mapAndNum.first[f] )
371+
compBs.set( f );
372+
} );
373+
components[i].addMeshPart( MeshPart( mesh, &compBs ) );
374+
375+
if ( params.trySelfBoolean )
376+
{
377+
auto sbRes = selfBoolean( components[i] );
378+
if ( sbRes.has_value() )
379+
{
380+
sbRes->deleteFaces( sbRes->topology.getValidFaces() - MeshComponents::getLargestComponent( *sbRes ) );
381+
components[i] = std::move( *sbRes );
382+
}
383+
}
384+
if ( params.flipInverted && components[i].volume() < 0.0f )
385+
components[i].topology.flipOrientation();
386+
387+
meshPtrs[i] = &components[i];
388+
389+
compBs = {}; // reduce peek memory
390+
391+
if ( params.expansionRatio != 0.0f )
392+
{
393+
auto center = components[i].findCenterFromFaces();
394+
components[i].transform( AffineXf3f::xfAround( Matrix3f::scale( 1.0f + params.expansionRatio ), center ) );
395+
}
396+
}, subprogress( params.baseParams.progressCb, 0.1f, 0.4f ) );
397+
if ( !keepGoing )
398+
return unexpectedOperationCanceled();
399+
UniteManyMeshesParams ump = params.baseParams;
400+
ump.progressCb = subprogress( params.baseParams.progressCb, 0.4f, 1.0f );
401+
return uniteManyMeshes( meshPtrs, ump );
402+
}
403+
350404
}

source/MRMesh/MRUniteManyMeshes.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,32 @@ struct UniteManyMeshesParams
5151
ProgressCallback progressCb;
5252
};
5353

54-
// Computes the surface of objects' union each of which is defined by its own surface mesh
55-
// - merge non intersecting meshes first
56-
// - unite merged groups
54+
/// Computes the surface of objects' union each of which is defined by its own surface mesh
55+
/// - merge non intersecting meshes first
56+
/// - unite merged groups
5757
MRMESH_API Expected<Mesh> uniteManyMeshes( const std::vector<const Mesh*>& meshes,
5858
const UniteManyMeshesParams& params = {} );
5959

60+
/// Parameters structure for uniteComponents function
61+
struct UniteComponentsParams
62+
{
63+
/// Basic parameters of multi unite
64+
UniteManyMeshesParams baseParams;
65+
66+
/// Per component expansion ratio, if !=0 each component is expanded on 1+expRatio around its own centroid
67+
float expansionRatio = 0.0f;
68+
69+
/// If enabled flips orientation for componentns with negative volume
70+
bool flipInverted = true;
71+
72+
/// Try experimental self-boolean for each component
73+
/// not recommended yet
74+
/// TODO: update when self-boolean is finalized
75+
bool trySelfBoolean = false;
76+
};
77+
78+
/// Unites components of single mesh together
79+
/// note: this function require closed mesh
80+
MRMESH_API Expected<Mesh> uniteComponents( const Mesh& mesh, const UniteComponentsParams& params = {} );
81+
6082
}

0 commit comments

Comments
 (0)