Fix bug when shifting object placements and their children. Add support for specifying placement matrixes in project units or SI units.

This commit is contained in:
Dion Moult
2021-09-17 16:54:53 +10:00
parent 02a68f6827
commit 2b82eaf019
2 changed files with 369 additions and 20 deletions
@@ -8,40 +8,35 @@ import ifcopenshell.util.placement
class Usecase:
def __init__(self, file, **settings):
self.file = file
self.settings = {"product": None, "matrix": np.eye(4), "should_transform_children": False}
self.settings = {"product": None, "matrix": np.eye(4), "is_si": True, "should_transform_children": False}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
print('EXECUTING', self.settings["product"])
if not hasattr(self.settings["product"], "ObjectPlacement"):
return
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
if not self.settings["is_si"]:
self.settings["matrix"][0][3] *= self.unit_scale
self.settings["matrix"][1][3] *= self.unit_scale
self.settings["matrix"][2][3] *= self.unit_scale
children_settings = []
if not self.settings["should_transform_children"]:
print("THIS IS RUNNING")
children_settings = self.get_children_settings(self.settings["product"].ObjectPlacement)
placement_rel_to = None
if hasattr(self.settings["product"], "ContainedInStructure") and self.settings["product"].ContainedInStructure:
placement_rel_to = self.settings["product"].ContainedInStructure[0].RelatingStructure.ObjectPlacement
elif hasattr(self.settings["product"], "Decomposes") and self.settings["product"].Decomposes:
relating_object = self.settings["product"].Decomposes[0].RelatingObject
placement_rel_to = relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif hasattr(self.settings["product"], "VoidsElements") and self.settings["product"].VoidsElements:
relating_object = self.settings["product"].VoidsElements[0].RelatingBuildingElement
placement_rel_to = relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif hasattr(self.settings["product"], "FillsVoids") and self.settings["product"].FillsVoids:
relating_object = self.settings["product"].FillsVoids[0].RelatingOpeningElement
placement_rel_to = relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif hasattr(self.settings["product"], "ProjectsElements") and self.settings["product"].ProjectsElements:
relating_object = self.settings["product"].ProjectsElements[0].RelatingElement
placement_rel_to = relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
placement_rel_to = self.get_placement_rel_to()
placement = self.file.createIfcLocalPlacement(placement_rel_to, self.get_relative_placement(placement_rel_to))
old_placement = self.settings["product"].ObjectPlacement
if old_placement and len(self.file.get_inverse(old_placement)) == 1:
old_placement.PlacementRelTo = None
if old_placement:
self.settings["product"].ObjectPlacement = None
inverses = self.file.get_inverse(old_placement)
for inverse in inverses:
ifcopenshell.util.element.replace_attribute(inverse, old_placement, placement)
old_placement.PlacementRelTo = None
ifcopenshell.util.element.remove_deep(self.file, old_placement)
self.settings["product"].ObjectPlacement = placement
@@ -53,6 +48,22 @@ class Usecase:
return placement
def get_placement_rel_to(self):
if getattr(self.settings["product"], "ContainedInStructure", None):
return self.settings["product"].ContainedInStructure[0].RelatingStructure.ObjectPlacement
elif getattr(self.settings["product"], "Decomposes", None):
relating_object = self.settings["product"].Decomposes[0].RelatingObject
return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif getattr(self.settings["product"], "VoidsElements", None):
relating_object = self.settings["product"].VoidsElements[0].RelatingBuildingElement
return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif getattr(self.settings["product"], "FillsVoids", None):
relating_object = self.settings["product"].FillsVoids[0].RelatingOpeningElement
return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
elif getattr(self.settings["product"], "ProjectsElements", None):
relating_object = self.settings["product"].ProjectsElements[0].RelatingElement
return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None
def get_children_settings(self, placement):
if not placement:
return []
@@ -60,7 +71,7 @@ class Usecase:
for referenced_placement in placement.ReferencedByPlacements:
matrix = ifcopenshell.util.placement.get_local_placement(referenced_placement)
for obj in referenced_placement.PlacesObject:
results.append({"product": obj, "matrix": matrix, "should_transform_children": False})
results.append({"product": obj, "matrix": matrix, "is_si": self.settings["is_si"], "should_transform_children": False})
results.extend(self.get_children_settings(referenced_placement))
return results