Merge branch 'v0.7.0' into v0.8.0

This commit is contained in:
Dion Moult
2024-06-07 23:48:39 +10:00
776 changed files with 34282 additions and 27706 deletions
@@ -17,10 +17,13 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import numpy as np
import numpy.typing as npt
import ifcopenshell
from typing import Literal, Iterable
from typing import Literal, Iterable, Optional
MatrixType = np.ndarray[np.ndarray[float]]
MatrixType = npt.NDArray[np.float64]
"""`npt.NDArray[np.float64]`"""
def a2p(o: Iterable[float], z: Iterable[float], x: Iterable[float]) -> MatrixType:
@@ -36,7 +39,7 @@ def a2p(o: Iterable[float], z: Iterable[float], x: Iterable[float]) -> MatrixTyp
:param x: The +X vector / axis of the matrix
:type x: iterable[float]
:return: A 4x4 numpy matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
x = x / np.linalg.norm(x)
z = z / np.linalg.norm(z)
@@ -57,9 +60,9 @@ def get_axis2placement(placement: ifcopenshell.entity_instance) -> MatrixType:
should use ``get_local_placement`` instead.
:param placement: The IfcLocalPlacement enitity
:type placement: ifcopenshell.entity_instance.entity_instance
:type placement: ifcopenshell.entity_instance
:return: A 4x4 numpy matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
ifc_class = placement.is_a()
if ifc_class in ("IfcAxis2Placement3D", "IfcAxis2PlacementLinear"):
@@ -70,11 +73,11 @@ def get_axis2placement(placement: ifcopenshell.entity_instance) -> MatrixType:
o = coordinates
else:
import ifcopenshell.geom
st = ifcopenshell.geom.settings()
st.set('convert-back-units', True)
shp = ifcopenshell.geom.create_shape(st, placement)
return np.array(shp.matrix).reshape((4, 4), order="F")
settings = ifcopenshell.geom.settings()
settings.set('convert-back-units', True)
shape = ifcopenshell.geom.create_shape(settings, placement)
return np.array(shape.matrix).reshape((4, 4), order="F")
elif ifc_class == "IfcAxis2Placement2D":
z = np.array((0, 0, 1))
if placement.RefDirection:
@@ -93,7 +96,7 @@ def get_axis2placement(placement: ifcopenshell.entity_instance) -> MatrixType:
return a2p(o, z, x)
def get_local_placement(placement: ifcopenshell.entity_instance) -> MatrixType:
def get_local_placement(placement: Optional[ifcopenshell.entity_instance] = None) -> MatrixType:
"""Parse a local placement into a 4x4 transformation matrix
This is typically used to find the location and rotation of an element. The
@@ -114,9 +117,9 @@ def get_local_placement(placement: ifcopenshell.entity_instance) -> MatrixType:
matrix = ifcopenshell.util.placement.get_local_placement(placement)
:param placement: The IfcLocalPlacement entity
:type placement: ifcopenshell.entity_instance.entity_instance
:type placement: ifcopenshell.entity_instance, optional
:return: A 4x4 numpy matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
if placement is None:
return np.eye(4)
@@ -134,9 +137,9 @@ def get_cartesiantransformationoperator3d(inst: ifcopenshell.entity_instance) ->
``get_mappeditem_transformation`` instead.
:param item: The IfcCartesianTransformationOperator entity
:type item: ifcopenshell.entity_instance.entity_instance
:type item: ifcopenshell.entity_instance
:return: A 4x4 numpy transformation matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
origin = np.array(inst.LocalOrigin.Coordinates)
axis1 = np.array((1.0, 0.0, 0.0))
@@ -180,9 +183,9 @@ def get_mappeditem_transformation(item: ifcopenshell.entity_instance) -> MatrixT
transformation matrix.
:param item: The IfcMappedItem entity
:type item: ifcopenshell.entity_instance.entity_instance
:type item: ifcopenshell.entity_instance
:return: A 4x4 numpy transformation matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
m4 = get_axis2placement(item.MappingSource.MappingOrigin)
# TODO 2d
@@ -197,7 +200,7 @@ def get_storey_elevation(storey: ifcopenshell.entity_instance) -> float:
its placement, or as a fallback the ``Elevation`` attribute.
:param storey: The IfcBuildingStorey entity
:type storey: ifcopenshell.entity_instance.entity_instance
:type storey: ifcopenshell.entity_instance
:return: The elevation in project units
:rtype: float
"""
@@ -218,7 +221,7 @@ def rotation(angle: float, axis: Literal["X", "Y", "Z"], is_degrees=True) -> Mat
radians. Defaults to true (i.e. degrees).
:type is_degrees: bool
:return: A 4x4 numpy rotation matrix
:rtype: np.ndarray[np.ndarray[float]]
:rtype: MatrixType
"""
theta = np.radians(angle) if is_degrees else angle
cos, sin = np.cos(theta), np.sin(theta)