Open larsgrobe opened 1 year ago
Hey, have you looked at trimesh.creation.extrude_polygon
or trimesh.primitive.Extrusion
?:
In [1]: import trimesh
In [2]: from shapely.geometry import Point
In [3]: polygon = Point([0,0]).buffer(1.0)
In [4]: polygon
Out[4]: <POLYGON ((1 0, 0.995 -0.098, 0.981 -0.195, 0.957 -0.29, 0.924 -0.383, 0.882...>
In [5]: extrude = trimesh.primitives.Extrusion(polygon=polygon, height=10)
In [6]: extrude
Out[6]: <trimesh.primitives.Extrusion>
In [7]: extrude.volume
Out[7]: 31.365484905459397
In [8]: extrude.bounds
Out[8]:
array([[-1., -1., 0.],
[ 1., 1., 10.]])
In [9]: m = trimesh.creation.extrude_polygon(polygon, height=10)
In [10]: m
Out[10]: <trimesh.Trimesh(vertices.shape=(128, 3), faces.shape=(252, 3))>
Hi Mike,
thank you for the example! I have done this to create mesh volumes. The difference is that now I want to create a thin surface, not a closed volume.
Best, Lars.
Oh gotcha, seems like we could pretty easily add an cap=True
option to trimesh.creation.extrude_triangulation
to just optionally skip the caps? Would filtering by face normal work in the mean time?
In [1]: import trimesh
In [2]: from shapely.geometry import Point
In [3]: polygon = Point([0,0]).buffer(1.0)
In [4]: extrude = trimesh.creation.extrude_polygon(polygon, height=10)
In [5]: extrude
Out[5]: <trimesh.Trimesh(vertices.shape=(128, 3), faces.shape=(252, 3))>
In [7]: import numpy as np
In [8]: epsilon = 1e-8
In [10]: dot = np.dot(extrude.face_normals, [0,0,1])
In [11]: face_ok = np.logical_and(dot > (epsilon - 1), dot < (1 - epsilon))
In [12]: face_ok.all()
Out[12]: False
In [13]: extrude.update_faces(face_ok)
Hi Mike,
filtering would be an option, good point - I am just not sure if I can extrude open paths (like a simple line). My first attempts were not very successful with it, but this may be due to me just starting with trimesh.
Best, Lars.
Dear trimesh-community,
first of all, thank you for providing and supporting this amazing software package!
I am trying to create a trimesh representation of a 2.5D geometry defined by a 2D-path, a base height, and an z-extrusion. Initially I had hoped that there was some trimesh-function allowing to extrude an open 2D-path to a triangulated, vertical rectange, but could not find any such feature.
My workaround was to generate a 3D shapely polygon by transforming the path to the base height, then transforming its copy by the extrusion lenght and inverting its coordinates, and finally closing it. This results in a 3D shapely polygon like this:
POLYGON Z ((-6.198309651941504 5.723988925475256 15, -5.787440372932203 4.571607560399093 15, -5.787440372932203 4.571607560399093 16.9, -6.198309651941504 5.723988925475256 16.9, -6.198309651941504 5.723988925475256 15))
I was hoping that I could now convert it into a mesh with the help of
trimesh.creation.triangulate_polygon()
. Unfortunately, this does not work (I have shortened the path names):File testPath2.py:149 in refinePolygons
print(trimesh.creation.triangulate_polygon(p))
File python3.10/site-packages/trimesh/creation.py:454 in triangulate_polygon
faces = _tri_earcut(vertices, rings).reshape(
ValueError: The second dimension of vertices is not 2!
The function
trimesh.path.exchange.misc.polygon_to_path()
apparently accepts the polygon, it returns for the same input:{'entities': [<trimesh.path.entities.Line object at 0x16a6a8400>], 'vertices':
array([[ 0.15185252, 4.65746915, 14.5 ],
[ 0.91988539, 4.88676764, 14.5 ],
[ 0.91988539, 4.88676764, 16.5 ],
[ 0.15185252, 4.65746915, 16.5 ],
[ 0.15185252, 4.65746915, 14.5 ]])}
I tried to construct a path from this result, leading to
TypeError: iteration over a 0-d array
What is accepted is to pass only the vertices:
trimesh.path.Path2D(vertices=par['vertices'])
resulting in:
<trimesh.Path2D(vertices.shape=(4, 3), len(entities)=0)>
I read this like a path comprising unconnected vertices. At this point I am stuck. Before I try to create the triangles from my vertices "manually" - is there any functionality implemented in trimesh for what I want to achieve?
Best, Lars.