From 0eae3de6a2e3f2354a4a9abc0ad311d82635cf98 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 3 Oct 2022 23:29:59 +1100 Subject: [PATCH] Openings now move with the host by default. Small change, big impact. --- .../blenderbim/bim/module/model/opening.py | 2 + .../api/geometry/edit_object_placement.py | 8 +++- .../geometry/test_edit_object_placement.py | 48 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/opening.py b/src/blenderbim/blenderbim/bim/module/model/opening.py index 3fca869690..abbeeb510f 100644 --- a/src/blenderbim/blenderbim/bim/module/model/opening.py +++ b/src/blenderbim/blenderbim/bim/module/model/opening.py @@ -417,6 +417,8 @@ class ShowOpenings(Operator, tool.Ifc.Operator): element = tool.Ifc.get_entity(obj) if not element: continue + if tool.Ifc.is_moved(obj): + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) openings = tool.Model.load_openings(element, [r.RelatedOpeningElement for r in element.HasOpenings]) for opening in openings: new = props.openings.add() diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py index 64d16873f0..0830bbfbbb 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py @@ -104,9 +104,13 @@ class Usecase: for referenced_placement in placement.ReferencedByPlacements: matrix = ifcopenshell.util.placement.get_local_placement(referenced_placement) for obj in referenced_placement.PlacesObject: - # Although a port is technically a nested child, it is generally - # more intuitive that the ports always move with the parent. if obj.is_a("IfcDistributionPort"): + # Although a port is technically a nested child, it is generally + # more intuitive that the ports always move with the parent. + continue + elif obj.is_a("IfcFeatureElement"): + # Feature elements affect the geometry of their parent, and + # so logically should always move with the parent. continue results.append({"product": obj, "matrix": matrix, "is_si": False, "should_transform_children": False}) results.extend(self.get_children_settings(referenced_placement)) diff --git a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py index bd0d24b728..a63bb2446b 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py +++ b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py @@ -541,6 +541,54 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(subelement.ObjectPlacement), shifted_submatrix) assert subelement.ObjectPlacement.PlacementRelTo == element.ObjectPlacement + def test_changing_placements_always_affecting_child_features_as_a_special_case(self): + ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + ifcopenshell.api.run("unit.assign_unit", self.file) + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcOpeningElement") + matrix = numpy.array( + ( + (1.0, 0.0, 0.0, 1.0), + (0.0, 1.0, 0.0, 1.0), + (0.0, 0.0, 1.0, 1.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + submatrix = numpy.array( + ( + (1.0, 0.0, 0.0, 1.0), + (0.0, 1.0, 0.0, 2.0), + (0.0, 0.0, 1.0, 3.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + shifted_submatrix = numpy.array( + ( + (1.0, 0.0, 0.0, 1.0), + (0.0, 1.0, 0.0, 3.0), + (0.0, 0.0, 1.0, 5.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + ifcopenshell.api.run("void.add_opening", self.file, opening=subelement, element=element) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=element, matrix=matrix.copy(), is_si=False + ) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=subelement, matrix=submatrix.copy(), is_si=False + ) + ifcopenshell.api.run( + "geometry.edit_object_placement", + self.file, + product=element, + matrix=submatrix.copy(), + is_si=False, + should_transform_children=False, + ) + assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement), submatrix) + assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(subelement.ObjectPlacement), shifted_submatrix) + assert subelement.ObjectPlacement.PlacementRelTo == element.ObjectPlacement + class TestEditObjectPlacementIFC2X3(test.bootstrap.IFC2X3): def test_changing_placements_relative_to_a_distribution_element(self):