MeshLib Documentation
Loading...
Searching...
No Matches
Laplacian deformation Example

Example of using Laplacian deformer

  • C++
    #include <MRMesh/MRBox.h>
    #include <MRMesh/MRExpandShrink.h>
    #include <MRMesh/MRLaplacian.h>
    #include <MRMesh/MRMesh.h>
    #include <MRMesh/MRMeshLoad.h>
    #include <MRMesh/MRMeshSave.h>
    int main()
    {
    // Load mesh
    auto mesh = MR::MeshLoad::fromAnySupportedFormat( "mesh.stl" );
    assert( mesh );
    // Construct deformer on the mesh vertices
    MR::Laplacian lDeformer( *mesh );
    // Find an area for the deformation anchor points
    const auto ancV0 = mesh->topology.getValidVerts().find_first();
    const auto ancV1 = mesh->topology.getValidVerts().find_last();
    // Mark the anchor points in the free area
    MR::VertBitSet freeVerts;
    freeVerts.resize( mesh->topology.getValidVerts().size() );
    freeVerts.set( ancV0, true );
    freeVerts.set( ancV1, true );
    // Expand the free area
    MR::expand( mesh->topology, freeVerts, 5 );
    // Initialize laplacian
    lDeformer.init( freeVerts, MR::EdgeWeights::CotanWithAreaEqWeight );
    const auto shiftAmount = mesh->computeBoundingBox().diagonal() * 0.01f;
    // Fix the anchor vertices in the required position
    lDeformer.fixVertex( ancV0, mesh->points[ancV0] + mesh->normal( ancV0 ) * shiftAmount );
    lDeformer.fixVertex( ancV1, mesh->points[ancV1] + mesh->normal( ancV1 ) * shiftAmount );
    // Move the free vertices according to the anchor ones
    lDeformer.apply();
    // Invalidate the mesh because of the external vertex changes
    mesh->invalidateCaches();
    // Save the deformed mesh
    MR::MeshSave::toAnySupportedFormat( *mesh, "deformed_mesh.stl" );
    }
    MRMESH_API Expected< Mesh > fromAnySupportedFormat(const std::filesystem::path &file, const MeshLoadSettings &settings={})
    MRMESH_API Expected< void > toAnySupportedFormat(const Mesh &mesh, const std::filesystem::path &file, const SaveSettings &settings={})
    MRMESH_API void expand(const MeshTopology &topology, FaceBitSet &region, int hops=1)
  • Python
    Note
    Python API version 3 and later
    from meshlib import mrmeshpy as mm
    # Load mesh
    mesh = mm.loadMesh("mesh.stl")
    # Construct deformer on mesh vertices
    lDeformer = mm.Laplacian(mesh)
    # Find area for deformation anchor points
    ancV0 = mesh.topology.getValidVerts().find_first()
    ancV1 = mesh.topology.getValidVerts().find_last()
    # Mark anchor points in free area
    freeVerts = mm.VertBitSet()
    freeVerts.resize(mesh.topology.getValidVerts().size())
    freeVerts.set( ancV0, True )
    freeVerts.set( ancV1, True )
    # Expand free area
    mm.expand(mesh.topology,freeVerts,5)
    # Initialize laplacian
    lDeformer.init(freeVerts,mm.EdgeWeights.CotanWithAreaEqWeight)
    shiftAmount = mesh.computeBoundingBox().diagonal()*0.01
    # Fix anchor vertices in required position
    lDeformer.fixVertex( ancV0, mesh.points.vec[ancV0.get()] + mesh.normal(ancV0) * shiftAmount )
    lDeformer.fixVertex( ancV1, mesh.points.vec[ancV1.get()] + mesh.normal(ancV1) * shiftAmount )
    # Move free vertices according to anchor ones
    lDeformer.apply()
    # Invalidate mesh because of external vertices changes
    mesh.invalidateCaches()
    # Save deformed mesh
    mm.saveMesh(mesh,"deformed_mesh.stl")
    size_t size() const
  • C
    #include <MRMeshC/MRBitSet.h>
    #include <MRMeshC/MRExpandShrink.h>
    #include <MRMeshC/MRLaplacian.h>
    #include <MRMeshC/MRMesh.h>
    #include <MRMeshC/MRMeshLoad.h>
    #include <MRMeshC/MRMeshSave.h>
    #include <stdlib.h>
    int main( int argc, char* argv[] )
    {
    // Load mesh
    MRMesh* mesh = mrMeshLoadFromAnySupportedFormat( "mesh.stl", NULL );
    // Construct deformer on the mesh vertices
    MRLaplacian* lDeformer = mrLaplacianNew( mesh );
    // Find an area for the deformation anchor points
    MRVertId ancV0 = { mrBitSetFindFirst( (MRBitSet*)verts ) };
    MRVertId ancV1 = { mrBitSetFindLast( (MRBitSet*)verts ) };
    // Mark the anchor points in the free area
    MRVertBitSet* freeVerts = mrVertBitSetNew( mrBitSetSize( (MRBitSet*)verts ), false );
    mrBitSetSet( (MRBitSet*)verts, ancV0.id, true );
    mrBitSetSet( (MRBitSet*)verts, ancV1.id, true );
    // Expand the free area
    mrExpandVertRegion( mrMeshTopology( mesh ), freeVerts, 5 );
    // Initialize laplacian
    mrLaplacianInit( lDeformer, freeVerts, MREdgeWeightsCotanWithAreaEqWeight, MRLaplacianRememberShapeYes );
    MRBox3f bbox = mrMeshComputeBoundingBox( mesh, NULL );
    float shiftAmount = mrBox3fDiagonal( &bbox ) * 0.01f;
    // Fix the anchor vertices in the required position
    const MRVector3f* points = mrMeshPoints( mesh );
    MRVector3f posV0 = mrMeshNormalFromVert( mesh, ancV0 );
    posV0 = mrVector3fMulScalar( &posV0, shiftAmount );
    posV0 = mrVector3fAdd( &points[ancV0.id], &posV0 );
    mrLaplacianFixVertex( lDeformer, ancV0, &posV0, true );
    MRVector3f posV1 = mrMeshNormalFromVert( mesh, ancV1 );
    posV1 = mrVector3fMulScalar( &posV1, shiftAmount );
    posV1 = mrVector3fAdd( &points[ancV1.id], &posV1 );
    mrLaplacianFixVertex( lDeformer, ancV1, &posV1, true );
    // Move the free vertices according to the anchor ones
    mrLaplacianApply( lDeformer );
    // Invalidate the mesh because of the external vertex changes
    mrMeshInvalidateCaches( mesh, true );
    // Save the deformed mesh
    mrMeshSaveToAnySupportedFormat( mesh, "deformed_mesh.stl", NULL, NULL );
    mrVertBitSetFree( freeVerts );
    mrLaplacianFree( lDeformer );
    mrMeshFree( mesh );
    return EXIT_SUCCESS;
    }
    MRMESHC_API size_t mrBitSetSize(const MRBitSet *bs)
    MRMESHC_API void mrBitSetSet(MRBitSet *bs, size_t index, bool value)
    MRMESHC_API size_t mrBitSetFindLast(const MRBitSet *bs)
    MRMESHC_API MRVertBitSet * mrVertBitSetNew(size_t numBits, bool fillValue)
    MRMESHC_API void mrVertBitSetFree(MRVertBitSet *vbs)
    MRMESHC_API size_t mrBitSetFindFirst(const MRBitSet *bs)
    MRMESHC_API float mrBox3fDiagonal(const MRBox3f *box)
    MRMESHC_API void mrExpandVertRegion(const MRMeshTopology *top, MRVertBitSet *region, int hops)
    MRMESHC_API void mrLaplacianFixVertex(MRLaplacian *laplacian, MRVertId v, const MRVector3f *fixedPos, bool smooth)
    MRMESHC_API void mrLaplacianFree(MRLaplacian *laplacian)
    MRMESHC_API void mrLaplacianInit(MRLaplacian *laplacian, const MRVertBitSet *freeVerts, MREdgeWeights weights, MRLaplacianRememberShape rem)
    MRMESHC_API MRLaplacian * mrLaplacianNew(MRMesh *mesh)
    MRMESHC_API void mrLaplacianApply(MRLaplacian *laplacian)
    struct MRLaplacian MRLaplacian
    struct MRVertBitSet MRVertBitSet
    struct MRMesh MRMesh
    struct MRBitSet MRBitSet
    MR_EXTERN_C_BEGIN MRMESHC_API MRMesh * mrMeshLoadFromAnySupportedFormat(const char *file, MRString **errorStr)
    MR_EXTERN_C_BEGIN MRMESHC_API void mrMeshSaveToAnySupportedFormat(const MRMesh *mesh, const char *file, const MRSaveSettings *settings, MRString **errorStr)
    MRMESHC_API const MRVertBitSet * mrMeshTopologyGetValidVerts(const MRMeshTopology *top)
    MRMESHC_API const MRVector3f * mrMeshPoints(const MRMesh *mesh)
    MRMESHC_API const MRMeshTopology * mrMeshTopology(const MRMesh *mesh)
    MRMESHC_API MRBox3f mrMeshComputeBoundingBox(const MRMesh *mesh, const MRAffineXf3f *toWorld)
    MRMESHC_API void mrMeshFree(MRMesh *mesh)
    MRMESHC_API MRVector3f mrMeshNormalFromVert(const MRMesh *mesh, MRVertId v)
    MRMESHC_API void mrMeshInvalidateCaches(MRMesh *mesh, bool pointsChanged)
    MRMESHC_API MRVector3f mrVector3fAdd(const MRVector3f *a, const MRVector3f *b)
    MRMESHC_API MRVector3f mrVector3fMulScalar(const MRVector3f *a, float b)