Add support for manual classifications and references

This commit is contained in:
Dion Moult
2023-12-15 23:07:03 +11:00
parent cfdc54064e
commit 40e494996d
5 changed files with 140 additions and 4 deletions
@@ -24,12 +24,18 @@ classes = (
operator.AddClassificationFromBSDD, operator.AddClassificationFromBSDD,
operator.AddClassificationReference, operator.AddClassificationReference,
operator.AddClassificationReferenceFromBSDD, operator.AddClassificationReferenceFromBSDD,
operator.AddManualClassification,
operator.AddManualClassificationReference,
operator.ChangeClassificationLevel, operator.ChangeClassificationLevel,
operator.DisableAddingManualClassification,
operator.DisableAddingManualClassificationReference,
operator.DisableEditingClassification, operator.DisableEditingClassification,
operator.DisableEditingClassificationReference, operator.DisableEditingClassificationReference,
operator.DisableEditingClassificationReferences, operator.DisableEditingClassificationReferences,
operator.EditClassification, operator.EditClassification,
operator.EditClassificationReference, operator.EditClassificationReference,
operator.EnableAddingManualClassification,
operator.EnableAddingManualClassificationReference,
operator.EnableEditingClassification, operator.EnableEditingClassification,
operator.EnableEditingClassificationReference, operator.EnableEditingClassificationReference,
operator.LoadClassificationLibrary, operator.LoadClassificationLibrary,
@@ -73,6 +73,10 @@ class ReferencesData:
if name in [e.Name for e in tool.Ifc.get().by_type("IfcClassification")]: if name in [e.Name for e in tool.Ifc.get().by_type("IfcClassification")]:
return name return name
@classmethod
def classifications(cls):
return [(str(e.id()), e.Name, "") for e in tool.Ifc.get().by_type("IfcClassification")]
class ClassificationReferencesData(ReferencesData): class ClassificationReferencesData(ReferencesData):
data = {} data = {}
@@ -83,6 +87,8 @@ class ClassificationReferencesData(ReferencesData):
cls.is_loaded = True cls.is_loaded = True
cls.data["references"] = cls.references() cls.data["references"] = cls.references()
cls.data["active_classification_library"] = cls.active_classification_library() cls.data["active_classification_library"] = cls.active_classification_library()
cls.data["classifications"] = cls.classifications()
cls.data["object_type"] = "OBJECT"
@classmethod @classmethod
def references(cls): def references(cls):
@@ -105,6 +111,8 @@ class MaterialClassificationsData(ReferencesData):
cls.is_loaded = True cls.is_loaded = True
cls.data["references"] = cls.references() cls.data["references"] = cls.references()
cls.data["active_classification_library"] = cls.active_classification_library() cls.data["active_classification_library"] = cls.active_classification_library()
cls.data["classifications"] = cls.classifications()
cls.data["object_type"] = "MATERIAL"
@classmethod @classmethod
def references(cls): def references(cls):
@@ -127,6 +135,8 @@ class CostClassificationsData(ReferencesData):
cls.is_loaded = True cls.is_loaded = True
cls.data["references"] = cls.references() cls.data["references"] = cls.references()
cls.data["active_classification_library"] = cls.active_classification_library() cls.data["active_classification_library"] = cls.active_classification_library()
cls.data["classifications"] = cls.classifications()
cls.data["object_type"] = "COST"
@classmethod @classmethod
def references(cls): def references(cls):
@@ -54,6 +54,50 @@ class AddClassification(bpy.types.Operator, tool.Ifc.Operator):
) )
class AddManualClassification(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_manual_classification"
bl_label = "Add Manual Classification"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.scene.BIMClassificationProperties
attributes = blenderbim.bim.helper.export_attributes(props.classification_attributes)
classification = ifcopenshell.api.run(
"classification.add_classification", tool.Ifc.get(), classification="Unnamed"
)
ifcopenshell.api.run(
"classification.edit_classification", tool.Ifc.get(), classification=classification, attributes=attributes
)
props.is_adding = False
class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_manual_classification_reference"
bl_label = "Add Manual Classification Reference"
bl_options = {"REGISTER", "UNDO"}
obj_type: bpy.props.StringProperty()
def _execute(self, context):
obj = context.active_object
props = obj.BIMClassificationReferenceProperties
attributes = blenderbim.bim.helper.export_attributes(props.reference_attributes)
product = tool.Ifc.get_entity(obj)
# TODO: refactor and support material and cost item classifications
classification = tool.Ifc.get().by_id(int(props.classifications))
reference = ifcopenshell.api.run(
"classification.add_reference",
tool.Ifc.get(),
product=product,
classification=classification,
identification="X",
name="Unnamed",
)
ifcopenshell.api.run(
"classification.edit_reference", tool.Ifc.get(), reference=reference, attributes=attributes
)
props.is_adding = False
class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator): class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_classification_from_bsdd" bl_idname = "bim.add_classification_from_bsdd"
bl_label = "Add Classification From bSDD" bl_label = "Add Classification From bSDD"
@@ -73,6 +117,57 @@ class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
classification.Edition = domain.version classification.Edition = domain.version
class EnableAddingManualClassification(bpy.types.Operator):
bl_idname = "bim.enable_adding_manual_classification"
bl_label = "Enable Adding Manual Classification"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
props = context.scene.BIMClassificationProperties
props.is_adding = True
props.active_classification_id = 0
props.classification_attributes.clear()
blenderbim.bim.helper.import_attributes2("IfcClassification", props.classification_attributes)
return {"FINISHED"}
class DisableAddingManualClassification(bpy.types.Operator):
bl_idname = "bim.disable_adding_manual_classification"
bl_label = "Disable Adding Manual Classification"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
props = context.scene.BIMClassificationProperties
props.is_adding = False
return {"FINISHED"}
class EnableAddingManualClassificationReference(bpy.types.Operator):
bl_idname = "bim.enable_adding_manual_classification_reference"
bl_label = "Enable Adding Manual Classification Reference"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
obj = context.active_object
props = obj.BIMClassificationReferenceProperties
props.is_adding = True
props.reference_attributes.clear()
blenderbim.bim.helper.import_attributes2("IfcClassificationReference", props.reference_attributes)
return {"FINISHED"}
class DisableAddingManualClassificationReference(bpy.types.Operator):
bl_idname = "bim.disable_adding_manual_classification_reference"
bl_label = "Disable Adding Manual Classification Reference"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
obj = context.active_object
props = obj.BIMClassificationReferenceProperties
props.is_adding = False
return {"FINISHED"}
class EnableEditingClassification(bpy.types.Operator): class EnableEditingClassification(bpy.types.Operator):
bl_idname = "bim.enable_editing_classification" bl_idname = "bim.enable_editing_classification"
bl_label = "Enable Editing Classification" bl_label = "Enable Editing Classification"
@@ -17,9 +17,10 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import blenderbim.bim.helper
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.prop import StrProperty, Attribute from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.module.classification.data import ClassificationsData from blenderbim.bim.module.classification.data import ClassificationsData, ClassificationReferencesData
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
from bpy.props import ( from bpy.props import (
PointerProperty, PointerProperty,
@@ -39,6 +40,12 @@ def get_available_classifications(self, context):
return ClassificationsData.data["available_classifications"] return ClassificationsData.data["available_classifications"]
def get_classifications(self, context):
if not ClassificationReferencesData.is_loaded:
ClassificationReferencesData.load()
return ClassificationReferencesData.data["classifications"]
class ClassificationReference(PropertyGroup): class ClassificationReference(PropertyGroup):
name: StringProperty(name="Name") name: StringProperty(name="Name")
identification: StringProperty(name="Identification") identification: StringProperty(name="Identification")
@@ -48,6 +55,7 @@ class ClassificationReference(PropertyGroup):
class BIMClassificationProperties(PropertyGroup): class BIMClassificationProperties(PropertyGroup):
is_adding: BoolProperty(name="Is Adding", default=False)
classification_source: EnumProperty( classification_source: EnumProperty(
items=[ items=[
("FILE", "IFC File", ""), ("FILE", "IFC File", ""),
@@ -66,5 +74,7 @@ class BIMClassificationProperties(PropertyGroup):
class BIMClassificationReferenceProperties(PropertyGroup): class BIMClassificationReferenceProperties(PropertyGroup):
is_adding: BoolProperty(name="Is Adding", default=False)
classifications: EnumProperty(items=get_classifications, name="Classifications")
reference_attributes: CollectionProperty(name="Reference Attributes", type=Attribute) reference_attributes: CollectionProperty(name="Reference Attributes", type=Attribute)
active_reference_id: IntProperty(name="Active Reference Id") active_reference_id: IntProperty(name="Active Reference Id")
@@ -66,8 +66,14 @@ class BIM_PT_classifications(Panel):
self.draw_ui(classification) self.draw_ui(classification)
def draw_add_manual_ui(self, context): def draw_add_manual_ui(self, context):
row = self.layout.row() if self.props.is_adding:
row.label(text="TODO", icon="ERROR") blenderbim.bim.helper.draw_attributes(self.props.classification_attributes, self.layout)
row = self.layout.row(align=True)
row.operator("bim.add_manual_classification", text="Save", icon="CHECKMARK")
row.operator("bim.disable_adding_manual_classification", text="", icon="CANCEL")
else:
row = self.layout.row()
row.operator("bim.enable_adding_manual_classification", text="Add Classification", icon="ADD")
def draw_add_bsdd_ui(self, context): def draw_add_bsdd_ui(self, context):
self.bprops = context.scene.BIMBSDDProperties self.bprops = context.scene.BIMBSDDProperties
@@ -144,7 +150,16 @@ class ReferenceUI:
def draw_add_manual_ui(self, context): def draw_add_manual_ui(self, context):
row = self.layout.row() row = self.layout.row()
row.label(text="TODO", icon="ERROR") row.prop(self.props, "classifications", text="")
if self.props.is_adding:
blenderbim.bim.helper.draw_attributes(self.props.reference_attributes, self.layout)
row = self.layout.row(align=True)
op = row.operator("bim.add_manual_classification_reference", text="Save", icon="CHECKMARK")
op.type = self.data.data["object_type"]
row.operator("bim.disable_adding_manual_classification_reference", text="", icon="CANCEL")
else:
row = self.layout.row()
row.operator("bim.enable_adding_manual_classification_reference", text="Add Reference", icon="ADD")
def draw_add_bsdd_ui(self, context): def draw_add_bsdd_ui(self, context):
if not self.bprops.active_domain: if not self.bprops.active_domain: