diff --git a/src/Mod/BIM/nativeifc/ifc_objects.py b/src/Mod/BIM/nativeifc/ifc_objects.py index 0dd3b90813..245d1e213f 100644 --- a/src/Mod/BIM/nativeifc/ifc_objects.py +++ b/src/Mod/BIM/nativeifc/ifc_objects.py @@ -65,7 +65,7 @@ class ifc_object: elif prop == "Schema": self.edit_schema(obj, obj.Schema) elif prop == "Type": - self.Classification(obj) + self.assign_classification(obj) elif prop == "Classification": self.edit_classification(obj) elif prop == "Group": @@ -116,6 +116,31 @@ class ifc_object: QtCore.QTimer.singleShot(100, obj.Document.recompute) QtCore.QTimer.singleShot(100, self.fit_all) + def assign_classification(self, obj): + """ + Assigns Classification to an IFC object in a case where + the object references a Type that has a Classification property, + so we move copy the Type's property to our actual object. + """ + + if not getattr(obj, "Type", None): + return + + type_obj = obj.Type + if getattr(type_obj, "Classification", None): + # Check if there is Classification already, since user can just change + # the IFC type, but there could be one previously assigned which had + # Classification + if getattr(obj, "Classification", None) is None: + obj.addProperty("App::PropertyString", "Classification", "IFC") + obj.Classification = type_obj.Classification + obj.recompute() + elif getattr(obj, "Classification", None): + # This means user has assigned type that has no classification, so clear + # the one that they have currently selected + obj.Classification = "" + obj.recompute() + def fit_all(self): """Fits the view""" diff --git a/src/Mod/BIM/nativeifc/ifc_tools.py b/src/Mod/BIM/nativeifc/ifc_tools.py index 5f92e3f9da..675c2a99a1 100644 --- a/src/Mod/BIM/nativeifc/ifc_tools.py +++ b/src/Mod/BIM/nativeifc/ifc_tools.py @@ -48,6 +48,7 @@ try: import ifcopenshell.util.placement import ifcopenshell.util.schema import ifcopenshell.util.unit + import ifcopenshell.entity_instance except ImportError as e: import FreeCAD FreeCAD.Console.PrintError( @@ -721,6 +722,37 @@ def add_properties( obj.addProperty("App::PropertyString", attr, "IFC", locked=True) if value is not None: setattr(obj, attr, str(value)) + + # We shortly go through the list of IFCRELASSOCIATESCLASSIFICATION members + # in the file to see if the newly added object should have a Classification added + # since we can run `add_properties`, when changing from IFC Object to IFC Type, or BIM Object (Standard Code) + # to BIM Type, and during the process of creation the only place where we save Classification is + # the file itself, so below code retrieves it and assigns it back to the newly created obj. + if not hasattr(obj, "Classification"): + assoc_classifications = ifcfile.by_type("IfcRelAssociatesClassification") + for assoc in assoc_classifications: + related_objects = assoc.RelatedObjects + if isinstance(related_objects, ifcopenshell.entity_instance): + related_objects = [related_objects] + if ifcentity in related_objects: + cref = assoc.RelatingClassification + if cref and cref.is_a("IfcClassificationReference"): + classification_name = "" + + # Try to get the source classification name + if hasattr(cref, "ReferencedSource") and cref.ReferencedSource: + if hasattr(cref.ReferencedSource, "Name") and cref.ReferencedSource.Name: + classification_name += cref.ReferencedSource.Name + " " + + # Add the Identification if present + if cref.Identification: + classification_name += cref.Identification + + classification_name = classification_name.strip() + if classification_name: + obj.addProperty("App::PropertyString", "Classification", "IFC", locked=True) + setattr(obj, "Classification", classification_name) + break # Found the relevant one, stop # annotation properties if ifcentity.is_a("IfcGridAxis"): axisdata = ifc_export.get_axis(ifcentity)