Skip to content

Commit

Permalink
Fix Undercuts: avoid unexpected hole appearance in thin areas (#2737)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fedr authored May 20, 2024
1 parent eb41490 commit ac25d1b
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions source/MRMesh/MRFixUndercuts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
#include "MRVDBFloatGrid.h"
#include "MRMeshIntersect.h"
#include "MRLine3.h"
#include "MRPch/MRTBB.h"
#include "MRMeshDirMax.h"
#include <filesystem>
#include "MRIntersectionPrecomputes.h"
#include "MRPch/MRTBB.h"

namespace MR
{
Expand All @@ -37,6 +37,37 @@ static void extendAndFillAllHoles( Mesh& mesh, float bottomExtension, const Vect
fillHoles( mesh, borders );
}

/// move bottom vertices of given mesh to make object thickness at least (minThickness) in (up) direction;
/// use this function before making signed distance field from the mesh with minThickness=voxelSize
/// to avoid unexpected hole appearance in thin areas
static void makeZThinkAtLeast( Mesh & mesh, float minThickness, Vector3f up )
{
MR_TIMER
up = up.normalized();
const IntersectionPrecomputes<float> iprec( up );
auto newPoints = mesh.points;
BitSetParallelFor( mesh.topology.getValidVerts(), [&]( VertId v )
{
if ( dot( mesh.pseudonormal( v ), up ) >= 0 )
return; // skip top surface vertices
// find up-intersection within minThickness
auto isec = rayMeshIntersect( mesh, { mesh.points[v], up }, 0.0f, minThickness, &iprec, true,
[&]( FaceId f )
{
VertId a, b, c;
mesh.topology.getTriVerts( f, a, b, c );
if ( v == a || v == b || v == c )
return false; // ignore intersections with incident faces of (v)
return dot( mesh.normal( f ), up ) >= 0;
} );
// if such intersection found then move bottom point down
if ( isec )
newPoints[v] = isec->proj.point - minThickness * up;
} );

mesh.points = std::move( newPoints );
}

void fix( FloatGrid& grid, int zOffset )
{
MR_TIMER;
Expand Down Expand Up @@ -107,6 +138,7 @@ void fixUndercuts( Mesh& mesh, const Vector3f& upDirectionMeshSpace, float voxel
zOffset = int( bottomExtension / voxelSize );

extendAndFillAllHoles( mesh, bottomExtension, upDirectionMeshSpace );
makeZThinkAtLeast( mesh, voxelSize, upDirectionMeshSpace );
auto grid = meshToLevelSet( mesh, rot, Vector3f::diagonal( voxelSize ) );
fix( grid, zOffset );

Expand Down Expand Up @@ -141,6 +173,7 @@ void fixUndercuts( Mesh& mesh, const FaceBitSet& faceBitSet, const Vector3f& upD
FaceBitSet copyFBS = faceBitSet;
copyFBS.resize( mesh.topology.faceSize(), false );
extendAndFillAllHoles( mesh, bottomExtension, upDirectionMeshSpace );
makeZThinkAtLeast( mesh, voxelSize, upDirectionMeshSpace );
auto fullGrid = meshToLevelSet( mesh, rot, Vector3f::diagonal( voxelSize ) );
copyFBS.resize( mesh.topology.faceSize(), true );

Expand Down

0 comments on commit ac25d1b

Please sign in to comment.