Package: trimesh
Trimesh is a pure Python 3.7+ library for loading and usingtriangular mesheswith an emphasis on watertight surfaces. The goal of the library is to provide a full featured and well tested Trimesh object which allows for easy manipulation and analysis, in the style of the Polygon object in theShapely library.The API is mostly stable, but this should not be relied on and is not guaranteed: install a specific version if you plan on deploying something using trimesh.Pull requests are appreciated and responded to promptly! If you'd like to contribute, here is anup to date list of potential enhancementsalthough things not on that list are also welcome. Here's a quickdevelopment and contributing guide.Basic InstallationKeepingtrimesheasy to install is a core goal, thus theonlyhard dependency isnumpy. Installing other packages adds functionality but is not required. For the easiest install with just numpy,pipcan generally installtrimeshcleanly on Windows, Linux, and OSX:pipinstalltrimeshThe minimal install can load many supported formats (STL, PLY, GLTF/GLB) into numpy arrays. More functionality is available when soft dependencies are installed. This includes things like convex hulls (scipy), graph operations (networkx), faster ray queries (embreex), vector path handling (shapelyandrtree), XML formats like 3DXML/XAML/3MF (lxml), preview windows (pyglet), faster cache checks (xxhash), etc. To installtrimeshwith the soft dependencies that generally install cleanly on Linux, OSX, and Windows usingpip:pipinstalltrimesh[easy]Further information is available in theadvanced installation documentation.Quick StartHere is an example of loading a mesh from file and colorizing its faces. Here is a nicely formattedipython notebook versionof this example. Also check out thecross section example.importnumpyasnpimporttrimesh# attach to logger so trimesh messages will be printed to consoletrimesh.util.attach_to_log()# mesh objects can be created from existing faces and vertex datamesh=trimesh.Trimesh(vertices=[[0,0,0],[0,0,1],[0,1,0]],faces=[[0,1,2]])# by default, Trimesh will do a light processing, which will# remove any NaN values and merge vertices that share position# if you want to not do this on load, you can pass `process=False`mesh=trimesh.Trimesh(vertices=[[0,0,0],[0,0,1],[0,1,0]],faces=[[0,1,2]],process=False)# some formats represent multiple meshes with multiple instances# the loader tries to return the datatype which makes the most sense# which will for scene-like files will return a `trimesh.Scene` object.# if you *always* want a straight `trimesh.Trimesh` you can ask the# loader to "force" the result into a mesh through concatenationmesh=trimesh.load('models/CesiumMilkTruck.glb',force='mesh')# mesh objects can be loaded from a file name or from a buffer# you can pass any of the kwargs for the `Trimesh` constructor# to `trimesh.load`, including `process=False` if you would like# to preserve the original loaded data without merging vertices# STL files will be a soup of disconnected triangles without# merging vertices however and will not register as watertightmesh=trimesh.load('../models/featuretype.STL')# is the current mesh watertight?mesh.is_watertight# what's the euler number for the mesh?mesh.euler_number# the convex hull is another Trimesh object that is available as a property# lets compare the volume of our mesh with the volume of its convex hullprint(mesh.volume/mesh.convex_hull.volume)# since the mesh is watertight, it means there is a# volumetric center of mass which we can set as the origin for our meshmesh.vertices-=mesh.center_mass# what's the moment of inertia for the mesh?mesh.moment_inertia# if there are multiple bodies in the mesh we can split the mesh by# connected components of face adjacency# since this example mesh is a single watertight body we get a list of one meshmesh.split()# facets are groups of coplanar adjacent faces# set each facet to a random color# colors are 8 bit RGBA by default (n, 4) np.uint8forfacetinmesh.facets:mesh.visual.face_colors[facet]=trimesh.visual.random_color()# preview mesh in an opengl window if you installed pyglet and scipy with pipmesh.show()# transform method can be passed a (4, 4) matrix and will cleanly apply the transformmesh.apply_transform(trimesh.transformations.random_rotation_matrix())# axis aligned bounding box is availablemesh.bounding_box.extents# a minimum volume oriented bounding box also available# primitives are subclasses of Trimesh objects which automatically generate# faces and vertices from data stored in the 'primitive' attributemesh.bounding_box_oriented.primitive.extentsmesh.bounding_box_oriented.primitive.transform# show the mesh appended with its oriented bounding box# the bounding box is a trimesh.primitives.Box object, which subclasses# Trimesh and lazily evaluates to fill in vertices and faces when requested# (press w in viewer to see triangles)(mesh+mesh.bounding_box_oriented).show()# bounding spheres and bounding cylinders of meshes are also# available, and will be the minimum volume version of each# except in certain degenerate cases, where they will be no worse# than a least squares fit version of the primitive.print(mesh.bounding_box_oriented.volume,mesh.bounding_cylinder.volume,mesh.bounding_sphere.volume)FeaturesImport meshes from binary/ASCII STL, Wavefront OBJ, ASCII OFF, binary/ASCII PLY, GLTF/GLB 2.0, 3MF, XAML, 3DXML, etc.Import and export 2D or 3D vector paths from/to DXF or SVG filesImport geometry files using the GMSH SDK if installed (BREP, STEP, IGES, INP, BDF, etc)Export meshes as binary STL, binary PLY, ASCII OFF, OBJ, GLTF/GLB 2.0, COLLADA, etc.Export meshes using the GMSH SDK if installed (Abaqus INP, Nastran BDF, etc)Preview meshes using pyglet or in- line in jupyter notebooks using three.jsAutomatic hashing of numpy arrays for change tracking using MD5, zlib CRC, or xxhashInternal caching of computed values validated from hashesCalculate face adjacencies, face angles, vertex defects, etc.Calculate cross sections, i.e. the slicing operation used in 3D printingSlice meshes with one or multiple arbitrary planes and return the resulting surfaceSplit mesh based on face connectivity using networkx, graph-tool, or scipy.sparseCalculate mass properties, including volume, center of mass, moment of inertia, principal components of inertia vectors and componentsRepair simple problems with triangle winding, normals, and quad/tri holesConvex hulls of meshesCompute rotation/translation/tessellation invariant identifier and find duplicate meshesDetermine if a mesh is watertight, convex, etc.Uniformly sample the surface of a meshRay-mesh queries including location, triangle index, etc.Boolean operations on meshes (intersection, union, difference) using Manifold3D or Blender Note that mesh booleans in general are usually slow and unreliableVoxelize watertight meshesVolume mesh generation (TETgen) using Gmsh SDKSmooth watertight meshes using laplacian smoothing algorithms (Classic, Taubin, Humphrey)Subdivide faces of a meshApproximate minimum volume oriented bounding boxes for meshesApproximate minimum volume bounding spheresCalculate nearest point on mesh surface and signed distanceDetermine if a point lies inside or outside of a well constructed mesh using signed distancePrimitive objects (Box, Cylinder, Sphere, Extrusion) which are subclassed Trimesh objects and have all the same features (inertia, viewers, etc)Simple scene graph and transform tree which can be rendered (pyglet window, three.js in a jupyter notebook,pyrender) or exported.Many utility functions, like transforming points, unitizing vectors, aligning vectors, tracking numpy arrays for changes, grouping rows, etc.ViewerTrimesh includes an optionalpygletbased viewer for debugging and inspecting. In the mesh view window, opened withmesh.show(), the following commands can be used:mouse click + dragrotates the viewctl + mouse click + dragpans the viewmouse wheelzoomszreturns to the base viewwtoggles wireframe modectoggles backface cullinggtoggles an XY grid with Z set to lowest pointatoggles an XYZ-RGB axis marker between: off, at world frame, or at every frame and world, and at every frameftoggles between fullscreen and windowed modemmaximizes the windowqcloses the windowIf called from inside ajupyternotebook,mesh.show()displays an in-line preview usingthree.jsto display the mesh or scene. For more complete rendering (PBR, better lighting, shaders, better off-screen support, etc)pyrenderis designed to interoperate withtrimeshobjects.Projects Using TrimeshYou can check out theGithub networkfor things using trimesh. A select few:Nvidia'skaolinfor deep learning on 3D geometry.Cura, a popular slicer for 3D printing.Berkeley'sDexNet4and relatedambidextrous.aiwork with robotic grasp planning and manipulation.Kerfed'sKerfed's Enginefor analyzing assembly geometry for manufacturing.MyMiniFactory'sP2Slice for preparing models for 3D printing.pyrenderA library to render scenes from Python using nice looking PBR materials.urdfpyLoad URDF robot descriptions in Python.moderngl-windowA helper to create GL contexts and load meshes.vedoVisualize meshes interactively (see examplegallery).FSLeyesView MRI images and brain data.Which Mesh Format Should I Use?Quick recommendation:GLBorPLY. Every time you replaceOBJwithGLBan angel gets its wings.If you want things like by-index faces, instancing, colors, textures, etc,GLBis a terrific choice. GLTF/GLB is anextremely well specifiedmodern format that is easy and fast to parse: it has a JSON header describing data in a binary blob. It has a simple hierarchical scene graph, a great looking modern physically based material system, support indozens-to-hundreds of libraries, and aJohn Carmack endorsment. Note that GLTF is a large specification, andtrimeshonly supports a subset of features: loading basic geometry is supported, NOT supported are fancier things like animations, skeletons, etc.In the wild,STLis perhaps the most common format.STLfiles are extremely simple: it is basically just a list of triangles. They are robust and are a good choice for basic geometry. BinaryPLYfiles are a good step up, as they support indexed faces and colors.WavefrontOBJis also pretty common: unfortunately OBJ doesn't have a widely accepted specification so every importer and exporter implements things slightly differently, making it tough to support. It also allows unfortunate things like arbitrary sized polygons, has a face representation which is easy to mess up, references other files for materials and textures, arbitrarily interleaves data, and is slow to parse. GiveGLBorPLYa try as an alternative!How can I cite this library?A question that comes up pretty frequently ishow to cite the library.A quick BibTex recommendation:@software{trimesh,
	author = {{Dawson-Haggerty et al.}},
	title = {trimesh},
	url = {https://trimesh.org/},
	version = {3.2.0},
	date = {2019-12-8},
}ContainersIf you want to deploy something in a container that uses trimesh automateddebian:slim-bullseyebased builds with trimesh and most dependencies are available onDocker Hubwith image tags forlatest, git short hash for the commit inmain(i.e.trimesh/trimesh:0c1298d), and version (i.e.trimesh/trimesh:3.5.27):docker pull trimesh/trimeshHere's an exampleof how to render meshes using LLVMpipe and XVFB inside a container.