mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +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
|
predefined_type = context.scene.BIMRootProperties.ifc_predefined_type
|
||||||
if predefined_type == "USERDEFINED":
|
if predefined_type == "USERDEFINED":
|
||||||
predefined_type = context.scene.BIMRootProperties.ifc_userdefined_type
|
predefined_type = context.scene.BIMRootProperties.ifc_userdefined_type
|
||||||
|
reassigned_elements = set()
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
product = ifcopenshell.api.run(
|
product = ifcopenshell.api.run(
|
||||||
"root.reassign_class",
|
"root.reassign_class",
|
||||||
self.file,
|
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,
|
ifc_class=context.scene.BIMRootProperties.ifc_class,
|
||||||
predefined_type=predefined_type,
|
predefined_type=predefined_type,
|
||||||
)
|
)
|
||||||
obj.name = "{}/{}".format(product.is_a(), getattr(product, "Name", "None"))
|
reassigned_elements.add(product)
|
||||||
tool.Ifc.link(product, obj)
|
obj.name = tool.Loader.get_name(product)
|
||||||
obj.BIMObjectProperties.is_reassigning_class = False
|
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"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Loader(blenderbim.core.tool.Loader):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_name(cls, element):
|
def get_name(cls, element):
|
||||||
return "{}/{}".format(element.is_a(), element.Name)
|
return "{}/{}".format(element.is_a(), getattr(element, "Name", "None"))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def link_mesh(cls, shape, mesh):
|
def link_mesh(cls, shape, mesh):
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ class Usecase:
|
|||||||
This is especially useful when dealing with poorly classified data from
|
This is especially useful when dealing with poorly classified data from
|
||||||
proprietary software with limited IFC capabilities.
|
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.
|
:param product: The IfcProduct that you want to change the class of.
|
||||||
:type product: ifcopenshell.entity_instance.entity_instance
|
:type product: ifcopenshell.entity_instance.entity_instance
|
||||||
:param ifc_class: The new IFC class you want to change it to.
|
:param ifc_class: The new IFC class you want to change it to.
|
||||||
@@ -70,10 +78,27 @@ class Usecase:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
element = ifcopenshell.util.schema.reassign_class(
|
element = self.reassign_class(self.settings["product"], self.settings["ifc_class"])
|
||||||
self.file, self.settings["product"], self.settings["ifc_class"]
|
|
||||||
)
|
if element.is_a("IfcTypeProduct"):
|
||||||
is_type = 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"):
|
if self.settings["predefined_type"] and hasattr(element, "PredefinedType"):
|
||||||
try:
|
try:
|
||||||
element.PredefinedType = self.settings["predefined_type"]
|
element.PredefinedType = self.settings["predefined_type"]
|
||||||
@@ -81,20 +106,9 @@ class Usecase:
|
|||||||
# PredefinedType wasn't in the respective enum, assume it's actually USERDEFINED
|
# PredefinedType wasn't in the respective enum, assume it's actually USERDEFINED
|
||||||
# and set .ElementType / .ObjectType to the provided predefined type
|
# and set .ElementType / .ObjectType to the provided predefined type
|
||||||
element.PredefinedType = "USERDEFINED"
|
element.PredefinedType = "USERDEFINED"
|
||||||
if is_type:
|
if element.is_a("IfcTypeProduct"):
|
||||||
element.ElementType = self.settings["predefined_type"]
|
element.ElementType = self.settings["predefined_type"]
|
||||||
else:
|
else:
|
||||||
element.ObjectType = self.settings["predefined_type"]
|
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
|
return element
|
||||||
|
|||||||
Reference in New Issue
Block a user