Save the current blend file as a metadata-only file (no geometry), preserving settings, window arrangement, geometry nodes, etc.
(self, context)
| 245 | bl_options = {"REGISTER", "UNDO"} |
| 246 | |
| 247 | def execute(self, context): |
| 248 | """ |
| 249 | Save the current blend file as a metadata-only file (no geometry), preserving settings, window arrangement, geometry nodes, etc. |
| 250 | """ |
| 251 | props = tool.Blender.get_bim_props() |
| 252 | ifc_file = getattr(props, "ifc_file", None) |
| 253 | if not ifc_file: |
| 254 | self.report({"WARNING"}, "No IFC file path set.") |
| 255 | return {"CANCELLED"} |
| 256 | |
| 257 | suffix = tool.Blender.get_addon_preferences().metadata_blend_file_suffix |
| 258 | if ifc_file.lower().endswith(".ifc"): |
| 259 | blendmetadata_path = ifc_file[:-4] + suffix |
| 260 | else: |
| 261 | blendmetadata_path = ifc_file + suffix |
| 262 | |
| 263 | ifc_dir = os.path.dirname(ifc_file) |
| 264 | temp_path = os.path.join(ifc_dir, "__temp_blendmetadata.blend") |
| 265 | bpy.ops.wm.save_as_mainfile(filepath=temp_path, copy=True) |
| 266 | |
| 267 | cleanup_script = f""" |
| 268 | import bpy |
| 269 | |
| 270 | # Ensure all styles are loaded before attempting to remove them |
| 271 | bpy.ops.bim.load_styles() |
| 272 | |
| 273 | # 1. Collect all IfcStyle material names |
| 274 | ifcstyle_material_names = [] |
| 275 | styles_props = getattr(bpy.context.scene, "BIMStylesProperties", None) |
| 276 | if styles_props is None and bpy.data.scenes: |
| 277 | styles_props = getattr(bpy.data.scenes[0], "BIMStylesProperties", None) |
| 278 | if styles_props: |
| 279 | for style in list(styles_props.styles): |
| 280 | material = getattr(style, "blender_material", None) |
| 281 | if material and material.name: |
| 282 | ifcstyle_material_names.append(material.name) |
| 283 | |
| 284 | # 2. Purge IfcStore |
| 285 | from bonsai.bim.ifc import IfcStore |
| 286 | IfcStore.purge() |
| 287 | |
| 288 | # 3. Remove all collections named IfcProject* |
| 289 | for collection in list(bpy.data.collections): |
| 290 | if collection.name.startswith('IfcProject'): |
| 291 | bpy.data.collections.remove(collection, do_unlink=True) |
| 292 | |
| 293 | # 4.1 Remove all collections from linked libraries (they will be recreated by bonsai) |
| 294 | for collection in list(bpy.data.collections): |
| 295 | if collection.library: |
| 296 | bpy.data.collections.remove(collection, do_unlink=True) |
| 297 | |
| 298 | # 4.2. Remove all empty objects that are collection instances for linked models |
| 299 | for obj in list(bpy.data.objects): |
| 300 | if obj.type == 'EMPTY' and obj.instance_type == 'COLLECTION' and obj.name.startswith('IfcProject/'): |
| 301 | bpy.data.objects.remove(obj, do_unlink=True) |
| 302 | |
| 303 | # 5. Purge orphaned data blocks after removing IfcProject collections |
| 304 | bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True) |
nothing calls this directly
no test coverage detected