mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Added Compound constructor and deprecated make_compound Issue #523
This commit is contained in:
parent
e6b9ca6e66
commit
d520fc40da
15 changed files with 182 additions and 83 deletions
|
|
@ -421,7 +421,7 @@ class Builder(ABC):
|
|||
raise RuntimeError("Nothing to intersect with")
|
||||
self._obj = self._obj.intersect(*typed[self._shape])
|
||||
elif mode == Mode.REPLACE:
|
||||
self._obj = Compound.make_compound(list(typed[self._shape]))
|
||||
self._obj = Compound(list(typed[self._shape]))
|
||||
|
||||
if self._obj is not None and clean:
|
||||
self._obj = self._obj.clean()
|
||||
|
|
@ -452,9 +452,7 @@ class Builder(ABC):
|
|||
if isinstance(self._obj, Compound):
|
||||
self._obj = self._sub_class(self._obj.wrapped)
|
||||
else:
|
||||
self._obj = self._sub_class(
|
||||
Compound.make_compound(self._shapes()).wrapped
|
||||
)
|
||||
self._obj = self._sub_class(Compound(self._shapes()).wrapped)
|
||||
|
||||
# Add to pending
|
||||
if self._tag == "BuildPart":
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class BuildSketch(Builder):
|
|||
global_objs = []
|
||||
for plane in workplanes:
|
||||
global_objs.append(plane.from_local_coords(self._obj))
|
||||
return Sketch(Compound.make_compound(global_objs).wrapped)
|
||||
return Sketch(Compound(global_objs).wrapped)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -139,8 +139,8 @@ class Drawing:
|
|||
BRepLib.BuildCurves3d_s(el, TOLERANCE)
|
||||
|
||||
# Convert and store the results.
|
||||
self.visible_lines = Compound.make_compound(map(Shape, visible))
|
||||
self.hidden_lines = Compound.make_compound(map(Shape, hidden))
|
||||
self.visible_lines = Compound(map(Shape, visible))
|
||||
self.hidden_lines = Compound(map(Shape, hidden))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -149,6 +149,7 @@ class Drawing:
|
|||
|
||||
class AutoNameEnum(Enum):
|
||||
"""An enum class that automatically sets members' value to their name."""
|
||||
|
||||
@staticmethod
|
||||
def _generate_next_value_(name, start, count, last_values):
|
||||
return name
|
||||
|
|
@ -865,6 +866,7 @@ class ExportSVG(Export2D):
|
|||
ValueError: Invalid unit.
|
||||
|
||||
"""
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
_Converter = Callable[[Edge], ET.Element]
|
||||
|
||||
|
|
@ -1375,7 +1377,11 @@ class ExportSVG(Export2D):
|
|||
ltname = layer.line_type.value
|
||||
_, pattern = Export2D.LINETYPE_DEFS[ltname]
|
||||
|
||||
d = self.dot_length.value if isinstance(self.dot_length, DotLength) else self.dot_length
|
||||
d = (
|
||||
self.dot_length.value
|
||||
if isinstance(self.dot_length, DotLength)
|
||||
else self.dot_length
|
||||
)
|
||||
pattern = copy(pattern)
|
||||
plen = len(pattern)
|
||||
for i in range(0, plen):
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ from svgpathtools import svg2paths
|
|||
from build123d.geometry import Color
|
||||
from build123d.topology import Compound, Face, Shape, ShapeList, Wire
|
||||
|
||||
|
||||
def import_brep(file_name: str) -> Shape:
|
||||
"""Import shape from a BREP file
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ def import_step(file_name: str) -> Compound:
|
|||
reader = STEPControl_Reader()
|
||||
read_status = reader.ReadFile(file_name)
|
||||
# pylint fails to understand OCP's module here, so suppress on the next line.
|
||||
if read_status != OCP.IFSelect.IFSelect_RetDone: # pylint: disable=no-member
|
||||
if read_status != OCP.IFSelect.IFSelect_RetDone: # pylint: disable=no-member
|
||||
raise ValueError(f"STEP File {file_name} could not be loaded")
|
||||
for i in range(reader.NbRootsForTransfer()):
|
||||
reader.TransferRoot(i + 1)
|
||||
|
|
@ -100,7 +101,7 @@ def import_step(file_name: str) -> Compound:
|
|||
for shape in occ_shapes:
|
||||
solids.append(Shape.cast(shape))
|
||||
|
||||
return Compound.make_compound(solids)
|
||||
return Compound(solids)
|
||||
|
||||
|
||||
def import_stl(file_name: str) -> Face:
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ class RevoluteJoint(Joint):
|
|||
"""A CAD symbol representing the axis of rotation as bound to part"""
|
||||
radius = self.parent.bounding_box().diagonal / 30
|
||||
|
||||
return Compound.make_compound(
|
||||
return Compound(
|
||||
[
|
||||
Edge.make_line((0, 0, 0), (0, 0, radius * 10)),
|
||||
Edge.make_circle(radius),
|
||||
|
|
@ -328,7 +328,7 @@ class LinearJoint(Joint):
|
|||
def symbol(self) -> Compound:
|
||||
"""A CAD symbol of the linear axis positioned relative to_part"""
|
||||
radius = (self.linear_range[1] - self.linear_range[0]) / 15
|
||||
return Compound.make_compound(
|
||||
return Compound(
|
||||
[
|
||||
Edge.make_line(
|
||||
(0, 0, self.linear_range[0]), (0, 0, self.linear_range[1])
|
||||
|
|
@ -492,13 +492,14 @@ class CylindricalJoint(Joint):
|
|||
Raises:
|
||||
ValueError: angle_reference must be normal to axis
|
||||
"""
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
|
||||
@property
|
||||
def symbol(self) -> Compound:
|
||||
"""A CAD symbol representing the cylindrical axis as bound to part"""
|
||||
radius = (self.linear_range[1] - self.linear_range[0]) / 15
|
||||
return Compound.make_compound(
|
||||
return Compound(
|
||||
[
|
||||
Edge.make_line(
|
||||
(0, 0, self.linear_range[0]), (0, 0, self.linear_range[1])
|
||||
|
|
@ -640,7 +641,7 @@ class BallJoint(Joint):
|
|||
circle_y = Edge.make_circle(radius, self.angle_reference.rotated((90, 0, 0)))
|
||||
circle_z = Edge.make_circle(radius, self.angle_reference.rotated((0, 90, 0)))
|
||||
|
||||
return Compound.make_compound(
|
||||
return Compound(
|
||||
[
|
||||
circle_x,
|
||||
circle_y,
|
||||
|
|
|
|||
|
|
@ -92,15 +92,15 @@ class BasePartObject(Part):
|
|||
context._add_to_context(*new_solids, mode=mode)
|
||||
|
||||
if len(new_solids) > 1:
|
||||
new_part = Compound.make_compound(new_solids).wrapped
|
||||
new_part = Compound(new_solids).wrapped
|
||||
elif isinstance(new_solids[0], Compound): # Don't add extra layers
|
||||
new_part = new_solids[0].wrapped
|
||||
else:
|
||||
new_part = Compound.make_compound(new_solids).wrapped
|
||||
new_part = Compound(new_solids).wrapped
|
||||
|
||||
super().__init__(
|
||||
obj=new_part,
|
||||
# obj=Compound.make_compound(new_solids).wrapped,
|
||||
# obj=Compound(new_solids).wrapped,
|
||||
label=part.label,
|
||||
material=part.material,
|
||||
joints=part.joints,
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class BaseSketchObject(Sketch):
|
|||
if isinstance(context, BuildSketch):
|
||||
context._add_to_context(*new_faces, mode=mode)
|
||||
|
||||
super().__init__(Compound.make_compound(new_faces).wrapped)
|
||||
super().__init__(Compound(new_faces).wrapped)
|
||||
|
||||
|
||||
class Circle(BaseSketchObject):
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ def add(
|
|||
else:
|
||||
raise RuntimeError(f"Builder {context.__class__.__name__} is unsupported")
|
||||
|
||||
return Compound.make_compound(new_objects)
|
||||
return Compound(new_objects)
|
||||
|
||||
|
||||
def bounding_box(
|
||||
|
|
@ -234,7 +234,7 @@ def bounding_box(
|
|||
)
|
||||
if context is not None:
|
||||
context._add_to_context(*new_faces, mode=mode)
|
||||
return Sketch(Compound.make_compound(new_faces).wrapped)
|
||||
return Sketch(Compound(new_faces).wrapped)
|
||||
|
||||
new_objects = []
|
||||
for obj in object_list:
|
||||
|
|
@ -251,7 +251,7 @@ def bounding_box(
|
|||
)
|
||||
if context is not None:
|
||||
context._add_to_context(*new_objects, mode=mode)
|
||||
return Part(Compound.make_compound(new_objects).wrapped)
|
||||
return Part(Compound(new_objects).wrapped)
|
||||
|
||||
|
||||
#:TypeVar("ChamferFilletType"): Type of objects which can be chamfered or filleted
|
||||
|
|
@ -326,7 +326,7 @@ def chamfer(
|
|||
|
||||
if context is not None:
|
||||
context._add_to_context(new_part, mode=Mode.REPLACE)
|
||||
return Part(Compound.make_compound([new_part]).wrapped)
|
||||
return Part(Compound([new_part]).wrapped)
|
||||
|
||||
if target._dim == 2:
|
||||
# Convert BaseSketchObject into Sketch so casting into Sketch during construction works
|
||||
|
|
@ -344,7 +344,7 @@ def chamfer(
|
|||
)
|
||||
else:
|
||||
new_faces.append(face)
|
||||
new_sketch = Sketch(Compound.make_compound(new_faces).wrapped)
|
||||
new_sketch = Sketch(Compound(new_faces).wrapped)
|
||||
|
||||
if context is not None:
|
||||
context._add_to_context(new_sketch, mode=Mode.REPLACE)
|
||||
|
|
@ -428,7 +428,7 @@ def fillet(
|
|||
|
||||
if context is not None:
|
||||
context._add_to_context(new_part, mode=Mode.REPLACE)
|
||||
return Part(Compound.make_compound([new_part]).wrapped)
|
||||
return Part(Compound([new_part]).wrapped)
|
||||
|
||||
if target._dim == 2:
|
||||
# Convert BaseSketchObject into Sketch so casting into Sketch during construction works
|
||||
|
|
@ -445,7 +445,7 @@ def fillet(
|
|||
new_faces.append(face.fillet_2d(radius, vertices_in_face))
|
||||
else:
|
||||
new_faces.append(face)
|
||||
new_sketch = Sketch(Compound.make_compound(new_faces).wrapped)
|
||||
new_sketch = Sketch(Compound(new_faces).wrapped)
|
||||
|
||||
if context is not None:
|
||||
context._add_to_context(new_sketch, mode=Mode.REPLACE)
|
||||
|
|
@ -522,7 +522,7 @@ def mirror(
|
|||
if context is not None:
|
||||
context._add_to_context(*mirrored, mode=mode)
|
||||
|
||||
mirrored_compound = Compound.make_compound(mirrored)
|
||||
mirrored_compound = Compound(mirrored)
|
||||
if all([obj._dim == 3 for obj in object_list]):
|
||||
return Part(mirrored_compound.wrapped)
|
||||
if all([obj._dim == 2 for obj in object_list]):
|
||||
|
|
@ -656,7 +656,7 @@ def offset(
|
|||
if context is not None:
|
||||
context._add_to_context(*new_objects, mode=mode)
|
||||
|
||||
offset_compound = Compound.make_compound(new_objects)
|
||||
offset_compound = Compound(new_objects)
|
||||
if all([obj._dim == 3 for obj in object_list]):
|
||||
return Part(offset_compound.wrapped)
|
||||
if all([obj._dim == 2 for obj in object_list]):
|
||||
|
|
@ -806,7 +806,7 @@ def project(
|
|||
if projected_points:
|
||||
result = ShapeList(projected_points)
|
||||
else:
|
||||
result = Compound.make_compound(projected_shapes)
|
||||
result = Compound(projected_shapes)
|
||||
if all([obj._dim == 2 for obj in object_list]):
|
||||
result = Sketch(result.wrapped)
|
||||
elif all([obj._dim == 1 for obj in object_list]):
|
||||
|
|
@ -881,7 +881,7 @@ def scale(
|
|||
if context is not None:
|
||||
context._add_to_context(*new_objects, mode=mode)
|
||||
|
||||
scale_compound = Compound.make_compound(new_objects)
|
||||
scale_compound = Compound(new_objects)
|
||||
if all([obj._dim == 3 for obj in object_list]):
|
||||
return Part(scale_compound.wrapped)
|
||||
if all([obj._dim == 2 for obj in object_list]):
|
||||
|
|
@ -934,7 +934,7 @@ def split(
|
|||
if context is not None:
|
||||
context._add_to_context(*new_objects, mode=mode)
|
||||
|
||||
split_compound = Compound.make_compound(new_objects)
|
||||
split_compound = Compound(new_objects)
|
||||
if all([obj._dim == 3 for obj in object_list]):
|
||||
return Part(split_compound.wrapped)
|
||||
if all([obj._dim == 2 for obj in object_list]):
|
||||
|
|
@ -1059,5 +1059,5 @@ def sweep(
|
|||
new_faces = [face.clean() for face in new_faces]
|
||||
|
||||
if new_solids:
|
||||
return Part(Compound.make_compound(new_solids).wrapped)
|
||||
return Sketch(Compound.make_compound(new_faces).wrapped)
|
||||
return Part(Compound(new_solids).wrapped)
|
||||
return Sketch(Compound(new_faces).wrapped)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ def extrude(
|
|||
if clean:
|
||||
new_solids = [solid.clean() for solid in new_solids]
|
||||
|
||||
return Part(Compound.make_compound(new_solids).wrapped)
|
||||
return Part(Compound(new_solids).wrapped)
|
||||
|
||||
|
||||
def loft(
|
||||
|
|
@ -250,7 +250,7 @@ def loft(
|
|||
elif clean:
|
||||
new_solid = new_solid.clean()
|
||||
|
||||
return Part(Compound.make_compound([new_solid]).wrapped)
|
||||
return Part(Compound([new_solid]).wrapped)
|
||||
|
||||
|
||||
def make_brake_formed(
|
||||
|
|
@ -356,7 +356,7 @@ def make_brake_formed(
|
|||
elif clean:
|
||||
new_solid = new_solid.clean()
|
||||
|
||||
return Part(Compound.make_compound([new_solid]).wrapped)
|
||||
return Part(Compound([new_solid]).wrapped)
|
||||
|
||||
|
||||
def project_workplane(
|
||||
|
|
@ -472,7 +472,7 @@ def revolve(
|
|||
|
||||
new_solids.append(Solid.revolve(profile, angle, axis))
|
||||
|
||||
new_solid = Compound.make_compound(new_solids)
|
||||
new_solid = Compound(new_solids)
|
||||
if context is not None:
|
||||
context._add_to_context(*new_solids, clean=clean, mode=mode)
|
||||
elif clean:
|
||||
|
|
@ -541,7 +541,7 @@ def section(
|
|||
if clean:
|
||||
new_objects = [r.clean() for r in new_objects]
|
||||
|
||||
return Sketch(Compound.make_compound(new_objects).wrapped)
|
||||
return Sketch(Compound(new_objects).wrapped)
|
||||
|
||||
|
||||
def thicken(
|
||||
|
|
@ -616,4 +616,4 @@ def thicken(
|
|||
if clean:
|
||||
new_solids = [solid.clean() for solid in new_solids]
|
||||
|
||||
return Part(Compound.make_compound(new_solids).wrapped)
|
||||
return Part(Compound(new_solids).wrapped)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ def make_face(
|
|||
context._add_to_context(pending_face, mode=mode)
|
||||
context.pending_edges = ShapeList()
|
||||
|
||||
return Sketch(Compound.make_compound([pending_face]).wrapped)
|
||||
return Sketch(Compound([pending_face]).wrapped)
|
||||
|
||||
|
||||
def make_hull(
|
||||
|
|
@ -104,7 +104,7 @@ def make_hull(
|
|||
context._add_to_context(pending_face, mode=mode)
|
||||
context.pending_edges = ShapeList()
|
||||
|
||||
return Sketch(Compound.make_compound([pending_face]).wrapped)
|
||||
return Sketch(Compound([pending_face]).wrapped)
|
||||
|
||||
|
||||
def trace(
|
||||
|
|
|
|||
|
|
@ -1417,7 +1417,6 @@ class Shape(NodeMixin):
|
|||
material: str = "",
|
||||
joints: dict[str, Joint] = None,
|
||||
parent: Compound = None,
|
||||
children: list[Shape] = None,
|
||||
):
|
||||
self.wrapped = downcast(obj) if obj is not None else None
|
||||
self.for_construction = False
|
||||
|
|
@ -1429,11 +1428,6 @@ class Shape(NodeMixin):
|
|||
if isinstance(self, Solid):
|
||||
self.joints = joints if joints else {}
|
||||
|
||||
# Bind joints and children to Compounds (other Shapes can't have children)
|
||||
if isinstance(self, Compound):
|
||||
self.joints = joints if joints else {}
|
||||
self.children = children if children else []
|
||||
|
||||
# parent must be set following children as post install accesses children
|
||||
self.parent = parent
|
||||
|
||||
|
|
@ -1695,7 +1689,7 @@ class Shape(NodeMixin):
|
|||
elif isinstance(self, Sketch):
|
||||
new_shape = Sketch(new_shape.wrapped)
|
||||
elif isinstance(self, (Wire, Curve)):
|
||||
new_shape = Curve(Compound.make_compound(new_shape.edges()).wrapped)
|
||||
new_shape = Curve(Compound(new_shape.edges()).wrapped)
|
||||
|
||||
return new_shape
|
||||
|
||||
|
|
@ -1727,7 +1721,7 @@ class Shape(NodeMixin):
|
|||
elif isinstance(self, Sketch):
|
||||
new_shape = Sketch(new_shape.wrapped)
|
||||
elif isinstance(self, (Wire, Curve)):
|
||||
new_shape = Curve(Compound.make_compound(new_shape.edges()).wrapped)
|
||||
new_shape = Curve(Compound(new_shape.edges()).wrapped)
|
||||
|
||||
return new_shape
|
||||
|
||||
|
|
@ -1747,7 +1741,7 @@ class Shape(NodeMixin):
|
|||
elif isinstance(self, Sketch):
|
||||
new_shape = Sketch(new_shape.wrapped)
|
||||
elif isinstance(self, (Wire, Curve)):
|
||||
new_shape = Curve(Compound.make_compound(new_shape.edges()).wrapped)
|
||||
new_shape = Curve(Compound(new_shape.edges()).wrapped)
|
||||
|
||||
return new_shape
|
||||
|
||||
|
|
@ -2760,12 +2754,12 @@ class Shape(NodeMixin):
|
|||
if len(tops) == 1:
|
||||
result = tops[0]
|
||||
else:
|
||||
result = Compound.make_compound(tops)
|
||||
result = Compound(tops)
|
||||
elif keep == Keep.BOTTOM:
|
||||
if len(bottoms) == 1:
|
||||
result = bottoms[0]
|
||||
else:
|
||||
result = Compound.make_compound(bottoms)
|
||||
result = Compound(bottoms)
|
||||
return result
|
||||
|
||||
def distance(self, other: Shape) -> float:
|
||||
|
|
@ -3093,7 +3087,7 @@ class Shape(NodeMixin):
|
|||
|
||||
logger.debug("finished projecting '%d' faces", len(faces))
|
||||
|
||||
return Compound.make_compound(projected_faces)
|
||||
return Compound(projected_faces)
|
||||
|
||||
def _extrude(
|
||||
self, direction: VectorLike
|
||||
|
|
@ -3136,7 +3130,7 @@ class Shape(NodeMixin):
|
|||
topods_solid = downcast(explorer.Current())
|
||||
solids.append(Solid(topods_solid))
|
||||
explorer.Next()
|
||||
result = Compound.make_compound(solids)
|
||||
result = Compound(solids)
|
||||
else:
|
||||
raise RuntimeError("extrude produced an unexpected result")
|
||||
return result
|
||||
|
|
@ -3791,6 +3785,105 @@ class Compound(Mixin3D, Shape):
|
|||
|
||||
_dim = None
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
obj: TopoDS_Shape = None,
|
||||
label: str = "",
|
||||
color: Color = None,
|
||||
material: str = "",
|
||||
joints: dict[str, Joint] = None,
|
||||
parent: Compound = None,
|
||||
children: Iterable[Shape] = None,
|
||||
):
|
||||
"""Build a Compound from an OCCT TopoDS_Shape/TopoDS_Compound
|
||||
|
||||
Args:
|
||||
obj (TopoDS_Shape, optional): OCCT Compound. Defaults to None.
|
||||
label (str, optional): Defaults to ''.
|
||||
color (Color, optional): Defaults to None.
|
||||
material (str, optional): tag for external tools. Defaults to ''.
|
||||
joints (dict[str, Joint], optional): names joints. Defaults to None.
|
||||
parent (Compound, optional): assembly parent. Defaults to None.
|
||||
children (Iterable[Shape], optional): assembly children. Defaults to None.
|
||||
"""
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
shapes: Iterable[Shape],
|
||||
label: str = "",
|
||||
color: Color = None,
|
||||
material: str = "",
|
||||
joints: dict[str, Joint] = None,
|
||||
parent: Compound = None,
|
||||
children: Iterable[Shape] = None,
|
||||
):
|
||||
"""Build a Compound from Shapes
|
||||
|
||||
Args:
|
||||
shapes (Iterable[Shape]): shapes within the compound
|
||||
label (str, optional): Defaults to ''.
|
||||
color (Color, optional): Defaults to None.
|
||||
material (str, optional): tag for external tools. Defaults to ''.
|
||||
joints (dict[str, Joint], optional): names joints. Defaults to None.
|
||||
parent (Compound, optional): assembly parent. Defaults to None.
|
||||
children (Iterable[Shape], optional): assembly children. Defaults to None.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
shapes, obj, label, color, material, joints, parent, children = (None,) * 8
|
||||
|
||||
if args:
|
||||
l_a = len(args)
|
||||
if isinstance(args[0], TopoDS_Shape):
|
||||
obj, label, color, material, joints, parent, children = args[:7] + (
|
||||
None,
|
||||
) * (7 - l_a)
|
||||
elif isinstance(args[0], Iterable):
|
||||
shapes, label, color, material, joints, parent, children = args[:7] + (
|
||||
None,
|
||||
) * (7 - l_a)
|
||||
|
||||
unknown_args = ", ".join(
|
||||
set(kwargs.keys()).difference(
|
||||
[
|
||||
"shapes",
|
||||
"obj",
|
||||
"label",
|
||||
"material",
|
||||
"color",
|
||||
"joints",
|
||||
"parent",
|
||||
"children",
|
||||
]
|
||||
)
|
||||
)
|
||||
if unknown_args:
|
||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||
|
||||
obj = kwargs.get("obj", obj)
|
||||
shapes = kwargs.get("shapes", shapes)
|
||||
material = kwargs.get("material", material)
|
||||
joints = kwargs.get("joints", joints)
|
||||
label = kwargs.get("label", label)
|
||||
color = kwargs.get("color", color)
|
||||
parent = kwargs.get("parent", parent)
|
||||
children = kwargs.get("children", children)
|
||||
|
||||
if shapes:
|
||||
obj = Compound._make_compound([s.wrapped for s in shapes])
|
||||
|
||||
super().__init__(
|
||||
obj=obj,
|
||||
label="" if label is None else label,
|
||||
color=color,
|
||||
material="" if material is None else material,
|
||||
parent=parent,
|
||||
)
|
||||
self.joints = {} if joints is None else joints
|
||||
self.children = [] if children is None else children
|
||||
|
||||
def __repr__(self):
|
||||
"""Return Compound info as string"""
|
||||
if hasattr(self, "label") and hasattr(self, "children"):
|
||||
|
|
@ -3865,6 +3958,12 @@ class Compound(Mixin3D, Shape):
|
|||
shapes: Iterable[Shape]:
|
||||
Returns:
|
||||
"""
|
||||
warnings.warn(
|
||||
"make_compound() will be deprecated - use the Compound constructor instead",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
return cls(Compound._make_compound([s.wrapped for s in shapes]))
|
||||
|
||||
def _remove(self, shape: Shape) -> Compound:
|
||||
|
|
@ -4079,9 +4178,7 @@ class Compound(Mixin3D, Shape):
|
|||
|
||||
if text_path is not None:
|
||||
path_length = text_path.length
|
||||
text_flat = Compound.make_compound(
|
||||
[position_face(f) for f in text_flat.faces()]
|
||||
)
|
||||
text_flat = Compound([position_face(f) for f in text_flat.faces()])
|
||||
|
||||
return text_flat
|
||||
|
||||
|
|
@ -5322,7 +5419,7 @@ class Face(Shape):
|
|||
inner_wires = inner_wires if inner_wires else []
|
||||
|
||||
# check if wires are coplanar
|
||||
verification_compound = Compound.make_compound([outer_wire] + inner_wires)
|
||||
verification_compound = Compound([outer_wire] + inner_wires)
|
||||
if not BRepLib_FindSurface(
|
||||
verification_compound.wrapped, OnlyPlane=True
|
||||
).Found():
|
||||
|
|
@ -5739,9 +5836,7 @@ class Face(Shape):
|
|||
Returns:
|
||||
ShapeList[Face]: Face(s) projected on target object ordered by distance
|
||||
"""
|
||||
max_dimension = (
|
||||
Compound.make_compound([self, target_object]).bounding_box().diagonal
|
||||
)
|
||||
max_dimension = Compound([self, target_object]).bounding_box().diagonal
|
||||
if taper == 0:
|
||||
face_extruded = Solid.extrude(self, Vector(direction) * max_dimension)
|
||||
else:
|
||||
|
|
@ -5823,7 +5918,7 @@ class Face(Shape):
|
|||
bool: indicating whether or not point is within Face
|
||||
|
||||
"""
|
||||
return Compound.make_compound([self]).is_inside(point, tolerance)
|
||||
return Compound([self]).is_inside(point, tolerance)
|
||||
|
||||
|
||||
class Shell(Shape):
|
||||
|
|
@ -6244,11 +6339,7 @@ class Solid(Mixin3D, Shape):
|
|||
|
||||
# make straight spine
|
||||
straight_spine_e = Edge.make_line(center, center.add(normal))
|
||||
straight_spine_w = Wire.combine(
|
||||
[
|
||||
straight_spine_e,
|
||||
]
|
||||
)[0].wrapped
|
||||
straight_spine_w = Wire.combine([straight_spine_e])[0].wrapped
|
||||
|
||||
# make an auxiliary spine
|
||||
pitch = 360.0 / angle * normal.length
|
||||
|
|
@ -6268,7 +6359,7 @@ class Solid(Mixin3D, Shape):
|
|||
]
|
||||
|
||||
# combine the inner solids into compound
|
||||
inner_comp = Compound.make_compound(inner_solids).wrapped
|
||||
inner_comp = Compound._make_compound(inner_solids)
|
||||
|
||||
# subtract from the outer solid
|
||||
return Solid(BRepAlgoAPI_Cut(outer_solid, inner_comp).Shape())
|
||||
|
|
@ -6304,9 +6395,7 @@ class Solid(Mixin3D, Shape):
|
|||
direction *= -1
|
||||
until = Until.NEXT if until == Until.PREVIOUS else Until.LAST
|
||||
|
||||
max_dimension = (
|
||||
Compound.make_compound([section, target_object]).bounding_box().diagonal
|
||||
)
|
||||
max_dimension = Compound([section, target_object]).bounding_box().diagonal
|
||||
clipping_direction = (
|
||||
direction * max_dimension
|
||||
if until == Until.NEXT
|
||||
|
|
@ -6866,7 +6955,7 @@ class Wire(Mixin1D, Shape):
|
|||
edges_in = TopTools_HSequenceOfShape()
|
||||
wires_out = TopTools_HSequenceOfShape()
|
||||
|
||||
for edge in Compound.make_compound(wires).edges():
|
||||
for edge in Compound(wires).edges():
|
||||
edges_in.Append(edge.wrapped)
|
||||
|
||||
ShapeAnalysis_FreeBounds.ConnectEdgesToWires_s(edges_in, tol, False, wires_out)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class AddTests(unittest.TestCase):
|
|||
# Add Compound
|
||||
with BuildPart() as test:
|
||||
add(
|
||||
Compound.make_compound(
|
||||
Compound(
|
||||
[
|
||||
Solid.make_box(10, 10, 10),
|
||||
Solid.make_box(5, 5, 5, Plane((20, 20, 20))),
|
||||
|
|
@ -116,7 +116,7 @@ class AddTests(unittest.TestCase):
|
|||
)
|
||||
self.assertAlmostEqual(test.part.volume, 1125, 5)
|
||||
with BuildPart() as test:
|
||||
add(Compound.make_compound([Edge.make_line((0, 0), (1, 1))]))
|
||||
add(Compound([Edge.make_line((0, 0), (1, 1))]))
|
||||
self.assertEqual(len(test.pending_edges), 1)
|
||||
|
||||
# Add Wire
|
||||
|
|
@ -435,7 +435,7 @@ class MirrorTests(unittest.TestCase):
|
|||
edge = Edge.make_line((1, 0), (2, 0))
|
||||
wire = Wire.make_circle(1, Plane((5, 0, 0)))
|
||||
face = Face.make_rect(2, 2, Plane((8, 0)))
|
||||
compound = Compound.make_compound(
|
||||
compound = Compound(
|
||||
[
|
||||
Face.make_rect(2, 2, Plane((8, 8))),
|
||||
Face.make_rect(2, 2, Plane((8, -8))),
|
||||
|
|
|
|||
|
|
@ -740,32 +740,32 @@ class TestCompound(DirectApiTestCase):
|
|||
def test_fuse(self):
|
||||
box1 = Solid.make_box(1, 1, 1)
|
||||
box2 = Solid.make_box(1, 1, 1, Plane((1, 0, 0)))
|
||||
combined = Compound.make_compound([box1]).fuse(box2, glue=True)
|
||||
combined = Compound([box1]).fuse(box2, glue=True)
|
||||
self.assertTrue(combined.is_valid())
|
||||
self.assertAlmostEqual(combined.volume, 2, 5)
|
||||
fuzzy = Compound.make_compound([box1]).fuse(box2, tol=1e-6)
|
||||
fuzzy = Compound([box1]).fuse(box2, tol=1e-6)
|
||||
self.assertTrue(fuzzy.is_valid())
|
||||
self.assertAlmostEqual(fuzzy.volume, 2, 5)
|
||||
|
||||
def test_remove(self):
|
||||
box1 = Solid.make_box(1, 1, 1)
|
||||
box2 = Solid.make_box(1, 1, 1, Plane((2, 0, 0)))
|
||||
combined = Compound.make_compound([box1, box2])
|
||||
combined = Compound([box1, box2])
|
||||
self.assertTrue(len(combined._remove(box2).solids()), 1)
|
||||
|
||||
def test_repr(self):
|
||||
simple = Compound.make_compound([Solid.make_box(1, 1, 1)])
|
||||
simple = Compound([Solid.make_box(1, 1, 1)])
|
||||
simple_str = repr(simple).split("0x")[0] + repr(simple).split(", ")[1]
|
||||
self.assertEqual(simple_str, "Compound at label()")
|
||||
|
||||
assembly = Compound.make_compound([Solid.make_box(1, 1, 1)])
|
||||
assembly = Compound([Solid.make_box(1, 1, 1)])
|
||||
assembly.children = [Solid.make_box(1, 1, 1)]
|
||||
assembly.label = "test"
|
||||
assembly_str = repr(assembly).split("0x")[0] + repr(assembly).split(", l")[1]
|
||||
self.assertEqual(assembly_str, "Compound at abel(test), #children(1)")
|
||||
|
||||
def test_center(self):
|
||||
test_compound = Compound.make_compound(
|
||||
test_compound = Compound(
|
||||
[
|
||||
Solid.make_box(2, 2, 2).locate(Location((-1, -1, -1))),
|
||||
Solid.make_box(1, 1, 1).locate(Location((8.5, -0.5, -0.5))),
|
||||
|
|
@ -807,6 +807,10 @@ class TestCompound(DirectApiTestCase):
|
|||
self.assertAlmostEqual(c.volume, 3, 5)
|
||||
# N.B. b and bb overlap but still add to Compound volume
|
||||
|
||||
def test_constructor(self):
|
||||
with self.assertRaises(ValueError):
|
||||
Compound(bob="fred")
|
||||
|
||||
|
||||
class TestEdge(DirectApiTestCase):
|
||||
def test_close(self):
|
||||
|
|
@ -3666,4 +3670,4 @@ class TestWire(DirectApiTestCase):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main(failfast=True)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ class TestAddShape(DirectApiTestCase):
|
|||
exporter = Mesher()
|
||||
box = Solid.make_box(1, 1, 1)
|
||||
cone = Solid.make_cone(1, 0, 2).locate(Location((0, -1, 0)))
|
||||
shape_assembly = Compound.make_compound([box, cone])
|
||||
shape_assembly = Compound([box, cone])
|
||||
exporter.add_shape(shape_assembly)
|
||||
exporter.write("test.3mf")
|
||||
importer = Mesher()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class TestPersistence(unittest.TestCase):
|
|||
wire = Wire.make_circle(10)
|
||||
face = Face.make_rect(10, 5)
|
||||
solid = Solid.make_box(10, 5, 2)
|
||||
compound = Compound.make_compound([edge, wire, face, solid])
|
||||
compound = Compound([edge, wire, face, solid])
|
||||
|
||||
buffer = serialize_shape(edge.wrapped)
|
||||
retrived_edge = deserialize_shape(buffer)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue