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>
    #include <iostream>
    int main()
    {
    // Load mesh
    auto loadRes = MR::MeshLoad::fromAnySupportedFormat( "mesh.stl" );
    if ( !loadRes.has_value() )
    {
    std::cerr << loadRes.error() << std::endl;
    return 1;
    }
    MR::Mesh& mesh = *loadRes;
    // 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::Cotan, MR::VertexMass::NeiArea );
    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
    if ( auto saveRes = MR::MeshSave::toAnySupportedFormat( mesh, "deformed_mesh.stl" ); !saveRes )
    {
    std::cerr << saveRes.error() << std::endl;
    return 1;
    }
    }
    int main()
    Definition LaplacianDeformation.cpp:4
  • 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.Cotan,mm.VertexMass.NeiArea)
    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")
  • C
    #include <MRCMesh/MRBitSet.h>
    #include <MRCMesh/MRExpandShrink.h>
    #include <MRCMesh/MRLaplacian.h>
    #include <MRCMesh/MRMesh.h>
    #include <MRCMesh/MRMeshLoad.h>
    #include <MRCMesh/MRMeshSave.h>
    #include <MRCMesh/MRMeshTopology.h>
    #include <MRCMesh/MRVector.h>
    #include <MRCMisc/expected_MR_Mesh_std_string.h>
    #include <MRCMisc/std_string.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main( void )
    {
    // Load mesh
    MR_expected_MR_Mesh_std_string* meshEx = MR_MeshLoad_fromAnySupportedFormat_2( "mesh.stl", NULL, NULL );
    MR_Mesh* mesh = MR_expected_MR_Mesh_std_string_value_mut( meshEx );
    // Handle failure to load mesh
    if ( !mesh )
    {
    fprintf( stderr, "Failed to load mesh: %s\n", MR_std_string_data( MR_expected_MR_Mesh_std_string_error( meshEx ) ) );
    MR_expected_MR_Mesh_std_string_Destroy( meshEx );
    return 1;
    }
    // Construct deformer on the mesh vertices
    MR_Laplacian* lDeformer = MR_Laplacian_Construct_1( mesh );
    // Find an area for the deformation anchor points
    const MR_VertBitSet* verts = MR_MeshTopology_getValidVerts( MR_Mesh_Get_topology( mesh ) );
    MR_VertId ancV0 = MR_VertBitSet_find_first( verts );
    MR_VertId ancV1 = MR_VertBitSet_find_last( verts );
    // Mark the anchor points in the free area
    MR_VertBitSet* freeVerts = MR_VertBitSet_DefaultConstruct();
    MR_BitSet_resize( MR_VertBitSet_MutableUpcastTo_MR_BitSet( freeVerts ), MR_BitSet_size( MR_VertBitSet_UpcastTo_MR_BitSet( verts ) ), NULL );
    MR_BitSet_set_2( MR_VertBitSet_MutableUpcastTo_MR_BitSet( freeVerts ), ancV0.id_, true );
    MR_BitSet_set_2( MR_VertBitSet_MutableUpcastTo_MR_BitSet( freeVerts ), ancV1.id_, true );
    // Expand the free area
    MR_expand_MR_VertBitSet( MR_Mesh_Get_topology( mesh ), freeVerts, &(int){5} );
    // Initialize laplacian
    MR_Laplacian_init( lDeformer, freeVerts, MR_EdgeWeights_Cotan, &(MR_VertexMass){MR_VertexMass_NeiArea}, NULL );
    MR_Box3f bbox = MR_Mesh_computeBoundingBox_1( mesh, NULL );
    float shiftAmount = MR_Box3f_diagonal( &bbox ) * 0.01f;
    // Fix the anchor vertices in the required position
    const MR_VertCoords* points = MR_Mesh_Get_points( mesh );
    MR_Vector3f posV0 = MR_Mesh_normal_MR_VertId( mesh, ancV0 );
    posV0 = MR_mul_MR_Vector3f_float( &posV0, shiftAmount );
    posV0 = MR_add_MR_Vector3f( MR_VertCoords_index( points, ancV0 ), &posV0 );
    MR_Laplacian_fixVertex_3( lDeformer, ancV0, &posV0, NULL );
    MR_Vector3f posV1 = MR_Mesh_normal_MR_VertId( mesh, ancV1 );
    posV1 = MR_mul_MR_Vector3f_float( &posV1, shiftAmount );
    posV1 = MR_add_MR_Vector3f( MR_VertCoords_index( points, ancV1 ), &posV1 );
    MR_Laplacian_fixVertex_3( lDeformer, ancV1, &posV1, NULL );
    // Move the free vertices according to the anchor ones
    MR_Laplacian_apply( lDeformer );
    // Invalidate the mesh because of the external vertex changes
    MR_Mesh_invalidateCaches( mesh, NULL );
    // Save the deformed mesh
    MR_MeshSave_toAnySupportedFormat_3( mesh, "deformed_mesh.stl", NULL, NULL );
    MR_VertBitSet_Destroy( freeVerts );
    MR_Laplacian_Destroy( lDeformer );
    MR_expected_MR_Mesh_std_string_Destroy( meshEx );
    return EXIT_SUCCESS;
    }