mikedh / trimesh

Python library for loading and using triangular meshes.

Home Page:https://trimesh.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Select connected faces to a FACET

shayan-nikoo opened this issue · comments

How can I select faces which are connected to a given facet.

From the documentation:

# 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()`

My example:

facets = mesh.facets
facet = facets[0]

# select faces from mesh that are connected to this facet
# I think something like connected_components should do it!!!
cc = trimesh.graph.connected_components(edges=??, min_len=3)

Hey, I think you want to take a look at mesh.face_adjacency:

In [1]: import trimesh

In [2]: m = trimesh.load('models/featuretype.STL')

In [3]: m
Out[3]: <trimesh.Trimesh(vertices.shape=(1722, 3), faces.shape=(3476, 3), name=`featuretype.STL`)>

In [4]: facet = m.facets[0]

In [5]: facet
Out[5]: 
array([  0, 286, ...  134, 133, 132, 130])

In [7]: import numpy as np

In [8]: facet_mask = np.zeros(len(m.faces), dtype=bool)

In [10]: facet_mask[facet] = True

# get pairs of faces where only *one* of them is included in the facet
In [11]: border = facet_mask[m.face_adjacency].sum(axis=1) == 1

In [12]: border.shape
Out[12]: (5214,)

In [14]: border
Out[14]: array([ True, False, False, ..., False, False, False])

In [15]: border.sum()
Out[15]: 374

# (m, 2) indexes of m.faces
In [16]: adjacent = m.face_adjacency[border]

In [21]: other_faces = adjacent.ravel()[~facet_mask[adjacent.ravel()]]

# make the facet blue
In [22]: m.visual.face_colors[facet] = [0,0,255,255]

# border faces red
In [23]: m.visual.face_colors[other_faces] = [255,0,0,255]

In [24]: m.show(smooth=False)

Screenshot from 2024-04-09 14-21-32

Thank you for the answer. In case, my mesh has separated components (bodies), how can I only get the components attached to my facet? Sorry didn't mention it clearly in the beginning. This is why I wanted to use trimesh.graph.connected_components.

Is the below correct?
cc_facet = trimesh.graph.connected_components(edges=m.edges[facet], min_len=4)

min_len should be 4 or 3?

cc_mask = np.zeros(len(m.faces), dtype=np.bool)
cc_mask[np.concatenate(cc_mask)] = True

# make the facet blue
m.visual.face_colors[facet] = [0,0,255,255]

# attached facets red
m.visual.face_colors[cc_mask] = [255,0,0,255]   
m.show(smooth=False)

# create a new mesh from selected cc
cc_m = m.copy()
cc_m.update_faces(cc_mask)

Have you looked at mesh.split? That might be close to what you want.

Yes I tried that, but how can I extract from the split output the component of a given facet?