From 455fe740c7838f355b0897534bdbf718ea91a72f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 25 Jul 2024 16:52:55 +0500 Subject: [PATCH] support assigning bsdd classifications in ifc4x3 too --- .../bim/module/classification/operator.py | 17 ++----- src/blenderbim/blenderbim/core/tool.py | 6 +++ src/blenderbim/blenderbim/tool/__init__.py | 1 + .../blenderbim/tool/classification.py | 48 +++++++++++++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 src/blenderbim/blenderbim/tool/classification.py diff --git a/src/blenderbim/blenderbim/bim/module/classification/operator.py b/src/blenderbim/blenderbim/bim/module/classification/operator.py index d7db0a68cb..99561ec40e 100644 --- a/src/blenderbim/blenderbim/bim/module/classification/operator.py +++ b/src/blenderbim/blenderbim/bim/module/classification/operator.py @@ -117,20 +117,17 @@ class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator): bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - is_ifc2x3 = tool.Ifc.get_schema() == "IFC2X3" - props = context.scene.BIMBSDDProperties domain = [d for d in props.domains if d.name == props.active_domain][0] for element in tool.Ifc.get().by_type("IfcClassification"): - if element.Name == props.active_domain or (not is_ifc2x3 and element.Location == domain.uri): + if element.Name == props.active_domain or (tool.Classification.get_location(element) == domain.uri): return classification = ifcopenshell.api.run( "classification.add_classification", tool.Ifc.get(), classification=props.active_domain ) classification.Source = domain.organization_name_owner classification.Edition = domain.version - if not is_ifc2x3: - classification.Location = domain.uri + tool.Classification.set_location(classification, domain.uri) class EnableAddingManualClassification(bpy.types.Operator): @@ -400,8 +397,6 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): obj_type: bpy.props.StringProperty() def _execute(self, context): - is_ifc2x3 = tool.Ifc.get_schema() == "IFC2X3" - if self.obj_type == "Object": if context.selected_objects: objects = [o.name for o in context.selected_objects] @@ -416,9 +411,8 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): classification = None for element in tool.Ifc.get().by_type("IfcClassification"): - if ( - element.Name == bsdd_classification.domain_name - or (not is_ifc2x3 and element.Location == bsdd_classification.domain_namespace_uri) + if element.Name == bsdd_classification.domain_name or ( + tool.Classification.get_location(element) == bsdd_classification.domain_namespace_uri ): classification = element break @@ -427,8 +421,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): classification = ifcopenshell.api.run( "classification.add_classification", tool.Ifc.get(), classification=bsdd_classification.domain_name ) - if not is_ifc2x3: - classification.Location = bsdd_classification.domain_namespace_uri + tool.Classification.set_location(classification, bsdd_classification.domain_namespace_uri) for obj in objects: ifc_definition_id = tool.Blender.get_obj_ifc_definition_id(obj, self.obj_type, context) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index cf835226ce..e80ec31f0d 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -168,6 +168,12 @@ class Clash: def look_at(cls, target, location): pass +@interface +class Classification: + def get_location(cls, classification): pass + def set_location(cls, classification): pass + + @interface class Collector: def assign(cls, obj): pass diff --git a/src/blenderbim/blenderbim/tool/__init__.py b/src/blenderbim/blenderbim/tool/__init__.py index 716915f4f5..3f80a685bc 100644 --- a/src/blenderbim/blenderbim/tool/__init__.py +++ b/src/blenderbim/blenderbim/tool/__init__.py @@ -23,6 +23,7 @@ from blenderbim.tool.brick import Brick from blenderbim.tool.bsdd import Bsdd from blenderbim.tool.cad import Cad from blenderbim.tool.clash import Clash +from blenderbim.tool.classification import Classification from blenderbim.tool.collector import Collector from blenderbim.tool.context import Context from blenderbim.tool.debug import Debug diff --git a/src/blenderbim/blenderbim/tool/classification.py b/src/blenderbim/blenderbim/tool/classification.py new file mode 100644 index 0000000000..0d07c91c7f --- /dev/null +++ b/src/blenderbim/blenderbim/tool/classification.py @@ -0,0 +1,48 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +from __future__ import annotations +import bpy +import ifcopenshell.api +import ifcopenshell.util.classification +import blenderbim.core.tool +import blenderbim.tool as tool +import blenderbim.bim +from typing import Any, Optional, Union, Literal, Iterable, Callable +from typing_extensions import assert_never + + +class Classification(blenderbim.core.tool.Classification): + @classmethod + def get_location(cls, classification: ifcopenshell.entity_instance) -> Union[str, None]: + schema = classification.file.schema + if schema in ("IFC4", "IFC4X3"): + return classification[5] + elif schema == "IFC2X3": + return None + assert_never(schema) + + @classmethod + def set_location(cls, classification: ifcopenshell.entity_instance, location: Union[str, None]) -> None: + schema = classification.file.schema + if schema in ("IFC4", "IFC4X3"): + classification[5] = location + return + elif schema == "IFC2X3": + return + assert_never(schema)