Pycork – A Mesh Boolean CSG Library for Python

PyCork is a Python Mesh Boolean CSG Library for 3D triangular meshes built upon the Cork library that is cross-platform solution for performing operations on Triangular meshes typically used but not limited for Additive Manufacturing applications.

Updates (Dec 2023):

Having recently tried Manifold3D – I would highly recommend those performing 3D boolean meshing operations consider this library, which has native python bindings available on PyPi. Performance is considerably improved (multi-threaded) and due to the use of floating-point precision offers reliable intersection and robust meshes. Note for those working with the library, they should ensure that their meshes are fully watertight, with correct normal orientation of their meshes. PyCork and the underlying Cork library will not be maintained apart for reference for those interested in using this on their projects separately. PySLM will switch to using the Manifold3D library in future.

Background

A long source of frustration on the PySLM and many other small 3D printing projects in the past was access to a relatively fast, portable and accessible 3D boolean CSG library for triangular meshes. Freshly released, PyCork, is a library that builds – or refactors, the pre-existing Cork library into a accessible form with bindings from within Python.

There are now pre-compiled packages available for Windows on PyPi and additionally it can be relatively easily compiled on Linux platforms meeting all the typical dependencies (eigen, mpir).

Usage

The library interface is simple and doesn’t include any additional bells and whistles. For each function in pycork, the user provides a numpy list of triangular vertices and indices that can be obtained directly from trimesh, without any cumbersome conversion and transfers to external files.

import numpy as np
import trimesh

import pycork

# Note any manifold, watertight mesh can be used in conjuction with the Trimesh library
meshA = trimesh.load_mesh('meshA.off')
meshB = trimesh.load_mesh('meshB.off')

# Extra list of vertices and triangular faces from the meshes
vertsA = meshA.vertices
trisA = meshA.faces

vertsB = meshB.vertices
trisB = meshB.faces

pycork.isSolid(vertsA, trisA)
pycork.isSolid(vertsB, trisB)

#Perform the boolean opertions directly with Cork library
vertsC, trisC = pycork.union(vertsA, trisA,
                             vertsB, trisB)

vertsD, trisD = pycork.intersection(vertsA, trisA,
                                    vertsB, trisB)


meshC = trimesh.Trimesh(vertices=vertsC, faces=trisC, process=True)

Motivation

There were many outstanding reasons that provided the initiative to go ahead and partially recreate this library. During the development of the support structure module in PySLM, to performing boolean operations on meshes a boolean CSG library was required. Through, benchmarking, the Cork library was identified as having a promising compromise between accuracy and speed. Additionally, for research projects there was no robust means for performing direct boolean operations between multiple meshes, without using commercial software such as Magics, Netfabb or Meshmixer. The latter had various issues and resampled the mesh and for experience was inconsistently un-reliable. Alternative solutions were re-sampling meshes into voxel model or level sets and then combining them together.

In PySLM, boolean CSG is used for providing exactly trimmed support structure volumes that exactly conform to the original part.

Generated support structure volume that conforms with the boundary of the original mesh

Under some circumstances, BRep CAD geometry can directly provide exact conforming boolean operations, but its performance suffers with more complex models. Also, it puts hard dependencies on the PySLM library, something intentionally avoided to remain exclusively opensource. Further explanations of its usage will be followed up in future posts detailing the method of generating support structures.

Development

During the development of the PySLM support module, compiling the Cork library on Linux is fairly straightforward and it only has the dependency of the GMP library, a numerical library for representing high precision numbers, that is pre-compiled and distributed across most Linux distributions. However, on Windows platforms, this is another story. MPIR is the Windows equivalent of GMP, that has pre-compuled solutions to compile with MSVC but it is not straight forward to compile and link separately with the Cork library. The process of compiling the Cork library is definitely possible, but is cumbersome to do for most users and is challenging to automate using a cross-platform build-service for generating packages.

Even compiling the library, only the command-line version of the Cork Library is available. The command line version requires exporting the meshes to the .off file format – essentially a list of triangles and vertices, similar to STL. It is possible to export to this file format using the Trimesh Python library, but it becomes a tedious operation to perform before the actual boolean operation each time. Ultimately, a better solution is to offer a fully compliable solution that may be used directly in Python.

Work was done to refactor and re-organise some of the original Cork libraries and provide a more robust packaging for use with CMake. The second part of the work involved integrating the MPIR library directly into the sources and integrating fixes to compile for 64 bit platforms on Windows directly within the project.

Finally, python bindings are generated using the Pybind library. This was actually the easiest part.

Outlook

It is unlikely, further work will be done to improve the library, except for further auditing and tidying up existing code, unless there is significant interest to modernise and simplify the codebase. Hopefully, the library assists many users working with meshes and performing boolean CSG operations in the work in many areas including research into 3D Printing.

Leave a Reply

Your email address will not be published. Required fields are marked *