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

Example of mesh offset

  • C++
    #include <MRMesh/MRBox.h>
    #include <MRMesh/MRMesh.h>
    int main()
    {
    // Load mesh
    // Setup parameters
    params.voxelSize = mesh.computeBoundingBox().diagonal() * 5e-3f; // offset grid precision (algorithm is voxel based)
    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.05f;
    auto meshRes = MR::generalOffsetMesh( mesh, offset, params );
    if ( !meshRes.has_value() )
    {
    // log meshRes.error()
    return 1;
    }
    // Save result
    MR::MeshSave::toAnySupportedFormat( *meshRes, "mesh_offset.stl" );
    return 0;
    }
    MRMESH_API Expected< Mesh > fromAnySupportedFormat(const std::filesystem::path &file, const MeshLoadSettings &settings={})
    detects the format from file extension and loads mesh from it
    MRMESH_API Expected< void > toAnySupportedFormat(const Mesh &mesh, const std::filesystem::path &file, const SaveSettings &settings={})
    detects the format from file extension and save mesh to it
    @ HoleWindingRule
    computes winding number generalization with support of holes in mesh, slower than WindingRule
    MRMESH_API std::vector< EdgeLoop > findRightBoundary(const MeshTopology &topology, const FaceBitSet *region=nullptr)
    MRVOXELS_API Expected< Mesh > generalOffsetMesh(const MeshPart &mp, float offset, const GeneralOffsetParameters &params)
    Offsets mesh by converting it to voxels and back using one of three modes specified in the parameters...
    float voxelSize
    Definition MRVoxels/MROffset.h:18
    allows the user to select in the parameters which offset algorithm to call
    Definition MRVoxels/MROffset.h:97
    Definition MRMesh/MRMesh.h:23
    MRMESH_API Box3f computeBoundingBox(const AffineXf3f *toWorld=nullptr) const
    MeshTopology topology
    Definition MRMesh/MRMesh.h:24
    SignDetectionMode signDetectionMode
    determines the method to compute distance sign
    Definition MRVoxels/MROffset.h:30
  • Python
    import meshlib.mrmeshpy as mrmeshpy
    # 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
    result_mesh = mrmeshpy.offsetMesh(mesh, offset, params)
    # Save result
    mrmeshpy.saveMesh(result_mesh, "offsetMesh.stl")
  • C
    #include <MRMeshC/MRMesh.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define APPROX_VOXEL_COUNT 10000000.f
    // print progress every 10%
    int gProgress = -1;
    bool onProgress( float v )
    {
    int progress = (int)( 10.f * v );
    if ( progress != gProgress )
    {
    gProgress = progress;
    printf( "%d%%...\n", progress * 10 );
    }
    return true;
    }
    int main( int argc, char* argv[] )
    {
    int rc = EXIT_FAILURE;
    if ( argc != 3 && argc != 4 )
    {
    fprintf( stderr, "Usage: %s OFFSET_VALUE INPUT [OUTPUT]", argv[0] );
    goto out;
    }
    float offsetValue = atof( argv[1] );
    if ( !isfinite( offsetValue ) )
    {
    fprintf( stderr, "Incorrect offset value: %s", argv[1] );
    goto out;
    }
    const char* input = argv[2];
    const char* output = ( argc == 3 ) ? argv[2] : argv[3];
    // error messages will be stored here
    MRString* errorString = NULL;
    MRMesh* inputMesh = mrMeshLoadFromAnySupportedFormat( input, &errorString );
    if ( errorString )
    {
    fprintf( stderr, "Failed to load inputMesh: %s", mrStringData( errorString ) );
    mrStringFree( errorString );
    goto out;
    }
    // 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
    MRMeshPart inputMeshPart = (MRMeshPart){
    .mesh = inputMesh,
    .region = NULL,
    };
    // calculate voxel size depending on desired accuracy and/or memory consumption
    params.voxelSize = mrSuggestVoxelSize( inputMeshPart, APPROX_VOXEL_COUNT );
    // set optional progress callback
    params.callBack = onProgress;
    MRMesh* outputMesh = mrOffsetMesh( inputMeshPart, offsetValue, &params, &errorString );
    if ( errorString )
    {
    fprintf( stderr, "Failed to perform offset: %s", mrStringData( errorString ) );
    mrStringFree( errorString );
    goto out_inputMesh;
    }
    mrMeshSaveToAnySupportedFormat( outputMesh, output, &errorString );
    if ( errorString )
    {
    fprintf( stderr, "Failed to save inputMesh: %s", mrStringData( errorString ) );
    mrStringFree( errorString );
    goto out_outputMesh;
    }
    rc = EXIT_SUCCESS;
    out_outputMesh:
    mrMeshFree( outputMesh );
    out_inputMesh:
    mrMeshFree( inputMesh );
    out:
    return rc;
    }
    struct MRMesh MRMesh
    Definition MRMeshC/MRMeshFwd.h:43
    typedefMR_EXTERN_C_BEGIN struct MRString MRString
    Definition MRMeshC/MRMeshFwd.h:32
    MR_EXTERN_C_BEGIN struct MRMeshPart MRMeshPart
    stores reference on whole mesh (if region is NULL) or on its part (if region pointer is valid)
    MRMESHC_API void mrMeshFree(MRMesh *mesh)
    deallocates a Mesh object
    MRMESHC_API MROffsetParameters mrOffsetParametersNew(void)
    initializes a default instance
    MRMESHC_API float mrSuggestVoxelSize(MRMeshPart mp, float approxNumVoxels)
    computes size of a cubical voxel to get approximately given number of voxels during rasterization
    MRMESHC_API void mrStringFree(MRString *str)
    deallocates the string object
    MR_EXTERN_C_BEGIN MRMESHC_API const char * mrStringData(const MRString *str)
    gets read-only access to the string data
    MRMESHC_API MRMesh * mrMeshLoadFromAnySupportedFormat(const char *file, MRString **errorStr)
    MRMESHC_API void mrMeshSaveToAnySupportedFormat(const MRMesh *mesh, const char *file, MRString **errorStr)
    MRMESHC_API MRMesh * mrOffsetMesh(MRMeshPart mp, float offset, const MROffsetParameters *params, MRString **errorString)
    stores reference on whole mesh (if region is NULL) or on its part (if region pointer is valid)
    Definition MRMeshC/MRMeshPart.h:9
    const MRMesh * mesh
    Definition MRMeshC/MRMeshPart.h:10
    Definition MRMeshC/MROffset.h:12
    float voxelSize
    Definition MRMeshC/MROffset.h:15
    MRProgressCallback callBack
    Progress callback.
    Definition MRMeshC/MROffset.h:17
  • C#
    using MR.DotNet;
    using System;
    using System.Globalization;
    using System.Reflection;
    class Program
    {
    static void Main(string[] args)
    {
    if (args.Length != 2 && args.Length != 3)
    {
    Console.WriteLine("Usage: {0} OFFSET_VALUE INPUT [OUTPUT]", Assembly.GetExecutingAssembly().GetName().Name);
    return;
    }
    try
    {
    float offsetValue = float.Parse(args[0],
    System.Globalization.NumberStyles.AllowThousands,
    CultureInfo.InvariantCulture);
    string input = args[1];
    string output = args.Length == 3 ? args[2] : args[1];
    MeshPart mp = new MeshPart();
    mp.mesh = Mesh.FromAnySupportedFormat( args[1] );
    OffsetParameters op = new OffsetParameters();
    op.voxelSize = Offset.SuggestVoxelSize(mp, 1e6f);
    var result = Offset.OffsetMesh(mp, offsetValue, op);
    Mesh.ToAnySupportedFormat(result, output);
    }
    catch (Exception e)
    {
    Console.WriteLine("Error: {0}", e.Message);
    }
    }
    }