From 2c82bfa150c97dfd87e4b3073b03cfd55b80292f Mon Sep 17 00:00:00 2001 From: tetektoza Date: Mon, 7 Jul 2025 16:06:43 +0200 Subject: [PATCH] BIM: Add an option to preload IFC types during document opening (#21450) * BIM: Add an option to preload IFC types during document opening Currently, IFC types are only possible to be loaded if user double clicks an IFC object, and this has be done for optimization reasons. But user can also want to preload IFC types, so this patch adds an option to the dialog and Properties dialog to do just that. * BIM: Remove cyclic import --------- Co-authored-by: Yorik van Havre --- src/Mod/BIM/Resources/ui/dialogImport.ui | 10 ++++++ .../BIM/Resources/ui/preferencesNativeIFC.ui | 16 ++++++++++ src/Mod/BIM/nativeifc/ifc_import.py | 7 +++++ src/Mod/BIM/nativeifc/ifc_tools.py | 1 + src/Mod/BIM/nativeifc/ifc_types.py | 31 +++++++++++++++++-- 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/Mod/BIM/Resources/ui/dialogImport.ui b/src/Mod/BIM/Resources/ui/dialogImport.ui index d94cf3ac3f..e4609879d8 100644 --- a/src/Mod/BIM/Resources/ui/dialogImport.ui +++ b/src/Mod/BIM/Resources/ui/dialogImport.ui @@ -113,6 +113,16 @@ + + + + Preload IFC types that are connected to the objects. It is also possible to leave this setting disabled and double click later on the object to load the types + + + Preload types + + + diff --git a/src/Mod/BIM/Resources/ui/preferencesNativeIFC.ui b/src/Mod/BIM/Resources/ui/preferencesNativeIFC.ui index 136249f741..43e9771878 100644 --- a/src/Mod/BIM/Resources/ui/preferencesNativeIFC.ui +++ b/src/Mod/BIM/Resources/ui/preferencesNativeIFC.ui @@ -129,6 +129,22 @@ + + + + Load all types automatically when opening an IFC file + + + Preload types + + + LoadTypes + + + Mod/NativeIFC + + + diff --git a/src/Mod/BIM/nativeifc/ifc_import.py b/src/Mod/BIM/nativeifc/ifc_import.py index 5209401baa..5f539c1cf9 100644 --- a/src/Mod/BIM/nativeifc/ifc_import.py +++ b/src/Mod/BIM/nativeifc/ifc_import.py @@ -32,6 +32,7 @@ from . import ifc_psets from . import ifc_materials from . import ifc_layers from . import ifc_status +from . import ifc_types if FreeCAD.GuiUp: import FreeCADGui @@ -101,6 +102,8 @@ def insert( ifc_layers.load_layers(prj_obj) if PARAMS.GetBool("LoadPsets", False): ifc_psets.load_psets(prj_obj) + if PARAMS.GetBool("LoadTypes", False): + ifc_types.load_types(prj_obj) document.recompute() # print a reference to the IFC file on the console if FreeCAD.GuiUp and PARAMS.GetBool("IfcFileToConsole", False): @@ -133,6 +136,7 @@ def get_options(strategy=None, shapemode=None, switchwb=None, silent=False): """ psets = PARAMS.GetBool("LoadPsets", False) + types = PARAMS.GetBool("LoadTypes", False) materials = PARAMS.GetBool("LoadMaterials", False) layers = PARAMS.GetBool("LoadLayers", False) singledoc = PARAMS.GetBool("SingleDoc", False) @@ -155,6 +159,7 @@ def get_options(strategy=None, shapemode=None, switchwb=None, silent=False): dlg.checkSwitchWB.setChecked(switchwb) dlg.checkAskAgain.setChecked(ask) dlg.checkLoadPsets.setChecked(psets) + dlg.checkLoadTypes.setChecked(types) dlg.checkLoadMaterials.setChecked(materials) dlg.checkLoadLayers.setChecked(layers) dlg.comboSingleDoc.setCurrentIndex(1 - int(singledoc)) @@ -166,6 +171,7 @@ def get_options(strategy=None, shapemode=None, switchwb=None, silent=False): switchwb = dlg.checkSwitchWB.isChecked() ask = dlg.checkAskAgain.isChecked() psets = dlg.checkLoadPsets.isChecked() + types = dlg.checkLoadTypes.isChecked() materials = dlg.checkLoadMaterials.isChecked() layers = dlg.checkLoadLayers.isChecked() singledoc = dlg.comboSingleDoc.currentIndex() @@ -174,6 +180,7 @@ def get_options(strategy=None, shapemode=None, switchwb=None, silent=False): PARAMS.SetBool("SwitchWB", switchwb) PARAMS.SetBool("AskAgain", ask) PARAMS.SetBool("LoadPsets", psets) + PARAMS.SetBool("LoadTypes", types) PARAMS.SetBool("LoadMaterials", materials) PARAMS.SetBool("LoadLayers", layers) PARAMS.SetBool("SingleDoc", bool(1 - singledoc)) diff --git a/src/Mod/BIM/nativeifc/ifc_tools.py b/src/Mod/BIM/nativeifc/ifc_tools.py index 8bc16126b4..619c58419f 100644 --- a/src/Mod/BIM/nativeifc/ifc_tools.py +++ b/src/Mod/BIM/nativeifc/ifc_tools.py @@ -350,6 +350,7 @@ def create_children( ] for window in windows: subresult.extend(create_child(child, window)) + if recursive: subresult.extend( create_children( diff --git a/src/Mod/BIM/nativeifc/ifc_types.py b/src/Mod/BIM/nativeifc/ifc_types.py index 7967c471a9..ce95c8222d 100644 --- a/src/Mod/BIM/nativeifc/ifc_types.py +++ b/src/Mod/BIM/nativeifc/ifc_types.py @@ -51,6 +51,34 @@ def show_type(obj): obj.Type = typeobj +def load_types(prj_obj): + """ + Loads IFC types for all objects in the project, used during + import of IFC files. + prj_obj is the project object, either a document or a document object. + """ + + def process_object(obj): + """Recursively process an object and its children""" + # Check if this object has IFC data and can have types + if hasattr(obj, 'StepId') and obj.StepId: + show_type(obj) + + # Process children recursively + if hasattr(obj, 'Group'): + for child in obj.Group: + process_object(child) + + if isinstance(prj_obj, FreeCAD.DocumentObject): + # Handle document object case + process_object(prj_obj) + else: + # Handle document case - process all IFC objects in the document + for obj in prj_obj.Objects: + if hasattr(obj, 'StepId') and obj.StepId: + show_type(obj) + + def is_typable(obj): """Checks if an object can become a type""" @@ -87,10 +115,9 @@ def convert_to_type(obj, keep_object=False): original_text = dlg.label.text() dlg.label.setText(original_text.replace("%1", obj.Class+"Type")) - + # Set the initial state of the checkbox from the "always keep" preference dlg.checkKeepObject.setChecked(always_keep) - result = dlg.exec_() if not result: return