mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 21:42:19 +00:00
edit_object_placement optimization for objects with subchildren #4035
1) We were iterating over same subchildren 2 or more times. 2) There is no need to change subchildren position at all since their parent position is already adjusted. Explained here in detail - https://github.com/IfcOpenShell/IfcOpenShell/issues/4035#issuecomment-1822824352
This commit is contained in:
@@ -100,6 +100,8 @@ class Usecase:
|
|||||||
if not placement:
|
if not placement:
|
||||||
return []
|
return []
|
||||||
results = []
|
results = []
|
||||||
|
# NOTE: we ignore subchildren as we already adjust position for their parent
|
||||||
|
# therefore they're not present in `results` and `should_transform_children` should be `True`
|
||||||
for referenced_placement in placement.ReferencedByPlacements:
|
for referenced_placement in placement.ReferencedByPlacements:
|
||||||
matrix = ifcopenshell.util.placement.get_local_placement(referenced_placement)
|
matrix = ifcopenshell.util.placement.get_local_placement(referenced_placement)
|
||||||
for obj in referenced_placement.PlacesObject:
|
for obj in referenced_placement.PlacesObject:
|
||||||
@@ -111,8 +113,7 @@ class Usecase:
|
|||||||
# Feature elements affect the geometry of their parent, and
|
# Feature elements affect the geometry of their parent, and
|
||||||
# so logically should always move with the parent.
|
# so logically should always move with the parent.
|
||||||
continue
|
continue
|
||||||
results.append({"product": obj, "matrix": matrix, "is_si": False, "should_transform_children": False})
|
results.append({"product": obj, "matrix": matrix, "is_si": False, "should_transform_children": True})
|
||||||
results.extend(self.get_children_settings(referenced_placement))
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def get_relative_placement(self, placement_rel_to):
|
def get_relative_placement(self, placement_rel_to):
|
||||||
|
|||||||
@@ -582,6 +582,47 @@ class TestEditObjectPlacement(test.bootstrap.IFC4):
|
|||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
self.file.by_id(previous_placement_id)
|
self.file.by_id(previous_placement_id)
|
||||||
|
|
||||||
|
def test_changing_placements_without_affecting_children_doesnt_affect_subchildren(self):
|
||||||
|
def np_matrix_translation(translation):
|
||||||
|
(m := numpy.eye(4))[:3, 3] = translation
|
||||||
|
return m
|
||||||
|
|
||||||
|
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
|
||||||
|
ifcopenshell.api.run("unit.assign_unit", self.file)
|
||||||
|
|
||||||
|
building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
|
||||||
|
storey = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuildingStorey")
|
||||||
|
ifcopenshell.api.run("aggregate.assign_object", self.file, product=storey, relating_object=building)
|
||||||
|
wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
|
ifcopenshell.api.run("spatial.assign_container", self.file, product=wall, relating_structure=storey)
|
||||||
|
|
||||||
|
matrix = np_matrix_translation((1, 1, 1))
|
||||||
|
submatrix = np_matrix_translation((1, 2, 3))
|
||||||
|
building_placement_id = ifcopenshell.api.run(
|
||||||
|
"geometry.edit_object_placement", self.file, product=building, matrix=matrix.copy(), is_si=False
|
||||||
|
).id()
|
||||||
|
storey_placement_id = ifcopenshell.api.run(
|
||||||
|
"geometry.edit_object_placement", self.file, product=storey, matrix=matrix.copy(), is_si=False
|
||||||
|
).id()
|
||||||
|
wall_placement_id = ifcopenshell.api.run(
|
||||||
|
"geometry.edit_object_placement", self.file, product=wall, matrix=matrix.copy(), is_si=False
|
||||||
|
).id()
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.edit_object_placement",
|
||||||
|
self.file,
|
||||||
|
product=building,
|
||||||
|
matrix=submatrix.copy(),
|
||||||
|
is_si=False,
|
||||||
|
)
|
||||||
|
# product and it's children have their placement rebuilt
|
||||||
|
with pytest.raises(RuntimeError):
|
||||||
|
self.file.by_id(building_placement_id)
|
||||||
|
with pytest.raises(RuntimeError):
|
||||||
|
self.file.by_id(storey_placement_id)
|
||||||
|
# subchildren are unaffected, exception is not raised
|
||||||
|
self.file.by_id(wall_placement_id)
|
||||||
|
assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(wall.ObjectPlacement), matrix)
|
||||||
|
|
||||||
|
|
||||||
class TestEditObjectPlacementIFC2X3(test.bootstrap.IFC2X3):
|
class TestEditObjectPlacementIFC2X3(test.bootstrap.IFC2X3):
|
||||||
def test_changing_placements_relative_to_a_distribution_element(self):
|
def test_changing_placements_relative_to_a_distribution_element(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user