Skip to content

Commit

Permalink
MarchingCubes: freeVolume option (#3247)
Browse files Browse the repository at this point in the history
* MarchingCubes: freeVolume option

* free SimpleVolume

* fix pointsToMeshFusion
  • Loading branch information
Fedr authored Aug 28, 2024
1 parent 485e877 commit c3c3cf3
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
8 changes: 6 additions & 2 deletions source/MRMesh/MRMarchingCubes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ Expected<TriMesh> volumeToMesh( const V& volume, const MarchingCubesParams& para
if ( params.cb && !keepGoing )
return unexpectedOperationCanceled();

// free input volume, since it will not be used below any more
if ( params.freeVolume )
params.freeVolume();

const auto totalVertices = sepStorage.makeUniqueVids();
if ( totalVertices > params.maxVertices )
return unexpected( "Vertices number limit exceeded." );
Expand Down Expand Up @@ -538,11 +542,11 @@ Expected<TriMesh> volumeToMesh( const V& volume, const MarchingCubesParams& para
// (*bs)[dl] is one of two bit sets, and layerFirstVoxelId[dl] is VoxelId corresponding to zeroth bit in it
return (*bs)[dl].test( vl.id - layerFirstVoxelId[dl] );
};
for ( loc.pos.y = 0; loc.pos.y + 1 < volume.dims.y; ++loc.pos.y )
for ( loc.pos.y = 0; loc.pos.y + 1 < indexer.dims().y; ++loc.pos.y )
{
loc.pos.x = 0;
loc.id = indexer.toVoxelId( loc.pos );
for ( ; loc.pos.x + 1 < volume.dims.x; ++loc.pos.x, ++loc.id )
for ( ; loc.pos.x + 1 < indexer.dims().x; ++loc.pos.x, ++loc.id )
{
assert( indexer.toVoxelId( loc.pos ) == loc.id );
if ( params.cb && !keepGoing.load( std::memory_order_relaxed ) )
Expand Down
3 changes: 3 additions & 0 deletions source/MRMesh/MRMarchingCubes.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ struct MarchingCubesParams
/// allocates 2 full slices per parallel thread
Normal,
} cachingMode = CachingMode::Automatic;

/// this optional function is called when volume is no longer needed to deallocate it and reduce peak memory consumption
std::function<void()> freeVolume;
};

// makes Mesh from SimpleVolume with given settings using Marching Cubes algorithm
Expand Down
30 changes: 21 additions & 9 deletions source/MRMesh/MROffset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@ Expected<Mesh> mcOffsetMesh( const MeshPart& mp, float offset,
vmParams.lessInside = true;
vmParams.cb = subprogress( params.callBack, 0.4f, 1.0f );
vmParams.outVoxelPerFaceMap = outMap;
auto res = marchingCubes( volume, vmParams );
Timer t( "~FloatGrid" );
volume.data.reset();
t.finish();
return res;
vmParams.freeVolume = [&volume]
{
Timer t( "~FloatGrid" );
volume.data.reset();
};
return marchingCubes( volume, vmParams );
#else
assert( false );
return unexpected( "OpenVDB is not available" );
Expand Down Expand Up @@ -166,9 +167,15 @@ Expected<Mesh> mcOffsetMesh( const MeshPart& mp, float offset,
}
else
{
return
meshToDistanceVolume( mp, msParams )
.and_then( [vmParams] ( auto&& volume ) { return marchingCubes( volume, vmParams ); } );
return meshToDistanceVolume( mp, msParams ).and_then( [&vmParams] ( SimpleVolume&& volume )
{
vmParams.freeVolume = [&volume]
{
Timer t( "~SimpleVolume" );
volume = {};
};
return marchingCubes( volume, vmParams );
} );
}
}
}
Expand Down Expand Up @@ -197,7 +204,12 @@ Expected<Mesh> mcShellMeshRegion( const Mesh& mesh, const FaceBitSet& region, fl
vmParams.cb = subprogress( params.callBack, 0.5f, 1.0f );
vmParams.lessInside = true;
vmParams.outVoxelPerFaceMap = outMap;
return marchingCubes( std::move( *volume ), vmParams );
vmParams.freeVolume = [&volume]
{
Timer t( "~SimpleVolume" );
volume = {};
};
return marchingCubes( *volume, vmParams );
}

Expected<Mesh> sharpOffsetMesh( const MeshPart& mp, float offset, const SharpOffsetParameters& params )
Expand Down
10 changes: 9 additions & 1 deletion source/MRMesh/MRPointsToMeshFusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ Expected<Mesh> pointsToMeshFusion( const PointCloud & cloud, const PointsToMeshP
vmParams.lessInside = true;

auto res = ( params.createVolumeCallback ?
params.createVolumeCallback( cloud, p2vParams ) : pointsToDistanceVolume( cloud, p2vParams ) ).and_then( [vmParams] ( auto&& volume ) { return marchingCubes( volume, vmParams ); } );
params.createVolumeCallback( cloud, p2vParams ) : pointsToDistanceVolume( cloud, p2vParams ) ).and_then( [&vmParams] ( SimpleVolume&& volume )
{
vmParams.freeVolume = [&volume]
{
Timer t( "~SimpleVolume" );
volume = {};
};
return marchingCubes( volume, vmParams );
} );

if ( res && params.ptColors && params.vColors )
{
Expand Down
7 changes: 6 additions & 1 deletion source/MRMesh/MRVoxelsConversionsByParts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ mergeVolumePart( Mesh &mesh, std::vector<EdgePath> &cutContours, Volume &&volume
{
res = marchingCubes( volume, {
.iso = 0.f,
.lessInside = true
.lessInside = true,
.freeVolume = [&volume]
{
Timer t( "~SimpleVolume" );
volume = {};
}
} );
}
else if constexpr ( std::is_same_v<Volume, FunctionVolume> )
Expand Down

0 comments on commit c3c3cf3

Please sign in to comment.