mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-15 15:20:37 -08:00
Removed target from fillet/chamfer, fixed fillet/chamfer bug with base objects
This commit is contained in:
parent
82898b4a39
commit
e74e496b43
4 changed files with 58 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -19,6 +19,7 @@ docs/_build/
|
|||
*.step
|
||||
*.STEP
|
||||
*.stl
|
||||
*.svg
|
||||
|
||||
#mypy cache
|
||||
.mypy_cache
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ from build123d.geometry import (
|
|||
RotationLike,
|
||||
Vector,
|
||||
)
|
||||
from build123d.objects_part import BasePartObject
|
||||
from build123d.objects_sketch import BaseSketchObject
|
||||
from build123d.topology import (
|
||||
Compound,
|
||||
Curve,
|
||||
|
|
@ -220,7 +222,6 @@ def chamfer(
|
|||
*objects: Union[Edge, Vertex],
|
||||
length: float,
|
||||
length2: float = None,
|
||||
target: Union[Face, Sketch, Solid, Part] = None,
|
||||
) -> Union[Sketch, Part]:
|
||||
"""Generic Operation: chamfer
|
||||
|
||||
|
|
@ -232,13 +233,11 @@ def chamfer(
|
|||
objects (Union[Edge,Vertex]): sequence of edges or vertices to chamfer
|
||||
length (float): chamfer size
|
||||
length2 (float, optional): asymmetric chamfer size. Defaults to None.
|
||||
target (Union[Face, Sketch, Solid, Part], optional): object to chamfer. Defaults to None.
|
||||
|
||||
Raises:
|
||||
ValueError: no objects provided
|
||||
ValueError: objects must be Edges
|
||||
ValueError: objects must be Vertices
|
||||
ValueError: missing target object
|
||||
"""
|
||||
context: Builder = Builder._get_context("chamfer")
|
||||
validate_inputs(context, "chamfer", objects)
|
||||
|
|
@ -248,12 +247,18 @@ def chamfer(
|
|||
):
|
||||
raise ValueError("No objects provided")
|
||||
|
||||
if target is None:
|
||||
if context is None:
|
||||
raise ValueError("A target object must be provided")
|
||||
objects = list(objects)
|
||||
if context is not None:
|
||||
target = context._obj
|
||||
else:
|
||||
target = objects[0].topo_parent
|
||||
if target is None:
|
||||
raise ValueError("Nothing to chamfer")
|
||||
|
||||
if target._dim == 3:
|
||||
# Convert BasePartObject into Part so casting into Part during construction works
|
||||
target = Part(target.wrapped) if isinstance(target, BasePartObject) else target
|
||||
|
||||
if not all([isinstance(obj, Edge) for obj in objects]):
|
||||
raise ValueError("3D chamfer operation takes only Edges")
|
||||
new_part = target.chamfer(length, length2, list(objects))
|
||||
|
|
@ -263,6 +268,11 @@ def chamfer(
|
|||
return Part(Compound.make_compound([new_part]).wrapped)
|
||||
|
||||
elif target._dim == 2:
|
||||
# Convert BaseSketchObject into Sketch so casting into Sketch during construction works
|
||||
target = (
|
||||
Sketch(target.wrapped) if isinstance(target, BaseSketchObject) else target
|
||||
)
|
||||
|
||||
if not all([isinstance(obj, Vertex) for obj in objects]):
|
||||
raise ValueError("2D chamfer operation takes only Vertices")
|
||||
new_faces = []
|
||||
|
|
@ -282,7 +292,6 @@ def chamfer(
|
|||
def fillet(
|
||||
*objects: Union[Edge, Vertex],
|
||||
radius: float,
|
||||
target: Union[Face, Sketch, Solid, Part] = None,
|
||||
) -> Union[Sketch, Part]:
|
||||
"""Generic Operation: fillet
|
||||
|
||||
|
|
@ -295,9 +304,10 @@ def fillet(
|
|||
radius (float): fillet size - must be less than 1/2 local width
|
||||
|
||||
Raises:
|
||||
ValueError: no objects provided
|
||||
ValueError: objects must be Edges
|
||||
ValueError: objects must be Vertices
|
||||
ValueError: missing target object
|
||||
ValueError: nothing to fillet
|
||||
"""
|
||||
context: Builder = Builder._get_context("fillet")
|
||||
validate_inputs(context, "fillet", objects)
|
||||
|
|
@ -307,12 +317,18 @@ def fillet(
|
|||
):
|
||||
raise ValueError("No objects provided")
|
||||
|
||||
if target is None:
|
||||
if context is None:
|
||||
raise ValueError("A target object must be provided")
|
||||
objects = list(objects)
|
||||
if context is not None:
|
||||
target = context._obj
|
||||
else:
|
||||
target = objects[0].topo_parent
|
||||
if target is None:
|
||||
raise ValueError("Nothing to fillet")
|
||||
|
||||
if target._dim == 3:
|
||||
# Convert BasePartObject in Part so casting into Part during construction works
|
||||
target = Part(target.wrapped) if isinstance(target, BasePartObject) else target
|
||||
|
||||
if not all([isinstance(obj, Edge) for obj in objects]):
|
||||
raise ValueError("3D fillet operation takes only Edges")
|
||||
new_part = target.fillet(radius, list(objects))
|
||||
|
|
@ -322,6 +338,11 @@ def fillet(
|
|||
return Part(Compound.make_compound([new_part]).wrapped)
|
||||
|
||||
elif target._dim == 2:
|
||||
# Convert BaseSketchObject into Sketch so casting into Sketch during construction works
|
||||
target = (
|
||||
Sketch(target.wrapped) if isinstance(target, BaseSketchObject) else target
|
||||
)
|
||||
|
||||
if not all([isinstance(obj, Vertex) for obj in objects]):
|
||||
raise ValueError("2D fillet operation takes only Vertices")
|
||||
new_faces = []
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ class Mixin1D:
|
|||
class Mixin3D:
|
||||
"""Additional methods to add to 3D Shape classes"""
|
||||
|
||||
def fillet(self, radius: float, edge_list: Iterable[Edge]):
|
||||
def fillet(self, radius: float, edge_list: Iterable[Edge]) -> Self:
|
||||
"""Fillet
|
||||
|
||||
Fillets the specified edges of this solid.
|
||||
|
|
@ -814,7 +814,7 @@ class Mixin3D:
|
|||
|
||||
def chamfer(
|
||||
self, length: float, length2: Optional[float], edge_list: Iterable[Edge]
|
||||
):
|
||||
) -> Self:
|
||||
"""Chamfer
|
||||
|
||||
Chamfers the specified edges of this solid.
|
||||
|
|
@ -1130,6 +1130,9 @@ class Shape(NodeMixin):
|
|||
if isinstance(self, Face):
|
||||
self.created_on: Plane = None
|
||||
|
||||
# Extracted objects like Vertices and Edges may need to know where they came from
|
||||
self.topo_parent: Shape = None
|
||||
|
||||
@property
|
||||
def location(self) -> Location:
|
||||
"""Get this Shape's Location"""
|
||||
|
|
@ -1871,17 +1874,25 @@ class Shape(NodeMixin):
|
|||
|
||||
def vertices(self) -> ShapeList[Vertex]:
|
||||
"""vertices - all the vertices in this Shape"""
|
||||
return ShapeList([Vertex(downcast(i)) for i in self._entities(Vertex.__name__)])
|
||||
vertex_list = ShapeList(
|
||||
[Vertex(downcast(i)) for i in self._entities(Vertex.__name__)]
|
||||
)
|
||||
for vertex in vertex_list:
|
||||
vertex.topo_parent = self
|
||||
return vertex_list
|
||||
|
||||
def edges(self) -> ShapeList[Edge]:
|
||||
"""edges - all the edges in this Shape"""
|
||||
return ShapeList(
|
||||
edge_list = ShapeList(
|
||||
[
|
||||
Edge(i)
|
||||
for i in self._entities(Edge.__name__)
|
||||
if not BRep_Tool.Degenerated_s(TopoDS.Edge_s(i))
|
||||
]
|
||||
)
|
||||
for edge in edge_list:
|
||||
edge.topo_parent = self
|
||||
return edge_list
|
||||
|
||||
def compounds(self) -> ShapeList[Compound]:
|
||||
"""compounds - all the compounds in this Shape"""
|
||||
|
|
@ -1898,7 +1909,10 @@ class Shape(NodeMixin):
|
|||
|
||||
def faces(self) -> ShapeList[Face]:
|
||||
"""faces - all the faces in this Shape"""
|
||||
return ShapeList([Face(i) for i in self._entities(Face.__name__)])
|
||||
face_list = ShapeList([Face(i) for i in self._entities(Face.__name__)])
|
||||
for face in face_list:
|
||||
face.topo_parent = self
|
||||
return face_list
|
||||
|
||||
def shells(self) -> ShapeList[Shell]:
|
||||
"""shells - all the shells in this Shape"""
|
||||
|
|
|
|||
|
|
@ -630,28 +630,29 @@ class LocationTests(unittest.TestCase):
|
|||
class OperationsTests(unittest.TestCase):
|
||||
def test_fillet_3d(self):
|
||||
b = Box(1, 2, 3)
|
||||
c = fillet(*b.edges(), radius=0.2, target=b)
|
||||
c = fillet(*b.edges(), radius=0.2)
|
||||
|
||||
self.assertAlmostEqual(b.volume, 6.0, 6)
|
||||
self.assertAlmostEqual(c.volume, 5.804696, 4)
|
||||
|
||||
def test_fillet_2d(self):
|
||||
r = Rectangle(1, 2)
|
||||
c = fillet(*r.vertices(), radius=0.2, target=r)
|
||||
c = fillet(*r.vertices(), radius=0.2)
|
||||
|
||||
self.assertAlmostEqual(r.area, 2.0, 6)
|
||||
self.assertAlmostEqual(c.area, 1.965663, 4)
|
||||
|
||||
def test_chamfer_3d(self):
|
||||
b = Box(1, 2, 3)
|
||||
c = chamfer(*b.edges(), length=0.2, target=b)
|
||||
c = chamfer(*b.edges(), length=0.2)
|
||||
|
||||
self.assertAlmostEqual(b.volume, 6.0, 6)
|
||||
self.assertAlmostEqual(c.volume, 5.804696, 4)
|
||||
# self.assertAlmostEqual(c.volume, 5.804696, 4)
|
||||
self.assertAlmostEqual(c.volume, 5.56266, 4)
|
||||
|
||||
def test_chamfer_2d(self):
|
||||
r = Rectangle(1, 2)
|
||||
c = chamfer(*r.vertices(), length=0.2, target=r)
|
||||
c = chamfer(*r.vertices(), length=0.2)
|
||||
|
||||
self.assertAlmostEqual(r.area, 2.0, 6)
|
||||
self.assertAlmostEqual(c.area, 1.92, 4)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue