TetWild

repository·master·Indexed 20 days ago

https://github.com/yixin-hu/tetwild

A robust tetrahedral meshing tool designed to generate tetrahedral meshes from input triangle meshes, including noisy geometry or those with inconsistent orientations. It supports input formats .off, .obj, .stl, and .ply, and outputs volume meshes in .msh or .mesh formats. TetWild can be used as a standalone CLI tool, via a Docker image, or integrated into C++ projects using the tetwild.h header wrapper.

Tokens
7.9K
Snippets
21
Records
33
Agent score
72%

What's inside TetWild

  1. Important considerations for input mesh orientation

    master

    TetWild is faithful to the input face positions and orientations. The underlying winding number algorithm requires a reasonably consistent orientation of the input triangle mesh.

    If the input mesh has large regions where faces are inverted (flipped normals), the output tetmesh may have missing parts or include elements 'outside' the surface in those regions. This occurs because inverted faces define the 'inside' as being 'outside'. Ensure your input mesh has consistent face orientations before processing.

  2. Configure TetWild meshing parameters

    master

    You can customize the tetrahedralization process using several parameters to balance mesh quality, density, and computation time:

    • Envelope size (--epsilon / args.eps_rel): Controls feature preservation. Smaller values preserve features better but increase computation time. Default is b/1000 (where b is the bounding box diagonal).
    • Ideal edge length (--ideal-edge-length / args.initial_edge_len_rel): Controls mesh density. Smaller values result in a denser mesh but take longer. Default is b/20.
    • Filtering energy (--filter-energy / args.filter_energy_thres): Determines when optimization stops. Higher values stop sooner with less optimization. Default is 10. Note: For complex inputs, do not set this lower than 8.
    • Maximum optimization passes (--max-pass / args.max_num_passes): The maximum number of improvement passes. Default is 80.
    • Targeted number of vertices (--targeted-num-v / args.target_num_vertices): Attempts to match a specific vertex count with a 5% error tolerance.
    • Sizing field (--bg-mesh / args.background_mesh): Provide a background .msh mesh with a values scalar field to control edge lengths via linear interpolation.
    • Laplacian smoothing (--is-laplacian / args.smooth_open_boundary): Applies Laplacian smoothing to the surface of output holes/gaps to prevent bumpy surfaces.
  3. Hardware requirements and memory usage

    master
    TetWild is designed to be robust for complex models, but it is resource-intensive. The most complex models tested require more than 100GB of memory. If the algorithm crashes on a laptop, try running it on a cluster with significantly more resources.
  4. Install TetWild via CMake (macOS/Linux/Windows)

    master

    You can build TetWild from source using CMake.

    Prerequisites

    On macOS, you may need to install gmp, mpfr, or CGAL via Homebrew:

    brew install gmp
    brew install mpfr
    # OR
    brew install cgal

    Build Steps

    1. Clone the repository:
    git clone https://github.com/Yixin-Hu/TetWild
    1. Compile the code:
    cd TetWild
    mkdir build
    cd build
    cmake ..
    make

    Configuration Options

    • Boost Dependency: If you do not have Boost installed (required for spdlog), enable the CMake option -DTETWILD_WITH_HUNTER=ON to let CMake download and configure Boost automatically using Hunter.
    • ISPC Optimization: To use ISPC for parallel energy computation (which can reduce energy computation time by 50%), install ISPC and set the GTET_ISPC flag to ON in CMakeLists.txt.
    • Non-critical warnings: Warnings regarding Matlab or Mosek during the CMake process can be ignored as they are not used by the application.
  5. Install TetWild via Docker

    master

    To run TetWild without local compilation, use the official Docker image. Ensure you mount your current working directory to /data inside the container so TetWild can access your input files and write output files.

    Note: If the process terminates unexpectedly, it is likely due to Docker's memory limits. Monitor usage with docker stats and increase the allocated memory if necessary.

    docker pull yixinhu/tetwild
    docker run --rm -v "$(pwd)":/data yixinhu/tetwild [TetWild arguments]
  6. Use the TetWild C++ Function Wrapper

    master

    If you want to avoid file I/O or are already using libigl to load meshes, use the tetwild.h header to call the tetrahedralization directly in your C++ code.

    Steps:

    1. Include the header: #include <tetwild/tetwild.h>.
    2. Configure parameters using a tetwild::Args struct.
    3. Call tetwild::tetrahedralization using libigl-style matrices.

    Parameter Mapping:

    Command Line Switchtetwild::Args Member
    --postfixargs.postfix
    --ideal-edge-lengthargs.initial_edge_len_rel
    --epsilonargs.eps_rel
    --stageargs.stage
    --filter-energyargs.filter_energy_thres
    --max-passargs.max_num_passes
    --is-quietargs.is_quiet
    --targeted-num-vargs.target_num_vertices
    --bg-meshargs.background_mesh
    --is-laplacianargs.smooth_open_boundary
    #include <tetwild/tetwild.h>
    #include <Eigen/Core>
    
    // ... load your mesh into v_in and f_in using libigl ...
    
    tetwild::Args args;
    args.eps_rel = 1e-3;
    args.max_num_passes = 80;
    // ... configure other args ...
    
    // v_out, t_out, a_out are output matrices (vertices, tetrahedra, and potentially attributes)
    // Use libigl-style matrices (e.g., Eigen::MatrixXd or Eigen::MatrixXf)
    tetwild::tetrahedralization(v_in, f_in, v_out, t_out, a_out, args);
  7. Configure EdgeCollapser parameters

    master

    The EdgeCollapser class exposes several configuration members to control the refinement behavior:

    • ideal_weight (double): The target weight for edge collapses.
    • is_limit_length (bool): If true, limits the length of edges.
    • is_check_quality (bool): If true, performs quality checks during collapse.
    • envelop_accept_cnt (int): Threshold for envelope acceptance.
    • is_soft (bool): Enables soft energy constraints.
    • soft_energy (double): The value used for soft energy calculations.
    • budget (int): The number of allowed operations or a resource limit.
    • ts (int): Internal state/timestamp used during processing.
  8. Supported Input and Output Formats

    master

    TetWild processes triangle surface meshes and produces tetrahedral meshes.

    Input Formats:

    • .off
    • .obj
    • .stl
    • .ply

    Output Formats:

    • .msh or .mesh (Default is .msh)
    • The default .msh output includes the minimum dihedral angle as an element scalar field, compatible with Gmsh.
    • If the --is-quiet flag is not used, TetWild also outputs the surface of the tetmesh in .obj format.

    For Python users, you can use PyMesh::MshLoader and PyMesh::MshSaver from the pymesh/ library to handle .msh files.

  9. Command Line Interface Reference

    master

    Use the TetWild executable to run the mesher from the terminal.

    Usage:

    ./TetWild [OPTIONS] input [output]

    Positionals:

    • input: Required. Input surface mesh in .off/.obj/.stl/.ply format.
    • output: Optional. Output tetmesh in .msh format. Defaults to input_file_postfix.msh.

    Options:

    -h,--help                   Print this help message and exit
    --input TEXT REQUIRED       Input surface mesh INPUT in .off/.obj/.stl/.ply format. (string, required)
    --output TEXT                Output tetmesh OUTPUT in .msh or .mesh format. (string, optional, default: input_file+postfix+'.msh')
    --postfix TEXT               Postfix P for output files. (string, optional, default: '_')
    -l,--ideal-edge-length FLOAT ideal_edge_length = diag_of_bbox * L. (double, optional, default: 0.05)
    -e,--epsilon FLOAT           epsilon = diag_of_bbox * EPS. (double, optional, default: 1e-3)
    --stage INT                  Run pipeline in stage STAGE. (integer, optional, default: 1)
    --filter-energy FLOAT        Stop mesh improvement when the maximum energy is smaller than ENERGY. (double, optional, default: 10)
    --max-pass INT               Do PASS mesh improvement passes in maximum. (integer, optional, default: 80)
    --is-laplacian               Do Laplacian smoothing for the surface of output on the holes of input (optional)
    --targeted-num-v INT        Output tetmesh that contains TV vertices. (integer, optional, tolerance: 5%)
    --bg-mesh TEXT               Background tetmesh BGMESH in .msh format for applying sizing field. (string, optional)
    --save-mid-result            0: save result before optimization, 1: save mid-results during optimization, 2: save result without winding number.
    -q,--is-quiet               Mute console output. (optional)
    --log TEXT                   Log info to given file.
    --level INT                  Log level (0 = most verbose, 6 = off).
    ./TetWild input.obj output.msh --ideal-edge-length 0.1 --is-laplacian
  10. Use the DelaunayTetrahedralization class for mesh generation

    master

    The DelaunayTetrahedralization class is the core engine for performing Delaunay tetrahedralization within TetWild. It provides methods to initialize the triangulation with surface mesh data, generate voxel points, perform the tetrahedralization process, and output the resulting mesh.

    Key methods include:

    • init: Sets up the triangulation using surface vertices, faces, and associated tags (face tags, edge tags, and connectivity).
    • getVoxelPoints: Generates voxel points within a specified bounding box defined by p_min and p_max.
    • tetra: Executes the main tetrahedralization logic, producing BSP (Binary Space Partitioning) elements like vertices, edges, faces, and nodes.
    • outputTetmesh: Writes the final tetrahedral mesh to a file.
    tetwild::DelaunayTetrahedralization engine;
    
    // Initialize with surface data
    engine.init(m_vertices, m_faces, m_f_tags, raw_e_tags, raw_conn_e4v);
    
    // Perform tetrahedralization
    engine.tetra(m_vertices, geo_surface_mesh, bsp_vertices, bsp_edges, bsp_faces, bsp_nodes, args, state);
    
    // Output the result
    engine.outputTetmesh(m_vertices, cells, "output_file.mesh");
  11. Use the BSPSubdivision class for mesh subdivision

    master

    The BSPSubdivision class provides an interface for performing Binary Space Partitioning (BSP) subdivision on meshes. It requires an existing MeshConformer instance to operate.

    Key workflow steps:

    1. Initialize the subdivision with a MeshConformer reference.
    2. Call init() to prepare the subdivision process.
    3. Call subdivideBSPNodes() to execute the subdivision logic.

    Note: The class maintains a processing_n_ids queue of integer IDs used during the subdivision process.

    #include <tetwild/BSPSubdivision.h>
    #include <tetwild/MeshConformer.h>
    
    tetwild::MeshConformer mc;
    // ... setup mc ...
    
    tetwild::BSPSubdivision bsp(mc);
    bsp.init();
    bsp.subdivideBSPNodes();