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.43835783, 3.93852084, 2.99908528]) .. 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.39739271, -0.25118121, 0.88260242, 0.06370253], [ 0.07836927, -0.94900509, -0.3053647 , 0.00874706], [ 0.91429606, 0.19051861, -0.35744282, 0.12788092], [ 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.18750000000001, np.float64(33.99695806180356), 95.89438997522053)