mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Fix #3996. Reassigning occurrences or types now also reassigns the correlating occurrence or type.
This commit is contained in:
@@ -103,17 +103,33 @@ class ReassignClass(bpy.types.Operator):
|
||||
predefined_type = context.scene.BIMRootProperties.ifc_predefined_type
|
||||
if predefined_type == "USERDEFINED":
|
||||
predefined_type = context.scene.BIMRootProperties.ifc_userdefined_type
|
||||
reassigned_elements = set()
|
||||
for obj in objects:
|
||||
product = ifcopenshell.api.run(
|
||||
"root.reassign_class",
|
||||
self.file,
|
||||
product=self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
|
||||
product=tool.Ifc.get_entity(obj),
|
||||
ifc_class=context.scene.BIMRootProperties.ifc_class,
|
||||
predefined_type=predefined_type,
|
||||
)
|
||||
obj.name = "{}/{}".format(product.is_a(), getattr(product, "Name", "None"))
|
||||
tool.Ifc.link(product, obj)
|
||||
reassigned_elements.add(product)
|
||||
obj.name = tool.Loader.get_name(product)
|
||||
obj.BIMObjectProperties.is_reassigning_class = False
|
||||
|
||||
dependent_elements = set()
|
||||
for reassigned_element in reassigned_elements:
|
||||
if reassigned_element.is_a("IfcTypeObject"):
|
||||
dependent_elements.update(ifcopenshell.util.element.get_types(product))
|
||||
else:
|
||||
element_type = ifcopenshell.util.element.get_type(product)
|
||||
if element_type:
|
||||
dependent_elements.add(element_type)
|
||||
dependent_elements.update(ifcopenshell.util.element.get_types(element_type))
|
||||
|
||||
for dependent_element in dependent_elements:
|
||||
obj = tool.Ifc.get_object(dependent_element)
|
||||
if obj:
|
||||
obj.name = tool.Loader.get_name(dependent_element)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
|
||||
@classmethod
|
||||
def get_name(cls, element):
|
||||
return "{}/{}".format(element.is_a(), element.Name)
|
||||
return "{}/{}".format(element.is_a(), getattr(element, "Name", "None"))
|
||||
|
||||
@classmethod
|
||||
def link_mesh(cls, shape, mesh):
|
||||
|
||||
@@ -39,6 +39,14 @@ class Usecase:
|
||||
This is especially useful when dealing with poorly classified data from
|
||||
proprietary software with limited IFC capabilities.
|
||||
|
||||
If you are reassigning a type, the occurrence classes are also
|
||||
reassigned to maintain validity.
|
||||
|
||||
Vice versa, if you are reassigning an occurrence, the type is also
|
||||
reassigned in IFC4 and up. In IFC2X3, this may not occur if the type
|
||||
cannot be unambiguously derived, so you are required to manually check
|
||||
this.
|
||||
|
||||
:param product: The IfcProduct that you want to change the class of.
|
||||
:type product: ifcopenshell.entity_instance.entity_instance
|
||||
:param ifc_class: The new IFC class you want to change it to.
|
||||
@@ -70,10 +78,27 @@ class Usecase:
|
||||
}
|
||||
|
||||
def execute(self):
|
||||
element = ifcopenshell.util.schema.reassign_class(
|
||||
self.file, self.settings["product"], self.settings["ifc_class"]
|
||||
)
|
||||
is_type = element.is_a("IfcTypeProduct")
|
||||
element = self.reassign_class(self.settings["product"], self.settings["ifc_class"])
|
||||
|
||||
if element.is_a("IfcTypeProduct"):
|
||||
for occurrence in ifcopenshell.util.element.get_types(element) or []:
|
||||
ifc_class = ifcopenshell.util.type.get_applicable_entities(self.settings["ifc_class"])[0]
|
||||
self.reassign_class(occurrence, ifc_class)
|
||||
else:
|
||||
element_type = ifcopenshell.util.element.get_type(element)
|
||||
if element_type:
|
||||
ifc_class = ifcopenshell.util.type.get_applicable_types(self.settings["ifc_class"])
|
||||
if ifc_class and len(ifc_class) == 1:
|
||||
element_type = self.reassign_class(element_type, ifc_class[0])
|
||||
ifc_class = element.is_a()
|
||||
for occurrence in ifcopenshell.util.element.get_types(element_type) or []:
|
||||
if occurrence == element:
|
||||
continue
|
||||
self.reassign_class(occurrence, ifc_class)
|
||||
return element
|
||||
|
||||
def reassign_class(self, element, ifc_class):
|
||||
element = ifcopenshell.util.schema.reassign_class(self.file, element, ifc_class)
|
||||
if self.settings["predefined_type"] and hasattr(element, "PredefinedType"):
|
||||
try:
|
||||
element.PredefinedType = self.settings["predefined_type"]
|
||||
@@ -81,20 +106,9 @@ class Usecase:
|
||||
# PredefinedType wasn't in the respective enum, assume it's actually USERDEFINED
|
||||
# and set .ElementType / .ObjectType to the provided predefined type
|
||||
element.PredefinedType = "USERDEFINED"
|
||||
if is_type:
|
||||
if element.is_a("IfcTypeProduct"):
|
||||
element.ElementType = self.settings["predefined_type"]
|
||||
else:
|
||||
element.ObjectType = self.settings["predefined_type"]
|
||||
|
||||
# reassign classes for occurences connected to the type
|
||||
if is_type:
|
||||
for occurrence in ifcopenshell.util.element.get_types(element) or []:
|
||||
ifc_class = ifcopenshell.util.type.get_applicable_entities(self.settings["ifc_class"])[0]
|
||||
ifcopenshell.api.run(
|
||||
"root.reassign_class",
|
||||
self.file,
|
||||
product=occurrence,
|
||||
ifc_class=ifc_class,
|
||||
predefined_type=self.settings["predefined_type"],
|
||||
)
|
||||
return element
|
||||
|
||||
Reference in New Issue
Block a user