added support for passing an iterable of radii to FilletPolyline.

This commit is contained in:
x0pherl 2025-10-30 21:08:26 -04:00 committed by Roger Maitland
parent df17ae8698
commit 173c7b08e2
2 changed files with 60 additions and 5 deletions

View file

@ -793,7 +793,7 @@ class FilletPolyline(BaseLineObject):
Args: Args:
pts (VectorLike | Iterable[VectorLike]): sequence of two or more points pts (VectorLike | Iterable[VectorLike]): sequence of two or more points
radius (float): fillet radius radius (float | Iterable[float]): radius to fillet at each vertex or a single value for all vertices
close (bool, optional): close end points with extra Edge and corner fillets. close (bool, optional): close end points with extra Edge and corner fillets.
Defaults to False Defaults to False
mode (Mode, optional): combination mode. Defaults to Mode.ADD mode (Mode, optional): combination mode. Defaults to Mode.ADD
@ -808,7 +808,7 @@ class FilletPolyline(BaseLineObject):
def __init__( def __init__(
self, self,
*pts: VectorLike | Iterable[VectorLike], *pts: VectorLike | Iterable[VectorLike],
radius: float, radius: float | Iterable[float],
close: bool = False, close: bool = False,
mode: Mode = Mode.ADD, mode: Mode = Mode.ADD,
): ):
@ -819,7 +819,16 @@ class FilletPolyline(BaseLineObject):
if len(points) < 2: if len(points) < 2:
raise ValueError("FilletPolyline requires two or more pts") raise ValueError("FilletPolyline requires two or more pts")
if radius <= 0:
if isinstance(radius, (int, float)):
radius_list = [radius] * len(points) # Single radius for all points
else:
radius_list = list(radius)
if len(radius_list) != len(points):
raise ValueError(
f"radius list length ({len(radius_list)}) must match points ({len(points)})"
)
if any(r <= 0 for r in radius_list):
raise ValueError("radius must be positive") raise ValueError("radius must be positive")
lines_pts = WorkplaneList.localize(*points) lines_pts = WorkplaneList.localize(*points)
@ -852,12 +861,14 @@ class FilletPolyline(BaseLineObject):
# For each corner vertex create a new fillet Edge # For each corner vertex create a new fillet Edge
fillets = [] fillets = []
for vertex, edges in vertex_to_edges.items(): for i, (vertex, edges) in enumerate(vertex_to_edges.items()):
if len(edges) != 2: if len(edges) != 2:
continue continue
other_vertices = {ve for e in edges for ve in e.vertices() if ve != vertex} other_vertices = {ve for e in edges for ve in e.vertices() if ve != vertex}
third_edge = Edge.make_line(*[v for v in other_vertices]) third_edge = Edge.make_line(*[v for v in other_vertices])
fillet_face = Face(Wire(edges + [third_edge])).fillet_2d(radius, [vertex]) fillet_face = Face(Wire(edges + [third_edge])).fillet_2d(
radius_list[i], [vertex]
)
fillets.append(fillet_face.edges().filter_by(GeomType.CIRCLE)[0]) fillets.append(fillet_face.edges().filter_by(GeomType.CIRCLE)[0])
# Create the Edges that join the fillets # Create the Edges that join the fillets
@ -1597,6 +1608,7 @@ class ArcArcTangentLine(BaseEdgeObject):
Defaults to Keep.INSIDE Defaults to Keep.INSIDE
mode (Mode, optional): combination mode. Defaults to Mode.ADD mode (Mode, optional): combination mode. Defaults to Mode.ADD
""" """
warnings.warn( warnings.warn(
"The 'ArcArcTangentLine' object is deprecated and will be removed in a future version.", "The 'ArcArcTangentLine' object is deprecated and will be removed in a future version.",
DeprecationWarning, DeprecationWarning,

View file

@ -183,6 +183,49 @@ class BuildLineTests(unittest.TestCase):
self.assertEqual(len(p.edges().filter_by(GeomType.CIRCLE)), 2) self.assertEqual(len(p.edges().filter_by(GeomType.CIRCLE)), 2)
self.assertEqual(len(p.edges().filter_by(GeomType.LINE)), 3) self.assertEqual(len(p.edges().filter_by(GeomType.LINE)), 3)
with self.assertRaises(ValueError):
p = FilletPolyline(
(0, 0),
(10, 0),
(10, 10),
(0, 10),
radius=(1, 2, 3, 0),
close=True,
)
with self.assertRaises(ValueError):
p = FilletPolyline(
(0, 0),
(10, 0),
(10, 10),
(0, 10),
radius=-1,
close=True,
)
with self.assertRaises(ValueError):
p = FilletPolyline(
(0, 0),
(10, 0),
(10, 10),
(0, 10),
radius=(1, 2),
close=True,
)
with BuildLine(Plane.YZ):
p = FilletPolyline(
(0, 0),
(10, 0),
(10, 10),
(0, 10),
radius=(1, 2, 3, 4),
close=True,
)
self.assertEqual(len(p.edges()), 8)
self.assertEqual(len(p.edges().filter_by(GeomType.CIRCLE)), 4)
self.assertEqual(len(p.edges().filter_by(GeomType.LINE)), 4)
with BuildLine(Plane.YZ): with BuildLine(Plane.YZ):
p = FilletPolyline( p = FilletPolyline(
(0, 0, 0), (0, 0, 10), (10, 2, 10), (10, 0, 0), radius=2, close=True (0, 0, 0), (0, 0, 10), (10, 2, 10), (10, 0, 0), radius=2, close=True