Merge remote-tracking branch 'origin/v0.7.0' into v08attempt1

This commit is contained in:
Thomas Krijnen
2024-04-21 11:26:06 +02:00
12 changed files with 152 additions and 46 deletions
@@ -61,11 +61,22 @@ def get_axis2placement(placement: ifcopenshell.entity_instance) -> MatrixType:
:return: A 4x4 numpy matrix
:rtype: np.ndarray[np.ndarray[float]]
"""
if placement.is_a("IfcAxis2Placement3D"):
ifc_class = placement.is_a()
if ifc_class in ("IfcAxis2Placement3D", "IfcAxis2PlacementLinear"):
z = np.array(placement.Axis.DirectionRatios if placement.Axis else (0, 0, 1))
x = np.array(placement.RefDirection.DirectionRatios if placement.RefDirection else (1, 0, 0))
o = placement.Location.Coordinates
elif placement.is_a("IfcAxis2Placement2D"):
location = placement.Location
if coordinates := getattr(location, "Coordinates", None):
o = coordinates
else:
ifc_class = location.is_a("IfcPointByDistanceExpression")
print(
f'WARNING. Placement location of type "{ifc_class}" '
f'is not yet supported and placement {placement} may be placed incorrectly.'
)
o = (0.0, 0.0, 0.0)
elif ifc_class == "IfcAxis2Placement2D":
z = np.array((0, 0, 1))
if placement.RefDirection:
x = np.array(placement.RefDirection.DirectionRatios)
@@ -73,6 +84,13 @@ def get_axis2placement(placement: ifcopenshell.entity_instance) -> MatrixType:
else:
x = np.array((1, 0, 0))
o = (*placement.Location.Coordinates, 0.0)
elif ifc_class == "IfcAxis1Placement":
axis = placement.Axis
z = np.array(axis.DirectionRatios if axis else (0, 0, 1))
x = np.array((1, 0, 0))
o = placement.Location.Coordinates
return a2p(o, z, x)
@@ -233,7 +233,7 @@ class FormatTransformer(lark.Transformer):
def imperial_length(self, args):
if len(args) == 2:
input_unit = "foot"
input_unit, output_unit = "foot", "foot"
value, precision = args
else:
value, precision, input_unit, output_unit = args
@@ -524,7 +524,10 @@ class FacetTransformer(lark.Transformer):
name = name.children[0].value
def filter_function(element):
element_value = getattr(element, name, None)
if name == "PredefinedType":
element_value = ifcopenshell.util.element.get_predefined_type(element)
else:
element_value = getattr(element, name, None)
return self.compare(element_value, comparison, value)
self.elements = set(filter(filter_function, self.elements))
@@ -604,8 +604,8 @@ def format_length(
decimal_places: int = 2,
suppress_zero_inches=True,
unit_system: Literal["metric", "imperial"] = "imperial",
input_unit="foot",
output_unit="foot",
input_unit: Literal["foot", "inch"] = "foot",
output_unit: Literal["foot", "inch"] = "foot",
) -> str:
"""Formats a length for readability and imperial formatting
@@ -165,6 +165,11 @@ class TestFilterElements(test.bootstrap.IFC4):
element.Description = "Foobar"
assert subject.filter_elements(self.file, "IfcWall, Name=Foo, Description=Foobar") == {element}
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type.PredefinedType = "SOLIDWALL"
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert subject.filter_elements(self.file, "IfcWall, PredefinedType=SOLIDWALL") == {element}
def test_selecting_by_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")