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
    // Setup parameters
    // 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
    MR::MeshSave::toAnySupportedFormat( *meshRes, "mesh_offset.stl" );
    return 0;
    }
    MRMESH_API Expected< void > toAnySupportedFormat(const Mesh &mesh, const std::filesystem::path &file, const SaveSettings &settings={})
    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)
    MRMESH_API Mesh makeCube(const Vector3f &size=Vector3f::diagonal(1.0f), const Vector3f &base=Vector3f::diagonal(-0.5f))
    MRMESH_API Box3f computeBoundingBox(const AffineXf3f *toWorld=nullptr) const
    MeshTopology topology
    SignDetectionMode signDetectionMode
    Source mesh
    After offset
  • Python
    import meshlib.mrmeshpy as mrmeshpy
    import sys
    # Load mesh
    mesh = mrmeshpy.loadMesh("mesh.stl")
    # Setup parameters
    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")
    None saveMesh(Mesh mesh, os.PathLike|str|bytes file, SaveSettings settings='{}')
    Mesh offsetMesh(MeshPart mp, float offset, OffsetParameters params='{}')
    std_vector_std_vector_Id_EdgeTag findRightBoundary(MeshTopology topology, FaceBitSet region=None)
    Mesh loadMesh(os.PathLike|str|bytes file, MeshLoadSettings settings='{}')
    Source mesh
    After offset
  • C
    #include <MRMeshC/MRMesh.h>
    #include <MRMeshC/MRCube.h>
    #include <MRMeshC/MRVector3.h>
    #include <MRMeshC/MRBox.h>
    #include <MRMeshC/MRAffineXf.h>
    #include <MRMeshC/MRMeshSave.h>
    #include <MRMeshC/MROffset.h>
    #include <MRMeshC/MRString.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define APPROX_VOXEL_COUNT 10000000.f
    int main( int argc, char* argv[] )
    {
    int rc = EXIT_FAILURE;
    // error messages will be stored here
    MRString* errorString = NULL;
    // Create mesh
    MRVector3f base = mrVector3fDiagonal( -0.5f );
    MRMesh* mesh = mrMakeCube( &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
    MRMeshPart inputMeshPart = (MRMeshPart){
    .mesh = mesh,
    .region = NULL,
    };
    // Setup parameters
    // calculate voxel size depending on desired accuracy and/or memory consumption
    params.voxelSize = mrSuggestVoxelSize( inputMeshPart, 10000000.f );
    MRBox3f bbox = mrMeshComputeBoundingBox( mesh, &xf );
    float offset = mrBox3fDiagonal( &bbox ) * 0.1f;
    // Make offset mesh
    MRMesh* outputMesh = mrOffsetMesh( inputMeshPart, offset, &params, &errorString );
    if ( errorString )
    {
    fprintf( stderr, "Failed to perform offset: %s", mrStringData( errorString ) );
    mrStringFree( errorString );
    goto out;
    }
    // Save result
    mrMeshSaveToAnySupportedFormat( outputMesh, "mesh_offset.stl", &saveSettings, &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:
    mrMeshFree( mesh );
    return rc;
    }
    MRMESHC_API MRAffineXf3f mrAffineXf3fNew(void)
    MRMESHC_API float mrBox3fDiagonal(const MRBox3f *box)
    MR_EXTERN_C_BEGIN MRMESHC_API MRMesh * mrMakeCube(const MRVector3f *size, const MRVector3f *base)
    struct MRMesh MRMesh
    typedefMR_EXTERN_C_BEGIN struct MRString MRString
    MR_EXTERN_C_BEGIN MRMESHC_API void mrMeshSaveToAnySupportedFormat(const MRMesh *mesh, const char *file, const MRSaveSettings *settings, MRString **errorStr)
    MRMESHC_API MRBox3f mrMeshComputeBoundingBox(const MRMesh *mesh, const MRAffineXf3f *toWorld)
    MRMESHC_API void mrMeshFree(MRMesh *mesh)
    MRMESHC_API MROffsetParameters mrOffsetParametersNew(void)
    MRMESHC_API float mrSuggestVoxelSize(MRMeshPart mp, float approxNumVoxels)
    MRMESHC_API MRSaveSettings mrSaveSettingsNew(void)
    MRMESHC_API void mrStringFree(MRString *str)
    MR_EXTERN_C_BEGIN MRMESHC_API const char * mrStringData(const MRString *str)
    MRMESHC_API MRVector3f mrVector3fDiagonal(float a)
    MRMESHC_API MRMesh * mrOffsetMesh(MRMeshPart mp, float offset, const MROffsetParameters *params, MRString **errorString)
    size_t size() const
    const MRMesh * mesh
    Source mesh
    After offset
  • C#
    using System.Globalization;
    using System.Reflection;
    using static MR.DotNet;
    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
    MeshPart mp = new MeshPart(MeshLoad.FromAnySupportedFormat("mesh.stl"));
    // Setup parameters
    OffsetParameters op = new OffsetParameters();
    op.voxelSize = Offset.SuggestVoxelSize(mp, 1e6f);
    // Make offset mesh
    var result = Offset.OffsetMesh(mp, offsetValue, op);
    // Save result
    MeshSave.ToAnySupportedFormat(result, "mesh_offset.stl");
    }
    catch (Exception e)
    {
    Console.WriteLine("Error: {0}", e.Message);
    }
    }
    }
    Source mesh
    After offset