Quick Start ============= A simple example showing various properties of `Trimesh` objects. .. code:: ipython3 import numpy as np import trimesh .. code:: ipython3 # load a file by name or from a buffer mesh = trimesh.load_mesh("../models/featuretype.STL") # to keep the raw data intact, disable any automatic processing # mesh = trimesh.load_mesh('../models/featuretype.STL', process=False) .. code:: ipython3 # is the current mesh watertight? mesh.is_watertight .. parsed-literal:: True .. code:: ipython3 # what's the euler number for the mesh? mesh.euler_number .. parsed-literal:: -16 .. code:: ipython3 # 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 hull np.divide(mesh.volume, mesh.convex_hull.volume) .. parsed-literal:: np.float64(0.7792407744466933) .. code:: ipython3 # since the mesh is watertight, it means there is a # volumetric center of mass which we can set as the origin for our mesh mesh.vertices -= mesh.center_mass .. code:: ipython3 # what's the moment of inertia for the mesh? mesh.moment_inertia .. parsed-literal:: array([[ 6.93059627e+00, -1.43877613e-03, -1.49424850e-01], [-1.43877613e-03, 2.19191960e+01, -1.25194047e-04], [-1.49424850e-01, -1.25194047e-04, 2.62344872e+01]]) .. code:: ipython3 # 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 mesh mesh.split() .. parsed-literal:: [] .. code:: ipython3 # preview mesh in a pyglet window from a terminal, or inline in a notebook mesh.show() .. raw:: html
.. code:: ipython3 # facets are groups of coplanar adjacent faces # set each facet to a random color # colors are 8 bit RGBA by default (n,4) np.uint8 for facet in mesh.facets: mesh.visual.face_colors[facet] = trimesh.visual.random_color() .. code:: ipython3 # transform method can be passed a (4,4) matrix and will cleanly apply the transform mesh.apply_transform(trimesh.transformations.random_rotation_matrix()) .. parsed-literal:: .. code:: ipython3 # an axis aligned bounding box is available mesh.bounding_box.primitive.extents .. parsed-literal:: TrackedArray([5.13122855, 2.5394607 , 2.70894972]) .. code:: ipython3 # a minimum volume oriented bounding box is available mesh.bounding_box_oriented.primitive.extents .. parsed-literal:: TrackedArray([1.375, 2.5 , 5. ]) .. code:: ipython3 mesh.bounding_box_oriented.primitive.transform .. parsed-literal:: TrackedArray([[ 0.01669666, -0.04843966, 0.99868655, -0.01022185], [ 0.77833983, -0.62634193, -0.04339246, -0.11093985], [ 0.62762117, 0.77804202, 0.0272447 , -0.0898661 ], [ 0. , 0. , 0. , 1. ]]) .. code:: ipython3 # the bounding box is a trimesh.primitives.Box object, which subclasses # Trimesh and lazily evaluates to fill in vertices and faces when requested mesh.bounding_box_oriented.show() .. raw:: html
.. code:: ipython3 # 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. ( mesh.bounding_box_oriented.volume, mesh.bounding_cylinder.volume, mesh.bounding_sphere.volume, ) .. parsed-literal:: (17.187500000000014, np.float64(33.76171792862316), 95.89438997522068)