Boolean geometry subtraction of 3D meshes

Question:

I am parsing a 3D mesh from .obj using pywavefront which gives me vertices, faces and normals.
I want to calculate the remaining area from subtracting another mesh.

Following up on calculating volume I wonder how can I perform operations on the meshes such as intersect and subtract.

Asked By: high_byte

||

Answers:

If I understand correctly, in order to get the volume of your remaining area you should first compute the resulting mesh. This is known as boolean operations which are often implemented on envelopes (surface mesh like in the .obj files)

There is several python modules proposing implementations for boolean operation on meshes.

  • pymesh exposes the algorithms of CGAL (c++ library)
  • pymadcad with a different algorithm in pure python
  • blender which is a complete software but which provide boolean operations in their API
  • trimesh relying on CGAL and Blender

there is few other modules but – as far as I know – all of them are relying on pymesh or blender under the coat.

Answered By: jimy byerley

Just to add to the existing answer, that one more option is to use open-source library MeshLib having Python interface. It can read and write meshes in Wavefront format (.obj) and perform Boolean operations on meshes.

For example, the code for subtracting a torus from a cube is as follows:

import meshlib.mrmeshpy as mr
# create a mesh of cube with edge length =1:
cube = mr.makeCube(size = mr.Vector3f( 1, 1, 1 ))
# create a mesh of torus:
torus = mr.makeTorus( primaryRadius = 0.65, secondaryRadius = 0.1 )
# compute the difference between the cube and the torus:
diff = mr.boolean( cube, torus, mr.BooleanOperation.DifferenceAB )
# save the difference in file:
mr.saveMesh(diff.mesh, mr.Path("diff.obj"))

The difference mesh after opening in some mesh viewer:
enter image description here

Answered By: Fedor

I would like to mention other two very interesting and powerful libraries:

  • pymeshlab: a Python library that interfaces to MeshLab, the popular open source application for editing and processing large 3D triangle meshes.
  • pyvista: a high-level Python API to the Visualization Toolkit (VTK).

Both libraries allows to perform boolean operations between meshes. Let’s consider the intersection between the Stanford bunny (~86k triangles) and a sphere:

enter image description here

The code below compare the intersection and computational time of the two libraries.

from time import perf_counter

import pymeshlab
import pyvista as pv
import trimesh

bunny_path = "bunny.ply"
sphere_path = "sphere.ply"


def pymeshlab_intersection() -> None:

    ms = pymeshlab.MeshSet()
    ms.load_new_mesh(bunny_path)
    ms.load_new_mesh(sphere_path)
    ms.generate_boolean_intersection()
    ms.save_current_mesh("pymeshlab_intersection.ply")
    intersection_volume = ms.get_geometric_measures()["mesh_volume"]
    print(f"pymeshlab - intersection volume = {intersection_volume}")


def pyvista_intersection() -> None:

    bunny = trimesh.load_mesh(bunny_path, process=False, maintain_order=True)
    bunny_pv = pv.wrap(bunny)
    sphere = trimesh.load_mesh(sphere_path, process=False, maintain_order=True)
    sphere_pv = pv.wrap(sphere)
    intersection = bunny_pv.boolean_intersection(sphere_pv)
    intersection.save("pyvista_intersection.ply")
    print(f"pyvista - intersection volume = {intersection.volume}")


if __name__ == "__main__":

    t0 = perf_counter()
    pymeshlab_intersection()
    print(f"pymeshlab: {perf_counter() - t0} s")

    t0 = perf_counter()
    pyvista_intersection()
    print(f"pyvista: {perf_counter() - t0} s")

pymeshlab:

  • intersection volume: 14799.202211491009
  • elapsed time: 2.1220125 s

pyvista:

  • intersection volume: 14799.297891938557
  • elapsed time: 4.3342883 s

So, pymeshlab is twice as fast as pyvista.

Below the resulting mesh created by pymeshlab:
enter image description here

Answered By: blunova
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.