MeshLib Documentation
Loading...
Searching...
No Matches
Mesh Offset

Example of mesh offset

  • C++
    #include <MRMesh/MRBox.h>
    #include <MRMesh/MRMesh.h>
    #include <MRMesh/MRCube.h>
    #include <MRMesh/MRMeshSave.h>
    #include <MRMesh/MRRegionBoundary.h>
    #include <MRVoxels/MROffset.h>
    #include <iostream>
    int main()
    {
    // Create mesh
    MR::Mesh mesh = MR::makeCube();
    // Setup parameters
    MR::GeneralOffsetParameters params;
    // calculate voxel size depending on desired accuracy and/or memory consumption
    params.voxelSize = suggestVoxelSize( mesh, 10000000.f );
    if ( !MR::findRightBoundary( mesh.topology ).empty() )
    params.signDetectionMode = MR::SignDetectionMode::HoleWindingRule; // use if you have holes in mesh
    // Make offset mesh
    float offset = mesh.computeBoundingBox().diagonal() * 0.1f;
    auto meshRes = MR::generalOffsetMesh( mesh, offset, params );
    if ( !meshRes.has_value() )
    {
    std::cerr << meshRes.error() << std::endl;
    return 1;
    }
    // Save result
    if ( auto saveRes = MR::MeshSave::toAnySupportedFormat( *meshRes, "mesh_offset.stl" ); !saveRes )
    {
    std::cerr << saveRes.error() << std::endl;
    return 1;
    }
    return 0;
    }
    int main()
    Definition LaplacianDeformation.cpp:4
    Source mesh
    After offset
  • Python
    import meshlib.mrmeshpy as mrmeshpy
    import sys
    # Load mesh
    mesh = mrmeshpy.loadMesh("mesh.stl")
    # Setup parameters
    params = mrmeshpy.OffsetParameters()
    params.voxelSize = mesh.computeBoundingBox().diagonal() * 5e-3 # offset grid precision (algorithm is voxel based)
    if mrmeshpy.findRightBoundary(mesh.topology).empty():
    params.signDetectionMode = mrmeshpy.SignDetectionMode.HoleWindingRule # use if you have holes in mesh
    # Make offset mesh
    offset = mesh.computeBoundingBox().diagonal() * 0.05
    try:
    result_mesh = mrmeshpy.offsetMesh(mesh, offset, params)
    except ValueError as e:
    print(e)
    sys.exit(1)
    # Save result
    mrmeshpy.saveMesh(result_mesh, "offsetMesh.stl")
    Source mesh
    After offset
  • C
    #include <MRCMesh/MRAffineXf.h>
    #include <MRCMesh/MRBox.h>
    #include <MRCMesh/MRCube.h>
    #include <MRCMesh/MRMesh.h>
    #include <MRCMesh/MRMeshPart.h>
    #include <MRCMesh/MRMeshSave.h>
    #include <MRCMesh/MRString.h>
    #include <MRCMesh/MRVector3.h>
    #include <MRCMisc/expected_MR_Mesh_std_string.h>
    #include <MRCMisc/expected_void_std_string.h>
    #include <MRCMisc/std_string.h>
    #include <MRCVoxels/MROffset.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define APPROX_VOXEL_COUNT 10000000.f
    int main( void )
    {
    int rc = EXIT_FAILURE;
    // Create mesh
    MR_Vector3f size = MR_Vector3f_diagonal( 1.f );
    MR_Vector3f base = MR_Vector3f_diagonal( -0.5f );
    MR_Mesh* mesh = MR_makeCube( &size, &base );
    // offset functions can also be applied to separate mesh components rather than to the whole mesh
    // this is not our case, so the region is set to NULL
    MR_MeshPart* inputMeshPart = MR_MeshPart_Construct( mesh, NULL );
    // Setup parameters
    MR_OffsetParameters* params = MR_OffsetParameters_DefaultConstruct();
    // calculate voxel size depending on desired accuracy and/or memory consumption
    MR_BaseShellParameters_Set_voxelSize( MR_OffsetParameters_MutableUpcastTo_MR_BaseShellParameters( params ), MR_suggestVoxelSize( inputMeshPart, 10000000.f ) );
    MR_Box3f bbox = MR_Mesh_computeBoundingBox_1( mesh, NULL );
    float offset = MR_Box3f_diagonal( &bbox ) * 0.1f;
    // Make offset mesh
    MR_expected_MR_Mesh_std_string* outputMeshEx = MR_offsetMesh( inputMeshPart, offset, params );
    MR_MeshPart_Destroy( inputMeshPart );
    MR_OffsetParameters_Destroy( params );
    MR_Mesh* outputMesh = MR_expected_MR_Mesh_std_string_value_mut( outputMeshEx );
    if ( !outputMesh )
    {
    fprintf( stderr, "Failed to perform offset: %s", MR_std_string_data( MR_expected_MR_Mesh_std_string_error( outputMeshEx ) ) );
    goto fail_offset;
    }
    // Save result
    MR_expected_void_std_string* saveEx = MR_MeshSave_toAnySupportedFormat_3( outputMesh, "mesh_offset.stl", NULL, NULL);
    if ( MR_expected_void_std_string_error( saveEx ) )
    {
    fprintf( stderr, "Failed to save mesh: %s\n", MR_std_string_data( MR_expected_void_std_string_error( saveEx ) ) );
    goto fail_save;
    }
    rc = EXIT_SUCCESS;
    fail_save:
    MR_expected_void_std_string_Destroy( saveEx );
    fail_offset:
    MR_expected_MR_Mesh_std_string_Destroy( outputMeshEx );
    MR_Mesh_Destroy( mesh );
    return rc;
    }
    Source mesh
    After offset
  • C#
    using System.Globalization;
    using System.Reflection;
    public class MeshOffsetExample
    {
    public static void Run(string[] args)
    {
    if (args.Length != 2)
    {
    Console.WriteLine("Usage: {0} MeshOffsetExample OFFSET_VALUE", Assembly.GetExecutingAssembly().GetName().Name);
    return;
    }
    try
    {
    float offsetValue = float.Parse(args[1],
    System.Globalization.NumberStyles.AllowDecimalPoint,
    CultureInfo.InvariantCulture);
    // Load mesh
    var mesh = MR.MeshLoad.fromAnySupportedFormat("mesh.stl");
    MR.MeshPart mp = new(mesh);
    // Setup parameters
    MR.OffsetParameters op = new();
    op.voxelSize = MR.suggestVoxelSize(mp, 1e6f);
    // Make offset mesh
    var result = MR.offsetMesh(mp, offsetValue, op);
    // Save result
    MR.MeshSave.toAnySupportedFormat(result, "mesh_offset.stl");
    }
    catch (Exception e)
    {
    Console.WriteLine("Error: {0}", e.Message);
    }
    }
    }
    Source mesh
    After offset