Skip to content

Commit

Permalink
Added new Edge.trim_to_length feature
Browse files Browse the repository at this point in the history
  • Loading branch information
gumyr committed Jun 14, 2024
1 parent 62d762b commit 4561105
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/build123d/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
Geom_TrimmedCurve,
Geom_Line,
)
from OCP.GeomAdaptor import GeomAdaptor_Curve
from OCP.Geom2d import Geom2d_Curve, Geom2d_Line, Geom2d_TrimmedCurve
from OCP.Geom2dAPI import Geom2dAPI_InterCurveCurve
from OCP.GeomAbs import GeomAbs_C0, GeomAbs_Intersection, GeomAbs_JoinType
Expand Down Expand Up @@ -558,7 +559,8 @@ def common_plane(self, *lines: Union[Edge, Wire]) -> Union[None, Plane]:
Union[None, Plane]: Either the common plane or None
"""
# pylint: disable=too-many-locals
# BRepLib_FindSurface could help here
# Note: BRepLib_FindSurface is not helpful as it requires the
# Edges to form a surface perimeter.
points: list[Vector] = []
all_lines: list[Edge, Wire] = [
line for line in [self, *lines] if line is not None
Expand Down Expand Up @@ -4621,6 +4623,39 @@ def trim(self, start: float, end: float) -> Edge:
new_edge = BRepBuilderAPI_MakeEdge(trimmed_curve).Edge()
return Edge(new_edge)

def trim_to_length(self, start: float, length: float) -> Edge:
"""trim_to_length
Create a new edge starting at the given normalized parameter of a
given length.
Args:
start (float): 0.0 <= start < 1.0
length (float): target length
Returns:
Edge: trimmed edge
"""
new_curve = BRep_Tool.Curve_s(
copy.deepcopy(self).wrapped, self.param_at(0), self.param_at(1)
)

# Create an adaptor for the curve
adaptor_curve = GeomAdaptor_Curve(new_curve)

# Find the parameter corresponding to the desired length
parm_start = self.param_at(start)
abscissa_point = GCPnts_AbscissaPoint(adaptor_curve, length, parm_start)

# Get the parameter at the desired length
parm_end = abscissa_point.Parameter()

# Trim the curve to the desired length
trimmed_curve = Geom_TrimmedCurve(new_curve, parm_start, parm_end)

new_edge = BRepBuilderAPI_MakeEdge(trimmed_curve).Edge()
return Edge(new_edge)

def param_at_point(self, point: VectorLike) -> float:
"""Parameter at point of Edge"""

Expand Down
23 changes: 23 additions & 0 deletions tests/test_direct_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,29 @@ def test_trim(self):
with self.assertRaises(ValueError):
line.trim(0.75, 0.25)

def test_trim_to_length(self):

e1 = Edge.make_line((0, 0), (10, 10))
e1_trim = e1.trim_to_length(0.0, 10)
self.assertAlmostEqual(e1_trim.length, 10, 5)

e2 = Edge.make_circle(10, start_angle=0, end_angle=90)
e2_trim = e2.trim_to_length(0.5, 1)
self.assertAlmostEqual(e2_trim.length, 1, 5)
self.assertVectorAlmostEquals(
e2_trim.position_at(0), Vector(10, 0, 0).rotate(Axis.Z, 45), 5
)

e3 = Edge.make_spline(
[(0, 10, 0), (-4, 5, 2), (0, 0, 0)], tangents=[(-1, 0), (1, 0)]
)
e3_trim = e3.trim_to_length(0, 7)
self.assertAlmostEqual(e3_trim.length, 7, 5)

a4 = Axis((0, 0, 0), (1, 1, 1))
e4_trim = a4.as_infinite_edge().trim_to_length(0.5, 2)
self.assertAlmostEqual(e4_trim.length, 2, 5)

def test_bezier(self):
with self.assertRaises(ValueError):
Edge.make_bezier((1, 1))
Expand Down

0 comments on commit 4561105

Please sign in to comment.