Yet another take at drawing trimesh meshes :)
#662
Replies: 5 comments 6 replies
|
This is nice, and I like your implementation better than the one I came up with. This is simpler. |
|
I found a problem with this strategy: It looks like single triangle faces are not considered "facets" and don't have their edges listed in I'd love to have a (simple) solution for this... import py5
import py5_tools
import trimesh
import numpy as np
def setup():
global a, b, c, d, e
py5.size(500, 500, py5.P3D)
a = box_mesh(0, 0, 0, 200)
b = a.copy()
apply_rotation(b, py5.radians(45), direction=(0, 0, 1))
c = a.copy()
apply_rotation(c, py5.radians(45), direction=(0, 1, 0))
apply_rotation(c, py5.radians(45), direction=(1, 0, 0))
d = c.intersection(b)
# Export animation, skip empty frame 0 created on setup
py5_tools.animated_gif('demo_mesh.gif', duration=0.08,
frame_numbers=range(1, 361, 5))
def draw():
py5.background(200, 0, 200)
py5.lights()
py5.translate(py5.width / 2, py5.height / 2)
py5.rotate_x(py5.PI / 8)
py5.rotate_y(py5.radians(py5.frame_count))
py5.stroke_weight(2)
py5.fill(0, 200, 200)
py5.stroke(0)
draw_mesh(d)
if py5.is_key_pressed:
py5.scale(1.01)
py5.no_fill()
py5.stroke(255)
draw_mesh(b)
draw_mesh(c)
def box_mesh(x, y, z, w, h=None, d=None):
h = h or w
d = d or h
mesh = trimesh.creation.box((w, h, d))
mesh.apply_translation((x, y, z))
return mesh
def apply_rotation(mesh, angle, direction=[1, 0, 0], center=[0, 0, 0]):
rot_matrix = trimesh.transformations.rotation_matrix(angle, direction, center)
mesh.apply_transform(rot_matrix)
def draw_mesh(m):
vs = m.vertices
bs = m.facets_boundary
py5.push_style() # To be able to get the stroke settings back
py5.no_stroke() # Turn off strokes, to draw without edges
# Draw triangulated faces without edges
with py5.begin_closed_shape(py5.TRIANGLES):
py5.vertices(vs[np.concatenate(m.faces)])
py5.pop_style() # Get previous stroke settings
# Draw only edges that are facet boundaries
a, b = np.vstack(bs).T
py5.lines(np.column_stack((vs[a], vs[b])))
py5.run_sketch() |
|
I'm trying
|
|
Experimenting with this, assuming edges have the indices ordered...: coplanar_edges = mesh.face_adjacency_edges[mesh.face_adjacency_angles < tol]
mask = ~np.any(np.all(coplanar_edges[:, None] == mesh.edges_unique, axis=2), axis=0)
a, b = np.vstack(mesh.edges_unique[mask]).T
py5.lines(np.column_stack((vs[a], vs[b])))Otherwise: coplanar_edges = np.sort(mesh.face_adjacency_edges[mesh.face_adjacency_angles < tol], axis=1)
mask = ~np.any(np.all(coplanar_edges[:, None] == mesh.edges_sorted, axis=2), axis=0)
a, b = np.vstack(mesh.edges_sorted[mask]).T
py5.lines(np.column_stack((vs[a], vs[b])))But I see no difference between the visual results of either. My problem is that in this example I still get one co-planar edge shown: [GitHub has been acting up for me, this page never ends loading so the JS that enables the edit & reply functions are unavailable] |
|
And this from our tutorial at Python Brasil is the "state of the art" on this subject! https://github.com/py5coding/python-brasil-2025/blob/main/prototypes/facets.py Do |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have tweaked a bit my
draw_mesh()function using numpy to draw meshes removing the "coplanar face edges", drawing only "facet boundaries".For comparison, with all edges visible:
All reactions