mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-15 15:20:37 -08:00
add Shape.relocate
This commit is contained in:
parent
c247077ce2
commit
7582feea13
3 changed files with 53 additions and 2 deletions
|
|
@ -452,7 +452,7 @@ class Vector:
|
|||
def signed_distance_from_plane(self, plane: Plane) -> float:
|
||||
"""Signed distance from plane to point vector."""
|
||||
return (self - plane.origin).dot(plane.z_dir)
|
||||
|
||||
|
||||
def project_to_plane(self, plane: Plane) -> Vector:
|
||||
"""Vector is projected onto the plane provided as input.
|
||||
|
||||
|
|
@ -1145,6 +1145,13 @@ class Location:
|
|||
def __pow__(self, exponent: int) -> Location:
|
||||
return Location(self.wrapped.Powered(exponent))
|
||||
|
||||
def __eq__(self, other: Location):
|
||||
return (
|
||||
isinstance(other, Location)
|
||||
and self.position == other.position
|
||||
and self.orientation == other.orientation
|
||||
)
|
||||
|
||||
def to_axis(self) -> Axis:
|
||||
"""Convert the location into an Axis"""
|
||||
return Axis.Z.located(self)
|
||||
|
|
|
|||
|
|
@ -2029,6 +2029,26 @@ class Shape(NodeMixin):
|
|||
shape_copy.wrapped = downcast(shape_copy.wrapped.Moved(loc.wrapped))
|
||||
return shape_copy
|
||||
|
||||
def relocate(self, loc: Location):
|
||||
"""Change the location of self while keeping it geometrically similar
|
||||
|
||||
Args:
|
||||
loc (Location): new location to set for self
|
||||
"""
|
||||
if self.location != loc:
|
||||
old_ax = gp_Ax3()
|
||||
old_ax.Transform(self.location.wrapped.Transformation())
|
||||
|
||||
new_ax = gp_Ax3()
|
||||
new_ax.Transform(loc.wrapped.Transformation())
|
||||
|
||||
trsf = gp_Trsf()
|
||||
trsf.SetDisplacement(new_ax, old_ax)
|
||||
builder = BRepBuilderAPI_Transform(self.wrapped, trsf, True, True)
|
||||
|
||||
self.wrapped = builder.Shape()
|
||||
self.wrapped.Location(loc.wrapped)
|
||||
|
||||
def distance_to_with_closest_points(
|
||||
self, other: Union[Shape, VectorLike]
|
||||
) -> tuple[float, Vector, Vector]:
|
||||
|
|
|
|||
|
|
@ -1403,6 +1403,16 @@ class TestLocation(DirectApiTestCase):
|
|||
self.assertVectorAlmostEquals(axis.position, (1, 2, 3), 6)
|
||||
self.assertVectorAlmostEquals(axis.direction, (0, 1, 0), 6)
|
||||
|
||||
def test_eq(self):
|
||||
loc = Location((1, 2, 3), (4, 5, 6))
|
||||
diff_posistion = Location((10, 20, 30), (4, 5, 6))
|
||||
diff_orientation = Location((1, 2, 3), (40, 50, 60))
|
||||
same = Location((1, 2, 3), (4, 5, 6))
|
||||
|
||||
self.assertEqual(loc, same)
|
||||
self.assertNotEqual(loc, diff_posistion)
|
||||
self.assertNotEqual(loc, diff_orientation)
|
||||
|
||||
|
||||
class TestMatrix(DirectApiTestCase):
|
||||
def test_matrix_creation_and_access(self):
|
||||
|
|
@ -2214,6 +2224,20 @@ class TestShape(DirectApiTestCase):
|
|||
positive_half, negative_half = [s.clean() for s in sphere.cut(divider).solids()]
|
||||
self.assertGreater(abs(positive_half.volume - negative_half.volume), 0, 1)
|
||||
|
||||
def test_relocate(self):
|
||||
box = Solid.make_box(10, 10, 10).move(Location((20, -5, -5)))
|
||||
cylinder = Solid.make_cylinder(2, 50).move(Location((0, 0, 0), (0, 90, 0)))
|
||||
|
||||
box_with_hole = box.cut(cylinder)
|
||||
box_with_hole.relocate(box.location)
|
||||
|
||||
self.assertEqual(box.location, box_with_hole.location)
|
||||
|
||||
bbox1 = box.bounding_box()
|
||||
bbox2 = box_with_hole.bounding_box()
|
||||
self.assertVectorAlmostEquals(bbox1.min, bbox2.min, 5)
|
||||
self.assertVectorAlmostEquals(bbox1.max, bbox2.max, 5)
|
||||
|
||||
|
||||
class TestShapeList(DirectApiTestCase):
|
||||
"""Test ShapeList functionality"""
|
||||
|
|
@ -2490,7 +2514,7 @@ class TestVector(DirectApiTestCase):
|
|||
"""
|
||||
Test line distance from plane.
|
||||
"""
|
||||
v = Vector(1,2,3)
|
||||
v = Vector(1, 2, 3)
|
||||
|
||||
self.assertAlmostEqual(1, v.signed_distance_from_plane(Plane.YZ))
|
||||
self.assertAlmostEqual(2, v.signed_distance_from_plane(Plane.ZX))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue