mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 14:31:39 +00:00
bim.validate_ifc_assets Bonsai operator #6243
There's now operator to check that all profiles, styles, materials in the current project have a unique name. Which is important since it's used when we append assets to ensure there are no duplicated assets. Operator location - https://i.imgur.com/bvXjZ8Y.png Example output: ``` IfcMaterial name 'KnownUnknown' is used by multiple assets: - # 260=IfcMaterial('KnownUnknown',$,$) - # 1220=IfcMaterial('KnownUnknown',$,$) Found issues validating IfcProfileDef assets. IfcProfileDef name 'DEMO-C' is used by multiple assets: - # 266=IfcCShapeProfileDef(.AREA.,'DEMO-C',$,0.2,0.1,0.0015,0.03,0.005) - # 261=IfcIShapeProfileDef(.AREA.,'DEMO-C',$,0.1,0.2,0.005,0.01,0.005,$,$) Found issues validating IfcPresentationStyle assets. IfcPresentationStyle name 'Frame' is used by multiple assets: - # 363=IfcSurfaceStyle('Frame',.BOTH.,(# 362)) - # 1221=IfcSurfaceStyle('Frame',.BOTH.,(# 1222)) ```
This commit is contained in:
@@ -44,6 +44,7 @@ classes = (
|
|||||||
operator.SelectHighPolygonMeshes,
|
operator.SelectHighPolygonMeshes,
|
||||||
operator.SelectHighestPolygonMeshes,
|
operator.SelectHighestPolygonMeshes,
|
||||||
operator.ToggleDetailedIOSLogs,
|
operator.ToggleDetailedIOSLogs,
|
||||||
|
operator.ValidateIfcAssets,
|
||||||
operator.ValidateIfcFile,
|
operator.ValidateIfcFile,
|
||||||
prop.BIMDebugProperties,
|
prop.BIMDebugProperties,
|
||||||
ui.BIM_PT_debug,
|
ui.BIM_PT_debug,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import bonsai.core.profile
|
|||||||
import bonsai.core.type
|
import bonsai.core.type
|
||||||
import bonsai.bim.handler
|
import bonsai.bim.handler
|
||||||
import bonsai.bim.import_ifc as import_ifc
|
import bonsai.bim.import_ifc as import_ifc
|
||||||
|
from collections import defaultdict
|
||||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from bonsai import get_debug_info, format_debug_info
|
from bonsai import get_debug_info, format_debug_info
|
||||||
@@ -152,6 +153,67 @@ class ValidateIfcFile(bpy.types.Operator):
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class ValidateIfcAssets(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.validate_ifc_assets"
|
||||||
|
bl_label = "Validate IFC Assets"
|
||||||
|
bl_description = (
|
||||||
|
"Run Bonsai validation for IFC assets.\n\n"
|
||||||
|
"There's an internal Bonsai convention to treat some IFC assets "
|
||||||
|
"as unique based on their name (e.g. profiles, materials, styles).\n"
|
||||||
|
"Though it's not required by IFC, it is a generally good practice "
|
||||||
|
"to keep asset names unique and it also helps with various issues.\n"
|
||||||
|
"If it's not conformed, it could lead to duplicated assets or "
|
||||||
|
"the opposite - different assets of the same name treated as one."
|
||||||
|
)
|
||||||
|
bl_options = set()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
if not tool.Ifc.get():
|
||||||
|
cls.poll_message_set("IFC file is not loaded.")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
ifc_file = tool.Ifc.get()
|
||||||
|
|
||||||
|
ifc_classes = {
|
||||||
|
"IfcMaterial": "Name",
|
||||||
|
"IfcProfileDef": "ProfileName",
|
||||||
|
"IfcPresentationStyle": "Name",
|
||||||
|
}
|
||||||
|
|
||||||
|
issues_found = False
|
||||||
|
unique_assets: defaultdict[str, list[ifcopenshell.entity_instance]]
|
||||||
|
for ifc_class, name_attr in ifc_classes.items():
|
||||||
|
unique_assets = defaultdict(list)
|
||||||
|
for asset in ifc_file.by_type(ifc_class):
|
||||||
|
asset_name: Union[str, None] = getattr(asset, name_attr)
|
||||||
|
if asset_name is None:
|
||||||
|
continue
|
||||||
|
unique_assets[asset_name].append(asset)
|
||||||
|
|
||||||
|
msg = ""
|
||||||
|
for asset_name, assets in unique_assets.items():
|
||||||
|
if len(assets) == 1:
|
||||||
|
continue
|
||||||
|
msg += f"{ifc_class} name '{asset_name}' is used by multiple assets:\n"
|
||||||
|
for asset in assets:
|
||||||
|
msg += f"- {asset}\n"
|
||||||
|
|
||||||
|
if msg:
|
||||||
|
issues_found = True
|
||||||
|
msg = f"Found issues validating {ifc_class} assets.\n" + msg
|
||||||
|
print(msg)
|
||||||
|
|
||||||
|
if issues_found:
|
||||||
|
self.report({"INFO"}, "Check asset validation results in the system console.")
|
||||||
|
else:
|
||||||
|
self.report({"INFO"}, "No asset validation issues found.")
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class ProfileImportIFC(bpy.types.Operator):
|
class ProfileImportIFC(bpy.types.Operator):
|
||||||
profile_filename = "blender.prof"
|
profile_filename = "blender.prof"
|
||||||
bl_idname = "bim.profile_import_ifc"
|
bl_idname = "bim.profile_import_ifc"
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ class BIM_PT_debug(Panel):
|
|||||||
row.prop(props, "package_name", text="")
|
row.prop(props, "package_name", text="")
|
||||||
row.operator("bim.pip_install", icon="EVENT_PAGEDOWN").name = props.package_name
|
row.operator("bim.pip_install", icon="EVENT_PAGEDOWN").name = props.package_name
|
||||||
|
|
||||||
|
layout.operator("bim.validate_ifc_assets", icon="CHECKMARK")
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.operator("bim.reload_ifc_file", text="Incrementally Reload Changes")
|
row.operator("bim.reload_ifc_file", text="Incrementally Reload Changes")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user