Skip to content

Commit

Permalink
add an early exit for polygon creation
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedh committed Jul 19, 2024
1 parent 85b4bd1 commit 7f2aa95
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 16 deletions.
2 changes: 1 addition & 1 deletion trimesh/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2667,7 +2667,7 @@ def area_faces(self) -> NDArray[float64]:
area_faces : (n, ) float
Area of each face
"""
return triangles.area(crosses=self.triangles_cross, sum=False)
return triangles.area(crosses=self.triangles_cross)

@caching.cache_decorator
def mass_properties(self) -> MassProperties:
Expand Down
2 changes: 1 addition & 1 deletion trimesh/convex.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def convex_hull(obj, qhull_options="QbB Pp Qt", repair=True):
crosses = crosses[valid]

# each triangle area and mean center
triangles_area = triangles.area(crosses=crosses, sum=False)
triangles_area = triangles.area(crosses=crosses)
triangles_center = vertices[faces].mean(axis=1)

# since the convex hull is (hopefully) convex, the vector from
Expand Down
1 change: 1 addition & 0 deletions trimesh/path/exchange/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def polygon_to_path(polygon):
"entities": entities,
"vertices": np.vstack(vertices) if len(vertices) > 0 else vertices,
}

return kwargs


Expand Down
17 changes: 14 additions & 3 deletions trimesh/path/polygons.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def enclosure_tree(polygons):
contained by another polygon
"""

# nodes are indexes in polygons
contains = nx.DiGraph()

if len(polygons) == 1:
# add an early exit for only a single polygon
contains.add_node(0)
return np.array([0], dtype=np.int64), contains

# get the bounds for every valid polygon
bounds = {
k: v
Expand All @@ -59,8 +67,6 @@ def enclosure_tree(polygons):
if len(v) == 4
}

# nodes are indexes in polygons
contains = nx.DiGraph()
# make sure we don't have orphaned polygon
contains.add_nodes_from(bounds.keys())

Expand Down Expand Up @@ -551,13 +557,18 @@ def paths_to_polygons(paths, scale=None):
# non-zero area
continue
try:
polygons[i] = repair_invalid(Polygon(path), scale)
polygon = Polygon(path)
if polygon.is_valid:
polygons[i] = polygon
else:
polygons[i] = repair_invalid(polygon, scale)
except ValueError:
# raised if a polygon is unrecoverable
continue
except BaseException:
log.error("unrecoverable polygon", exc_info=True)
polygons = np.array(polygons)

return polygons


Expand Down
27 changes: 16 additions & 11 deletions trimesh/triangles.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from .util import diagonal_dot, unitize


def cross(triangles):
def cross(triangles: NDArray) -> NDArray:
"""
Returns the cross product of two edges from input triangles
Expand All @@ -30,13 +30,19 @@ def cross(triangles):
crosses : (n, 3) float
Cross product of two edge vectors
"""
vectors = np.diff(triangles, axis=1)
crosses = np.cross(vectors[:, 0], vectors[:, 1])
vectors = triangles[:, 1:, :] - triangles[:, :2, :]
if triangles.shape[2] == 3:
return np.cross(vectors[:, 0], vectors[:, 1])
elif triangles.shape[2] == 2:
a = vectors[:, 0]
b = vectors[:, 1]
# numpy 2.0 deprecated 2D cross productes
return a[:, 0] * b[:, 1] - a[:, 1] * b[:, 0]

return crosses
raise ValueError(triangles.shape)


def area(triangles=None, crosses=None, sum=False):
def area(triangles=None, crosses=None):
"""
Calculates the sum area of input triangles
Expand All @@ -55,11 +61,8 @@ def area(triangles=None, crosses=None, sum=False):
Individual or summed area depending on `sum` argument
"""
if crosses is None:
crosses = cross(triangles)
areas = np.sqrt((crosses**2).sum(axis=1)) / 2.0
if sum:
return areas.sum()
return areas
crosses = cross(np.asanyarray(triangles, dtype=np.float64))
return np.sqrt((crosses**2).sum(axis=1)) / 2.0


def normals(triangles=None, crosses=None):
Expand All @@ -80,6 +83,8 @@ def normals(triangles=None, crosses=None):
valid : (n,) bool
Was the face nonzero area or not
"""
if triangles is not None and triangles.shape[-1] == 2:
return np.tile([0.0, 0.0, 1.0], (triangles.shape[0], 1))
if crosses is None:
crosses = cross(triangles)
# unitize the cross product vectors
Expand Down Expand Up @@ -435,7 +440,7 @@ def extents(triangles, areas=None):
raise ValueError("Triangles must be (n, 3, 3)!")

if areas is None:
areas = area(triangles=triangles, sum=False)
areas = area(triangles=triangles)

# the edge vectors which define the triangle
a = triangles[:, 1] - triangles[:, 0]
Expand Down

0 comments on commit 7f2aa95

Please sign in to comment.