Skip to content

Commit

Permalink
Improved Wire.trim
Browse files Browse the repository at this point in the history
  • Loading branch information
gumyr committed Dec 2, 2023
1 parent ad47361 commit f892032
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
25 changes: 17 additions & 8 deletions src/build123d/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -6786,9 +6786,13 @@ def trim(self, start: float, end: float) -> Wire:
trim_start_point = self.position_at(start)
trim_end_point = self.position_at(end)

# If this is really just an edge, skip the complexity of a Wire
if len(self.edges()) == 1:
return Wire.make_wire([self.edge().trim(start, end)])

# Get all the edges
modified_edges: list[Edge] = []
original_edges: list[Edge] = []
unmodified_edges: list[Edge] = []
for edge in self.edges():
# Is edge flipped
flipped = self.param_at_point(edge.position_at(0)) > self.param_at_point(
Expand All @@ -6800,7 +6804,11 @@ def trim(self, start: float, end: float) -> Wire:

# Trim edges containing start or end points
degenerate = False
if contains_start:
if contains_start and contains_end:
u_start = edge.param_at_point(trim_start_point)
u_end = edge.param_at_point(trim_end_point)
edge = edge.trim(u_start, u_end)
elif contains_start:
u_value = edge.param_at_point(trim_start_point)
if not flipped:
degenerate = u_value == 1.0
Expand All @@ -6810,7 +6818,7 @@ def trim(self, start: float, end: float) -> Wire:
degenerate = u_value == 0.0
if not degenerate:
edge = edge.trim(0.0, u_value)
if contains_end:
elif contains_end:
u_value = edge.param_at_point(trim_end_point)
if not flipped:
degenerate = u_value == 0.0
Expand All @@ -6824,10 +6832,10 @@ def trim(self, start: float, end: float) -> Wire:
if contains_start or contains_end:
modified_edges.append(edge)
else:
original_edges.append(edge)
unmodified_edges.append(edge)

# Select the wire containing the start and end points
wire_segments = edges_to_wires(modified_edges + original_edges)
wire_segments = edges_to_wires(modified_edges + unmodified_edges)
trimmed_wire = filter(
lambda w: all(
[
Expand All @@ -6837,9 +6845,10 @@ def trim(self, start: float, end: float) -> Wire:
),
wire_segments,
)
if not trimmed_wire:
raise RuntimeError("Invalid trim result")
return next(trimmed_wire)
try:
return next(trimmed_wire)
except StopIteration as exc:
raise RuntimeError("Invalid trim result") from exc

def order_edges(self) -> ShapeList[Edge]:
"""Return the edges in self ordered by wire direction and orientation"""
Expand Down
10 changes: 10 additions & 0 deletions tests/test_direct_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from build123d.objects_curve import Polyline
from build123d.build_sketch import BuildSketch
from build123d.build_line import BuildLine
from build123d.objects_curve import Spline
from build123d.objects_sketch import Circle, Rectangle, RegularPolygon
from build123d.geometry import (
Axis,
Expand Down Expand Up @@ -3513,6 +3514,15 @@ def test_trim(self):

with self.assertRaises(ValueError):
o.trim(0.75, 0.25)
spline = Spline(
(0, 0, 0),
(0, 10, 0),
tangents=((0, 0, 1), (0, 0, -1)),
tangent_scalars=(2, 2),
)
half = spline.trim(0.5, 1)
self.assertVectorAlmostEquals(spline @ 0.5, half @ 0, 4)
self.assertVectorAlmostEquals(spline @ 1, half @ 1, 4)

def test_param_at_point(self):
e = Edge.make_three_point_arc((0, -20), (5, 0), (0, 20))
Expand Down

0 comments on commit f892032

Please sign in to comment.