mirror of
https://github.com/gumyr/build123d.git
synced 2026-01-30 04:10:34 -08:00
Added options to center, ShapeList __add__
This commit is contained in:
parent
c7488db18c
commit
2e763af10f
2 changed files with 92 additions and 56 deletions
|
|
@ -203,3 +203,14 @@ class Direction(Enum):
|
|||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__}.{self.name}>"
|
||||
|
||||
|
||||
class CenterOf(Enum):
|
||||
"""Center Options"""
|
||||
|
||||
UV = auto()
|
||||
MASS = auto()
|
||||
BOUNDING_BOX = auto()
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__}.{self.name}>"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ from .build_enums import (
|
|||
PositionMode,
|
||||
FrameMethod,
|
||||
Direction,
|
||||
CenterOf,
|
||||
)
|
||||
from typing_extensions import Literal
|
||||
from io import BytesIO
|
||||
|
|
@ -550,9 +551,7 @@ class Vector:
|
|||
return Vector(self.wrapped.Normalized())
|
||||
|
||||
def center(self) -> Vector:
|
||||
"""
|
||||
|
||||
Args:
|
||||
"""center
|
||||
|
||||
Returns:
|
||||
The center of myself is myself.
|
||||
|
|
@ -1489,12 +1488,31 @@ class Mixin1D:
|
|||
|
||||
return return_value
|
||||
|
||||
def center(self) -> Vector:
|
||||
def center(self, center_of: CenterOf = CenterOf.UV) -> Vector:
|
||||
"""Center of object
|
||||
|
||||
properties = GProp_GProps()
|
||||
BRepGProp.LinearProperties_s(self.wrapped, properties)
|
||||
Return the center based on center_of
|
||||
|
||||
return Vector(properties.CentreOfMass())
|
||||
Args:
|
||||
center_of (CenterOf, optional): centering option. Defaults to CenterOf.UV.
|
||||
|
||||
Returns:
|
||||
Vector: center
|
||||
"""
|
||||
if center_of == CenterOf.UV:
|
||||
middle = self.position_at(0.5)
|
||||
elif center_of == CenterOf.MASS:
|
||||
properties = GProp_GProps()
|
||||
BRepGProp.LinearProperties_s(self.wrapped, properties)
|
||||
middle = Vector(properties.CentreOfMass())
|
||||
elif center_of == CenterOf.BOUNDING_BOX:
|
||||
b_box: BoundBox = self.bounding_box()
|
||||
middle = Vector(
|
||||
(b_box.xmin + b_box.xmax) / 2,
|
||||
(b_box.ymin + b_box.ymax) / 2,
|
||||
(b_box.zmin + b_box.zmax) / 2,
|
||||
)
|
||||
return middle
|
||||
|
||||
def length(self) -> float:
|
||||
|
||||
|
|
@ -2226,30 +2244,30 @@ class Shape:
|
|||
|
||||
return Vector(properties.CentreOfMass())
|
||||
|
||||
def center(self) -> Vector:
|
||||
"""
|
||||
def center(self, center_of: CenterOf = CenterOf.MASS) -> Vector:
|
||||
"""Return center of object
|
||||
|
||||
Find center of object
|
||||
|
||||
Args:
|
||||
center_of (CenterOf, optional): center option. Defaults to CenterOf.UV.
|
||||
|
||||
Returns:
|
||||
The point of the center of mass of this Shape
|
||||
|
||||
Vector: center
|
||||
"""
|
||||
|
||||
return Shape.center_of_mass(self)
|
||||
|
||||
def center_of_bound_box(self, tolerance: float = None) -> Vector:
|
||||
"""
|
||||
|
||||
Args:
|
||||
tolerance: Tolerance passed to the :py:meth:`bounding_box` method
|
||||
tolerance: float: (Default value = None)
|
||||
|
||||
Returns:
|
||||
center of the bounding box of this shape
|
||||
|
||||
"""
|
||||
return self.bounding_box(tolerance=tolerance).center
|
||||
if center_of == CenterOf.UV:
|
||||
raise ValueError("Center of UV is not supported for this object")
|
||||
if center_of == CenterOf.MASS:
|
||||
properties = GProp_GProps()
|
||||
calc_function = shape_properties_LUT[shapetype(self.wrapped)]
|
||||
if calc_function:
|
||||
calc_function(self.wrapped, properties)
|
||||
middle = Vector(properties.CentreOfMass())
|
||||
else:
|
||||
raise NotImplementedError
|
||||
elif center_of == CenterOf.BOUNDING_BOX:
|
||||
middle = self.bounding_box(tolerance=1e-6).center
|
||||
return middle
|
||||
|
||||
@staticmethod
|
||||
def combined_center(objects: Iterable[Shape]) -> Vector:
|
||||
|
|
@ -2293,26 +2311,6 @@ class Shape:
|
|||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def center_of_mass(obj: Shape) -> Vector:
|
||||
"""Calculates the center of 'mass' of an object.
|
||||
|
||||
Args:
|
||||
obj: Compute the center of mass of this object
|
||||
obj: Shape:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
properties = GProp_GProps()
|
||||
calc_function = shape_properties_LUT[shapetype(obj.wrapped)]
|
||||
|
||||
if calc_function:
|
||||
calc_function(obj.wrapped, properties)
|
||||
return Vector(properties.CentreOfMass())
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def combined_center_of_bound_box(objects: list[Shape]) -> Vector:
|
||||
"""Calculates the center of a bounding box of multiple objects.
|
||||
|
|
@ -3474,22 +3472,24 @@ class ShapeList(list):
|
|||
|
||||
return ShapeList(objects).sort_by(axis)
|
||||
|
||||
def filter_by_type(
|
||||
self,
|
||||
geom_type: GeomType,
|
||||
):
|
||||
def filter_by_type(self, geom_type: GeomType, reverse: bool = False):
|
||||
"""filter by type
|
||||
|
||||
Filter the objects by the provided type. Note that not all types apply to all
|
||||
objects.
|
||||
|
||||
Args:
|
||||
type (Type): type to sort by
|
||||
geom_type (GeomType): type to sort by
|
||||
reverse (bool): invert the filter
|
||||
|
||||
Returns:
|
||||
ShapeList: filtered list of objects
|
||||
"""
|
||||
result = filter(lambda o: o.geom_type() == geom_type.name, self)
|
||||
if reverse:
|
||||
result = filter(lambda o: o.geom_type() != geom_type.name, self)
|
||||
else:
|
||||
result = filter(lambda o: o.geom_type() == geom_type.name, self)
|
||||
|
||||
return ShapeList(result)
|
||||
|
||||
def sort_by(self, sort_by: Union[Axis, SortBy] = Axis.Z, reverse: bool = False):
|
||||
|
|
@ -3572,6 +3572,10 @@ class ShapeList(list):
|
|||
"""Filter by geometry type operator"""
|
||||
return self.filter_by_type(geom_type)
|
||||
|
||||
def __add__(self, other: ShapeList):
|
||||
"""Combine two ShapeLists together"""
|
||||
return ShapeList(list(self) + list(other))
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Return slices of ShapeList as ShapeList"""
|
||||
if isinstance(key, slice):
|
||||
|
|
@ -4897,12 +4901,33 @@ class Face(Shape):
|
|||
|
||||
return Vector(vn)
|
||||
|
||||
def center(self) -> Vector:
|
||||
def center(self, center_of: CenterOf = CenterOf.UV) -> Vector:
|
||||
"""Center of object
|
||||
|
||||
properties = GProp_GProps()
|
||||
BRepGProp.SurfaceProperties_s(self.wrapped, properties)
|
||||
Return the center based on center_of
|
||||
|
||||
return Vector(properties.CentreOfMass())
|
||||
Args:
|
||||
center_of (CenterOf, optional): centering option. Defaults to CenterOf.UV.
|
||||
|
||||
Returns:
|
||||
Vector: center
|
||||
"""
|
||||
if center_of == CenterOf.MASS:
|
||||
properties = GProp_GProps()
|
||||
BRepGProp.LinearProperties_s(self.wrapped, properties)
|
||||
middle = Vector(properties.CentreOfMass())
|
||||
elif center_of == CenterOf.UV:
|
||||
u0, u1, v0, v1 = self._uv_bounds()
|
||||
u = 0.5 * (u0 + u1)
|
||||
v = 0.5 * (v0 + v1)
|
||||
|
||||
p = gp_Pnt()
|
||||
vn = gp_Vec()
|
||||
BRepGProp_Face(self.wrapped).Normal(u, v, p, vn)
|
||||
middle = Vector(p)
|
||||
elif center_of == CenterOf.BOUNDING_BOX:
|
||||
middle = self.bounding_box().center
|
||||
return middle
|
||||
|
||||
def outer_wire(self) -> Wire:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue