mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Fixed 3d offset - Issue #74
This commit is contained in:
parent
9a15088ba2
commit
755994f8c5
4 changed files with 65 additions and 10 deletions
|
|
@ -153,7 +153,7 @@ Cheat Sheet
|
|||
+----------+---------------------+-----------------------------------------+---------------------------------------------+
|
||||
| Operator | Operand | Method | Description |
|
||||
+==========+=====================+=========================================+=============================================+
|
||||
| == | Any | :meth:`~direct_api.Shape.is_equal` | Compare CAD objects not including meta data |
|
||||
| == | Any | :meth:`~direct_api.Shape.is_same` | Compare CAD objects not including meta data |
|
||||
+----------+---------------------+-----------------------------------------+---------------------------------------------+
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ class Offset(Compound):
|
|||
else:
|
||||
openings_in_this_solid = []
|
||||
new_solids.append(
|
||||
solid.shell(openings_in_this_solid, amount, kind=kind).fix()
|
||||
solid.offset_3d(openings_in_this_solid, amount, kind=kind).fix()
|
||||
)
|
||||
|
||||
new_objects = new_wires + new_faces + new_solids
|
||||
|
|
|
|||
|
|
@ -2066,6 +2066,64 @@ class Mixin3D:
|
|||
|
||||
return return_value
|
||||
|
||||
def offset_3d(
|
||||
self,
|
||||
openings: Optional[Iterable[Face]],
|
||||
thickness: float,
|
||||
tolerance: float = 0.0001,
|
||||
kind: Kind = Kind.ARC,
|
||||
) -> Solid:
|
||||
"""Shell
|
||||
|
||||
Make an offset solid of self.
|
||||
|
||||
Args:
|
||||
openings (Optional[Iterable[Face]]): List of faces to be removed,
|
||||
which must be part of the solid. Can be an empty list.
|
||||
thickness (float): offset amount - positive offset outwards, negative inwards
|
||||
tolerance (float, optional): modelling tolerance of the method. Defaults to 0.0001.
|
||||
kind (Kind, optional): intersection type. Defaults to Kind.ARC.
|
||||
|
||||
Raises:
|
||||
ValueError: Kind.TANGENT not supported
|
||||
|
||||
Returns:
|
||||
Solid: A shelled solid.
|
||||
"""
|
||||
if kind == Kind.TANGENT:
|
||||
raise ValueError("Kind.TANGENT not supported")
|
||||
|
||||
kind_dict = {
|
||||
Kind.ARC: GeomAbs_JoinType.GeomAbs_Arc,
|
||||
Kind.INTERSECTION: GeomAbs_JoinType.GeomAbs_Intersection,
|
||||
Kind.TANGENT: GeomAbs_JoinType.GeomAbs_Tangent,
|
||||
}
|
||||
|
||||
occ_faces_list = TopTools_ListOfShape()
|
||||
for face in openings:
|
||||
occ_faces_list.Append(face.wrapped)
|
||||
|
||||
offset_builder = BRepOffsetAPI_MakeThickSolid()
|
||||
offset_builder.MakeThickSolidByJoin(
|
||||
self.wrapped,
|
||||
occ_faces_list,
|
||||
thickness,
|
||||
tolerance,
|
||||
Intersection=True,
|
||||
RemoveIntEdges=True,
|
||||
Join=kind_dict[kind],
|
||||
)
|
||||
offset_builder.Build()
|
||||
|
||||
offset_occt_solid = offset_builder.Shape()
|
||||
offset_solid = self.__class__(offset_occt_solid)
|
||||
|
||||
# The Solid can be inverted, if so reverse
|
||||
if offset_solid.volume < 0:
|
||||
offset_solid.wrapped.Reverse()
|
||||
|
||||
return offset_solid
|
||||
|
||||
def is_inside(self, point: VectorLike, tolerance: float = 1.0e-6) -> bool:
|
||||
"""Returns whether or not the point is inside a solid or compound
|
||||
object within the specified tolerance.
|
||||
|
|
@ -2635,8 +2693,8 @@ class Shape(NodeMixin):
|
|||
return self.wrapped.IsEqual(other.wrapped)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
"""Are shapes equal?"""
|
||||
return self.is_equal(other) if isinstance(other, Shape) else False
|
||||
"""Are shapes same?"""
|
||||
return self.is_same(other) if isinstance(other, Shape) else False
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
"""Returns True if no defect is detected on the shape S or any of its
|
||||
|
|
|
|||
|
|
@ -163,12 +163,9 @@ class TestOffset(unittest.TestCase):
|
|||
|
||||
def test_box_offset(self):
|
||||
with BuildPart() as test:
|
||||
Box(1, 1, 1)
|
||||
Offset(
|
||||
amount=1,
|
||||
kind=Kind.INTERSECTION,
|
||||
)
|
||||
self.assertAlmostEqual(test.part.volume, 3**3 - 1**3, 5)
|
||||
Box(10, 10, 10)
|
||||
Offset(amount=-1, kind=Kind.INTERSECTION, mode=Mode.SUBTRACT)
|
||||
self.assertAlmostEqual(test.part.volume, 10**3 - 8**3, 5)
|
||||
|
||||
def test_box_offset_with_opening(self):
|
||||
with BuildPart() as test:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue