Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
    Michael Dawson-Haggerty
    which face?
    Tobias Dünser
    the upper one
    Michael Dawson-Haggerty
    you could do something like
    In [1]: import trimesh
    In [2]: m = trimesh.creation.box()
    In [3]: m
    Out[3]: <trimesh.base.Trimesh at 0x7effccdba710>
    In [4]: m.vertices
    TrackedArray([[-0.5, -0.5, -0.5],
                  [-0.5, -0.5,  0.5],
                  [-0.5,  0.5, -0.5],
                  [-0.5,  0.5,  0.5],
                  [ 0.5, -0.5, -0.5],
                  [ 0.5, -0.5,  0.5],
                  [ 0.5,  0.5, -0.5],
                  [ 0.5,  0.5,  0.5]])
    In [6]: import numpy as np
    In [7]: at_extrema = np.isclose(m.vertices[:,2], m.vertices[:,2].max())
    In [8]: at_extrema
    Out[8]: TrackedArray([False,  True, False,  True, False,  True, False,  True])
    In [10]: at_extrema[m.faces]
    TrackedArray([[ True,  True, False],
                  [False,  True, False],
                  [False,  True, False],
                  [False, False, False],
                  [ True,  True,  True],
                  [ True,  True, False],
                  [ True,  True,  True],
                  [ True,  True, False],
                  [False, False, False],
                  [False,  True, False],
                  [False,  True, False],
                  [ True,  True, False]])
    In [11]: at_extrema[m.faces].all(axis=1)
    TrackedArray([False, False, False, False,  True, False,  True, False,
                  False, False, False, False])
    In [12]: top = at_extrema[m.faces].all(axis=1)
    In [13]: m.visual.face_colors[top] = [255,0,0,255]
    In [14]: m.show()
    or you could check the face normals of the mesh
    but relying on order is probably kind of flaky
    Tobias Dünser
    Michael Dawson-Haggerty
    Xiuming Zhang
    @mikedh hey Mike! Great work. I have a question that I feel better suited here rather than as a github issue: I wonder how obj.ray.intersects_location (the pyembree one) works under the hood; does it cache the tree in obj, or does it recompute the tree every time obj.ray.intersects_location gets called?
    I guess should be the former, but just want to double check. In my case, I call obj.ray.intersects_location() multiple times on the same object obj. Do I need to worry about the recomputation of the tree, or is it take care of under the hood?
    Hi, is there a way to merge all the meshes in a Trimesh object (that is a list of meshes) into a single mesh object? something like reverse of split?
    I see that obj files with multiple part sometimes load as a list of mesh objects but in case of some files as a single mesh object!
    Dvir Ginzburg
    Am I missing the documentation?
    Tried to find it under docs / examples but some of the links are broken.
    Michael Dawson-Haggerty
    hey, it's built into: https://trimsh.org/
    Dvir Ginzburg
    I don't want to open github issues just because
    Michael Dawson-Haggerty
    @hoosha you can try trimesh.util.concatentate:
    In [1]: import trimesh
    In [2]: m = [trimesh.primitives.Sphere() for i in range(10)]
    In [3]: m
    [<trimesh.primitives.Sphere at 0x7fe317ff0ef0>,
     <trimesh.primitives.Sphere at 0x7fe317782080>,
     <trimesh.primitives.Sphere at 0x7fe3177822e8>,
     <trimesh.primitives.Sphere at 0x7fe317782550>,
     <trimesh.primitives.Sphere at 0x7fe3177827b8>,
     <trimesh.primitives.Sphere at 0x7fe317782a20>,
     <trimesh.primitives.Sphere at 0x7fe317782c88>,
     <trimesh.primitives.Sphere at 0x7fe317782ef0>,
     <trimesh.primitives.Sphere at 0x7fe317787198>,
     <trimesh.primitives.Sphere at 0x7fe317787400>]
    In [4]: trimesh.util.concatenate(m)
    Out[4]: <trimesh.base.Trimesh at 0x7fe317742f28>
    Dvir Ginzburg
    @mikedh thanks a lot, trimesh is absolutely amazing.
    I'm trying to implement the LBO operator on python,
    Michael Dawson-Haggerty
    no worries, and thanks!
    Dvir Ginzburg
    I'm trying to implement the LBO operator on python, https://en.m.wikipedia.org/wiki/Laplace%E2%80%93Beltrami_operator,
    And I need to compute the laplacian of the mesh (mass and stiffness matrices),
    I see that you use the laplacian as part of some of the modules.
    Is there a way to explicitly extract those in trimesh?
    Michael Dawson-Haggerty
    well, there's mesh.moment_inertia
    Mihai ANDRIES
    Hello! I hope you are doing well. I cannot import Trimesh in python 2.7.12 on Ubuntu 16.04. Can anyone help me with this issue? Thanks!
    Mihai ANDRIES
    @mikedh Thanks for solving the issue! It works now!
    Douglas Lemos
    i have error
    File "/usr/local/lib/python3.6/site-packages/trimesh/path/path.py", line 1311, in simplify_spline
    TypeError: simplify_spline() got an unexpected keyword argument 'path_indexes'
    a = trimesh.load_path(cycloidal_profile(count_pin=count_pin,
    count_cam=count_pin - 1,
    # replace the polyline entity with a bajillion points with a
    # tightly fit B-Spline
    a = a.simplify_spline(smooth=1e-6)
    Michael Dawson-Haggerty
    ah @dougwdl_twitter that's a bug, fixed in mikedh/trimesh@0cf1b22
    Hello, I have a project where I need to compute line segment vs. mesh intersection, accounting for visibility. Each line segment should be transformed in 0, 1 or more segments where, assuming a projection direction (eg. z axis), including the part of the segment that is in front of the mesh and the parts that are not overlapping with the mesh, excluding both the part that is inside the mesh (assuming its watertight) and the part that is "behind" the mesh (along projection axis). Basically, I'm trying to "render" line segments into vector data (not raster), accounting for opaque meshes in the scene. I'm very new to Trimesh, is there an easy way to achieve this?
    I assume ray-mesh intersection is where to start, but I would then have to somehow subtract the silhouette of the mesh from the segment part that is behind.
    Jesse Vander Does
    Does anyone know whether the collision manager considers an object fully contained by another a hit?
    Jesse Vander Does
    To be more specific, I'm trying to slide a box collider over a scene and find which meshes or are within it. Here is my sample code
    import numpy as np
    import trimesh
    debug_material = trimesh.visual.material.PBRMaterial(baseColorFactor=np.array((255,0,0,80), dtype=np.uint), alphaMode='BLEND')
    scene = trimesh.load_mesh('./data/simple.glb')
    scene_bounds = scene.bounding_box
    max_bounds = scene_bounds.extents.min()
    box_count = 2
    grid_width = int(max_bounds/box_count)
    grid = scene_bounds.sample_grid(step=grid_width)
    cm, _ = trimesh.collision.scene_to_collision(scene)
    # Sliding box collider
    box = trimesh.primitives.Box()
    cm.add_object('selection', box)
    # List of unique objects that were hit
    was_hit = set([])
    for g in grid:
        matrix = np.eye(4)
        matrix[:3, 3] = np.array(g)
        debug_box = box.copy()
        debug_box.visual.material = debug_material
        hit, hit_list, l = cm.in_collision_single(box, transform=matrix, return_names=True, return_data=True)
        if hit:
            for item in hit_list:
                if item is not 'selection':
                    mesh_name = scene.graph.get(item)[1]
                    if item not in was_hit:
    scene.export(file_obj=open('/tmp/debug.glb', 'wb'), file_type='glb')
    print('Total hit %s' % len(was_hit))
    print('Total geo %s' % len(scene.geometry))
    And here is the sample GLB I'm using
    Only 10 mesh are hit, but there are 16 in the scene. Initially, I thought it was missing objects that were fully enclosed by the box collider, but, but I'm finding to two large objects that should intersect multiple times also do not register.
    My gut tells me that my "debug" object is not accurately representing the CollissionManager transform, but I can't figure out what I'm doing wrong.
    how can we add a mesh to another mesh ?
    Use + to add two meshes!
    mesh1 = mesh1 + mesh2
    hello, I was checkin the example of gauss curvature
    gauss = np.array([discrete_gaussian_curvature_measure(mesh, mesh.vertices, r)/sphere_ball_intersection(1, r) for r in radii])
    why is the division of sphere_ball_intersection ?
    Tobias Vitt
    Hey, Is there a way to colorise a VoxelGrid? After applying voxelize(d) the colors of the mesh are gone.
    Andrew Annex
    hey all, I am running into an issue with ray.intersects_location returning much larger distances than expected between two meshes. I first use closest_point to find points on the lower surface of interest and the indexes for the normals. then use ray.intersects_location with those lower surface points using the closes face normals to those points from the index returned by closest_point. I can tell something is off because if I explicitly set the normals to be [0,0,1], ray.intersects_location return points with different x and y coordinates then the ray origins (the rays should be orthogonal to the xy axis plane). am I missing something?
    uh was gonan ask something but lets wait until the questions above are answered :)