mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Fix #2364. Bug where classifications couldn't be added in IFC2X3.
This commit is contained in:
@@ -39,6 +39,8 @@ class IfcStore:
|
||||
edited_objs = set()
|
||||
pset_template_path = ""
|
||||
pset_template_file = None
|
||||
classification_path = ""
|
||||
classification_file = None
|
||||
library_path = ""
|
||||
library_file = None
|
||||
element_listeners = set()
|
||||
|
||||
@@ -20,18 +20,19 @@ import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.LoadClassificationLibrary,
|
||||
operator.AddClassification,
|
||||
operator.RemoveClassification,
|
||||
operator.EnableEditingClassification,
|
||||
operator.DisableEditingClassification,
|
||||
operator.EditClassification,
|
||||
operator.RemoveClassificationReference,
|
||||
operator.EnableEditingClassificationReference,
|
||||
operator.DisableEditingClassificationReference,
|
||||
operator.EditClassificationReference,
|
||||
operator.AddClassificationReference,
|
||||
operator.ChangeClassificationLevel,
|
||||
operator.DisableEditingClassification,
|
||||
operator.DisableEditingClassificationReference,
|
||||
operator.DisableEditingClassificationReferences,
|
||||
operator.EditClassification,
|
||||
operator.EditClassificationReference,
|
||||
operator.EnableEditingClassification,
|
||||
operator.EnableEditingClassificationReference,
|
||||
operator.LoadClassificationLibrary,
|
||||
operator.RemoveClassification,
|
||||
operator.RemoveClassificationReference,
|
||||
prop.ClassificationReference,
|
||||
prop.BIMClassificationProperties,
|
||||
prop.BIMClassificationReferenceProperties,
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.classification
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
def refresh():
|
||||
ClassificationsData.is_loaded = False
|
||||
ClassificationReferencesData.is_loaded = False
|
||||
|
||||
|
||||
class ClassificationsData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data["has_classification_file"] = cls.has_classification_file()
|
||||
cls.data["classifications"] = cls.classifications()
|
||||
cls.data["available_classifications"] = cls.available_classifications()
|
||||
|
||||
@classmethod
|
||||
def has_classification_file(cls):
|
||||
return bool(IfcStore.classification_file)
|
||||
|
||||
@classmethod
|
||||
def classifications(cls):
|
||||
results = []
|
||||
for element in tool.Ifc.get().by_type("IfcClassification"):
|
||||
data = element.get_info()
|
||||
if IfcStore.classification_file.schema == "IFC2X3" and element.EditionDate:
|
||||
data["EditionDate"] = ifcopenshell.util.date.ifc2datetime(data["EditionDate"])
|
||||
results.append(data)
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def available_classifications(cls):
|
||||
if not IfcStore.classification_file:
|
||||
return []
|
||||
return [(str(e.id()), e.Name, "") for e in IfcStore.classification_file.by_type("IfcClassification")]
|
||||
|
||||
|
||||
class ClassificationReferencesData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data["references"] = cls.references()
|
||||
cls.data["is_available_classification_added"] = cls.is_available_classification_added()
|
||||
|
||||
@classmethod
|
||||
def references(cls):
|
||||
results = []
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
if element:
|
||||
for reference in ifcopenshell.util.classification.get_references(element):
|
||||
data = reference.get_info()
|
||||
del data["ReferencedSource"]
|
||||
results.append(data)
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def is_available_classification_added(cls):
|
||||
if not IfcStore.classification_file or not IfcStore.classification_file.by_type("IfcClassification"):
|
||||
return False
|
||||
props = bpy.context.scene.BIMClassificationProperties
|
||||
name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
||||
return name in [e.Name for e in tool.Ifc.get().by_type("IfcClassification")]
|
||||
@@ -1,5 +1,5 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020-2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -18,46 +18,40 @@
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.bim.helper
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.classification.data import Data
|
||||
from blenderbim.bim.module.classification.prop import getClassifications, getReferences
|
||||
|
||||
|
||||
class LoadClassificationLibrary(bpy.types.Operator):
|
||||
class LoadClassificationLibrary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.load_classification_library"
|
||||
bl_label = "Load Classification Library"
|
||||
filename_ext = ".ifc"
|
||||
filter_glob: bpy.props.StringProperty(default="*.ifc;*.ifczip;*.ifcxml", options={"HIDDEN"})
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
def execute(self, context):
|
||||
Data.load_library(self.filepath)
|
||||
getClassifications(self, context)
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def _execute(self, context):
|
||||
IfcStore.classification_file = ifcopenshell.open(self.filepath)
|
||||
|
||||
class AddClassification(bpy.types.Operator):
|
||||
|
||||
class AddClassification(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_classification"
|
||||
bl_label = "Add Classification"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMClassificationProperties
|
||||
ifcopenshell.api.run(
|
||||
"classification.add_classification",
|
||||
IfcStore.get_file(),
|
||||
**{"classification": Data.library_file.by_id(int(props.available_classifications))},
|
||||
tool.Ifc.get(),
|
||||
classification=IfcStore.classification_file.by_id(int(props.available_classifications)),
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EnableEditingClassification(bpy.types.Operator):
|
||||
@@ -67,19 +61,21 @@ class EnableEditingClassification(bpy.types.Operator):
|
||||
classification: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
def callback(name, prop, data):
|
||||
if name == "ReferenceTokens":
|
||||
new = bpy.context.scene.BIMGeoreferenceProperties.projected_crs.add()
|
||||
new.name = name
|
||||
new.data_type = "string"
|
||||
new.is_null = data[name] is None
|
||||
new.is_optional = True
|
||||
new.string_value = "" if new.is_null else json.dumps(data[name])
|
||||
return True
|
||||
|
||||
props = context.scene.BIMClassificationProperties
|
||||
props.classification_attributes.clear()
|
||||
classification_data = Data.classifications[self.classification]
|
||||
for attribute in IfcStore.get_schema().declaration_by_name("IfcClassification").all_attributes():
|
||||
new = props.classification_attributes.add()
|
||||
new.name = attribute.name()
|
||||
new.is_null = classification_data[attribute.name()] is None
|
||||
new.is_optional = attribute.optional()
|
||||
new.data_type = "string"
|
||||
if attribute.name() == "ReferenceTokens":
|
||||
new.string_value = "" if new.is_null else json.dumps(classification_data[attribute.name()])
|
||||
else:
|
||||
new.string_value = "" if new.is_null else classification_data[attribute.name()]
|
||||
blenderbim.bim.helper.import_attributes2(
|
||||
tool.Ifc.get().by_id(self.classification), props.classification_attributes, callback
|
||||
)
|
||||
props.active_classification_id = self.classification
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -94,34 +90,26 @@ class DisableEditingClassification(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveClassification(bpy.types.Operator):
|
||||
class RemoveClassification(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.remove_classification"
|
||||
bl_label = "Remove Classification"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
classification: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run(
|
||||
"classification.remove_classification",
|
||||
self.file,
|
||||
**{"classification": self.file.by_id(self.classification)},
|
||||
tool.Ifc.get(),
|
||||
classification=self.file.by_id(self.classification),
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EditClassification(bpy.types.Operator):
|
||||
class EditClassification(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_classification"
|
||||
bl_label = "Edit Classification"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMClassificationProperties
|
||||
attributes = {}
|
||||
@@ -138,9 +126,7 @@ class EditClassification(bpy.types.Operator):
|
||||
self.file,
|
||||
**{"classification": self.file.by_id(props.active_classification_id), "attributes": attributes},
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
bpy.ops.bim.disable_editing_classification()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EnableEditingClassificationReference(bpy.types.Operator):
|
||||
@@ -154,16 +140,7 @@ class EnableEditingClassificationReference(bpy.types.Operator):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
props = obj.BIMClassificationReferenceProperties
|
||||
props.reference_attributes.clear()
|
||||
reference_data = Data.references[self.reference]
|
||||
for attribute in IfcStore.get_schema().declaration_by_name("IfcClassificationReference").all_attributes():
|
||||
if attribute.name() == "ReferencedSource":
|
||||
continue
|
||||
new = props.reference_attributes.add()
|
||||
new.name = attribute.name()
|
||||
new.is_null = reference_data[attribute.name()] is None
|
||||
new.is_optional = attribute.optional()
|
||||
new.data_type = "string"
|
||||
new.string_value = "" if new.is_null else reference_data[attribute.name()]
|
||||
blenderbim.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.reference), props.reference_attributes)
|
||||
props.active_reference_id = self.reference
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -180,41 +157,30 @@ class DisableEditingClassificationReference(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveClassificationReference(bpy.types.Operator):
|
||||
class RemoveClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.remove_classification_reference"
|
||||
bl_label = "Remove Classification Reference"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
reference: bpy.props.IntProperty()
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run(
|
||||
"classification.remove_reference",
|
||||
self.file,
|
||||
**{
|
||||
"reference": self.file.by_id(self.reference),
|
||||
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
|
||||
},
|
||||
reference=self.file.by_id(self.reference),
|
||||
product=self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
|
||||
)
|
||||
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EditClassificationReference(bpy.types.Operator):
|
||||
class EditClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_classification_reference"
|
||||
bl_label = "Edit Classification Reference"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
props = obj.BIMClassificationReferenceProperties
|
||||
@@ -228,48 +194,37 @@ class EditClassificationReference(bpy.types.Operator):
|
||||
ifcopenshell.api.run(
|
||||
"classification.edit_reference",
|
||||
self.file,
|
||||
**{"reference": self.file.by_id(props.active_reference_id), "attributes": attributes},
|
||||
reference=self.file.by_id(props.active_reference_id), attributes=attributes,
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
bpy.ops.bim.disable_editing_classification_reference()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddClassificationReference(bpy.types.Operator):
|
||||
class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_classification_reference"
|
||||
bl_label = "Add Classification Reference"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
reference: bpy.props.IntProperty()
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
self.file = IfcStore.get_file()
|
||||
|
||||
classification = None
|
||||
|
||||
props = context.scene.BIMClassificationProperties
|
||||
classification_name = Data.library_classifications[int(props.available_classifications)]
|
||||
for classification_id, classification in Data.classifications.items():
|
||||
if classification["Name"] == classification_name:
|
||||
classification = self.file.by_id(classification_id)
|
||||
classification = None
|
||||
classification_name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
||||
for element in tool.Ifc.get().by_type("IfcClassification"):
|
||||
if element.Name == classification_name:
|
||||
classification = element
|
||||
break
|
||||
|
||||
ifcopenshell.api.run(
|
||||
"classification.add_reference",
|
||||
self.file,
|
||||
**{
|
||||
"reference": Data.library_file.by_id(self.reference),
|
||||
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
|
||||
"classification": classification,
|
||||
},
|
||||
reference=IfcStore.classification_file.by_id(self.reference),
|
||||
product=tool.Ifc.get_entity(obj),
|
||||
classification=classification,
|
||||
)
|
||||
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ChangeClassificationLevel(bpy.types.Operator):
|
||||
@@ -279,5 +234,27 @@ class ChangeClassificationLevel(bpy.types.Operator):
|
||||
parent_id: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
getReferences(self, context, parent_id=self.parent_id)
|
||||
props = context.scene.BIMClassificationProperties
|
||||
props.available_library_references.clear()
|
||||
for reference in IfcStore.classification_file.by_id(self.parent_id).HasReferences:
|
||||
new = props.available_library_references.add()
|
||||
new.identification = reference.Identification or ""
|
||||
new.name = reference.Name or ""
|
||||
new.ifc_definition_id = reference.id()
|
||||
new.has_references = bool(reference.HasReferences)
|
||||
new.referenced_source
|
||||
if reference.ReferencedSource.is_a("IfcClassificationReference"):
|
||||
props.active_library_referenced_source = reference.ReferencedSource.ReferencedSource.id()
|
||||
else:
|
||||
props.active_library_referenced_source = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DisableEditingClassificationReferences(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_classification_references"
|
||||
bl_label = "Disable Editing Classification References"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMClassificationProperties
|
||||
props.available_library_references.clear()
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from ifcopenshell.api.classification.data import Data
|
||||
from blenderbim.bim.module.classification.data import ClassificationsData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
@@ -31,42 +32,10 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
)
|
||||
|
||||
classification_enum = []
|
||||
|
||||
|
||||
def purge():
|
||||
global classification_enum
|
||||
classification_enum = []
|
||||
|
||||
|
||||
def getClassifications(self, context):
|
||||
global classification_enum
|
||||
if len(classification_enum) < 1:
|
||||
classification_enum.clear()
|
||||
classification_enum.extend([(str(i), n, "") for i, n in Data.library_classifications.items()])
|
||||
if classification_enum:
|
||||
getReferences(self, context, parent_id=int(classification_enum[0][0]))
|
||||
return classification_enum
|
||||
|
||||
|
||||
def updateClassification(self, context):
|
||||
getReferences(self, context, parent_id=int(self.available_classifications))
|
||||
|
||||
|
||||
def getReferences(self, context, parent_id=None):
|
||||
props = context.scene.BIMClassificationProperties
|
||||
props.available_library_references.clear()
|
||||
for reference in Data.library_file.by_id(parent_id).HasReferences:
|
||||
new = props.available_library_references.add()
|
||||
new.identification = reference.Identification or ""
|
||||
new.name = reference.Name or ""
|
||||
new.ifc_definition_id = reference.id()
|
||||
new.has_references = bool(reference.HasReferences)
|
||||
new.referenced_source
|
||||
if reference.ReferencedSource.is_a("IfcClassificationReference"):
|
||||
props.active_library_referenced_source = reference.ReferencedSource.ReferencedSource.id()
|
||||
else:
|
||||
props.active_library_referenced_source = 0
|
||||
def get_available_classifications(self, context):
|
||||
if not ClassificationsData.is_loaded:
|
||||
ClassificationsData.load()
|
||||
return ClassificationsData.data["available_classifications"]
|
||||
|
||||
|
||||
class ClassificationReference(PropertyGroup):
|
||||
@@ -78,9 +47,7 @@ class ClassificationReference(PropertyGroup):
|
||||
|
||||
|
||||
class BIMClassificationProperties(PropertyGroup):
|
||||
available_classifications: EnumProperty(
|
||||
items=getClassifications, name="Available Classifications", update=updateClassification
|
||||
)
|
||||
available_classifications: EnumProperty(items=get_available_classifications, name="Available Classifications")
|
||||
classification_attributes: CollectionProperty(name="Classification Attributes", type=Attribute)
|
||||
active_classification_id: IntProperty(name="Active Classification Id")
|
||||
available_library_references: CollectionProperty(name="Available Library References", type=ClassificationReference)
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import blenderbim.bim.helper
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.bim.module.classification.prop as classification_prop
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.classification.data import Data
|
||||
from blenderbim.bim.module.classification.data import ClassificationsData, ClassificationReferencesData
|
||||
|
||||
|
||||
class BIM_PT_classifications(Panel):
|
||||
@@ -33,15 +35,15 @@ class BIM_PT_classifications(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return IfcStore.get_file()
|
||||
return tool.Ifc.get()
|
||||
|
||||
def draw(self, context):
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
if not ClassificationsData.is_loaded:
|
||||
ClassificationsData.load()
|
||||
|
||||
self.props = context.scene.BIMClassificationProperties
|
||||
|
||||
if Data.library_file:
|
||||
if ClassificationsData.data["has_classification_file"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "available_classifications", text="")
|
||||
row.operator("bim.load_classification_library", text="", icon="IMPORT")
|
||||
@@ -51,33 +53,25 @@ class BIM_PT_classifications(Panel):
|
||||
row.label(text="No Active Classification Library")
|
||||
row.operator("bim.load_classification_library", text="", icon="IMPORT")
|
||||
|
||||
for classification_id, classification in Data.classifications.items():
|
||||
if self.props.active_classification_id == classification_id:
|
||||
self.draw_editable_ui(classification)
|
||||
for classification in ClassificationsData.data["classifications"]:
|
||||
if self.props.active_classification_id == classification["id"]:
|
||||
self.draw_editable_ui()
|
||||
else:
|
||||
self.draw_ui(classification_id, classification)
|
||||
self.draw_ui(classification)
|
||||
|
||||
def draw_editable_ui(self, classification):
|
||||
def draw_editable_ui(self):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props.classification_attributes.get("Name"), "string_value", text="", icon="ASSET_MANAGER")
|
||||
row.operator("bim.edit_classification", text="", icon="CHECKMARK")
|
||||
row.operator("bim.edit_classification", text="Save changes", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_classification", text="", icon="CANCEL")
|
||||
blenderbim.bim.helper.draw_attributes(self.props.classification_attributes, self.layout)
|
||||
|
||||
for attribute in self.props.classification_attributes:
|
||||
if attribute.name == "Name":
|
||||
continue
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(attribute, "string_value", text=attribute.name)
|
||||
if attribute.is_optional:
|
||||
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
|
||||
|
||||
def draw_ui(self, classification_id, classification):
|
||||
def draw_ui(self, classification):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=classification["Name"], icon="ASSET_MANAGER")
|
||||
if not self.props.active_classification_id:
|
||||
op = row.operator("bim.enable_editing_classification", text="", icon="GREASEPENCIL")
|
||||
op.classification = classification_id
|
||||
row.operator("bim.remove_classification", text="", icon="X").classification = classification_id
|
||||
op.classification = classification["id"]
|
||||
row.operator("bim.remove_classification", text="", icon="X").classification = classification["id"]
|
||||
|
||||
|
||||
class BIM_PT_classification_references(Panel):
|
||||
@@ -93,74 +87,63 @@ class BIM_PT_classification_references(Panel):
|
||||
def poll(cls, context):
|
||||
if not context.active_object:
|
||||
return False
|
||||
if not IfcStore.get_element(context.active_object.BIMObjectProperties.ifc_definition_id):
|
||||
return False
|
||||
return bool(context.active_object.BIMObjectProperties.ifc_definition_id)
|
||||
return bool(tool.Ifc.get_entity(context.active_object))
|
||||
|
||||
def draw(self, context):
|
||||
if not ClassificationReferencesData.is_loaded:
|
||||
ClassificationReferencesData.load()
|
||||
|
||||
obj = context.active_object
|
||||
self.oprops = obj.BIMObjectProperties
|
||||
self.sprops = context.scene.BIMClassificationProperties
|
||||
self.props = obj.BIMClassificationReferenceProperties
|
||||
self.file = IfcStore.get_file()
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
if self.oprops.ifc_definition_id not in Data.products:
|
||||
Data.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
|
||||
|
||||
self.draw_add_ui(context)
|
||||
|
||||
reference_ids = Data.products[self.oprops.ifc_definition_id]
|
||||
if not reference_ids:
|
||||
if not ClassificationReferencesData.data["references"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="No References")
|
||||
|
||||
for reference_id in reference_ids:
|
||||
reference = Data.references[reference_id]
|
||||
if self.props.active_reference_id == reference_id:
|
||||
self.draw_editable_ui(reference)
|
||||
for reference in ClassificationReferencesData.data["references"]:
|
||||
if self.props.active_reference_id == reference["id"]:
|
||||
self.draw_editable_ui()
|
||||
else:
|
||||
self.draw_ui(reference_id, reference)
|
||||
self.draw_ui(reference)
|
||||
|
||||
def draw_add_ui(self, context):
|
||||
if not classification_prop.getClassifications(self.sprops, context):
|
||||
if not ClassificationReferencesData.data["is_available_classification_added"]:
|
||||
return
|
||||
|
||||
name = Data.library_classifications[int(self.sprops.available_classifications)]
|
||||
if name in [c["Name"] for c in Data.classifications.values()]:
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.sprops, "available_classifications", text="")
|
||||
if self.sprops.active_library_referenced_source:
|
||||
op = row.operator("bim.change_classification_level", text="", icon="FRAME_PREV")
|
||||
op.parent_id = self.sprops.active_library_referenced_source
|
||||
op = row.operator("bim.add_classification_reference", text="", icon="ADD")
|
||||
op.reference = self.sprops.available_library_references[
|
||||
self.sprops.active_library_reference_index
|
||||
].ifc_definition_id
|
||||
self.layout.template_list(
|
||||
"BIM_UL_classifications",
|
||||
"",
|
||||
self.sprops,
|
||||
"available_library_references",
|
||||
self.sprops,
|
||||
"active_library_reference_index",
|
||||
)
|
||||
|
||||
def draw_editable_ui(self, reference):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props.reference_attributes.get("Name"), "string_value", text="", icon="ASSET_MANAGER")
|
||||
row.operator("bim.edit_classification_reference", text="", icon="CHECKMARK")
|
||||
row.prop(self.sprops, "available_classifications", text="")
|
||||
if not self.sprops.available_library_references:
|
||||
op = row.operator("bim.change_classification_level", text="", icon="IMPORT")
|
||||
op.parent_id = int(self.sprops.available_classifications)
|
||||
return
|
||||
if self.sprops.active_library_referenced_source:
|
||||
op = row.operator("bim.change_classification_level", text="", icon="FRAME_PREV")
|
||||
op.parent_id = self.sprops.active_library_referenced_source
|
||||
op = row.operator("bim.add_classification_reference", text="", icon="ADD")
|
||||
op.reference = self.sprops.available_library_references[
|
||||
self.sprops.active_library_reference_index
|
||||
].ifc_definition_id
|
||||
row.operator("bim.disable_editing_classification_references", text="", icon="CANCEL")
|
||||
self.layout.template_list(
|
||||
"BIM_UL_classifications",
|
||||
"",
|
||||
self.sprops,
|
||||
"available_library_references",
|
||||
self.sprops,
|
||||
"active_library_reference_index",
|
||||
)
|
||||
|
||||
def draw_editable_ui(self):
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_classification_reference", text="Save changes", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_classification_reference", text="", icon="CANCEL")
|
||||
blenderbim.bim.helper.draw_attributes(self.props.reference_attributes, self.layout)
|
||||
|
||||
for attribute in self.props.reference_attributes:
|
||||
if attribute.name == "Name":
|
||||
continue
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(attribute, "string_value", text=attribute.name)
|
||||
if attribute.is_optional:
|
||||
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
|
||||
|
||||
def draw_ui(self, reference_id, reference):
|
||||
def draw_ui(self, reference):
|
||||
row = self.layout.row(align=True)
|
||||
if self.file.schema == "IFC2X3":
|
||||
name = reference["ItemReference"] or "No Identification"
|
||||
@@ -170,8 +153,8 @@ class BIM_PT_classification_references(Panel):
|
||||
row.label(text=reference["Name"] or "")
|
||||
if not self.props.active_reference_id:
|
||||
op = row.operator("bim.enable_editing_classification_reference", text="", icon="GREASEPENCIL")
|
||||
op.reference = reference_id
|
||||
row.operator("bim.remove_classification_reference", text="", icon="X").reference = reference_id
|
||||
op.reference = reference["id"]
|
||||
row.operator("bim.remove_classification_reference", text="", icon="X").reference = reference["id"]
|
||||
|
||||
|
||||
class BIM_UL_classifications(UIList):
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.helper import prop_with_search
|
||||
from blenderbim.bim.module.pset_template.data import PsetTemplatesData
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class Data:
|
||||
for classification in cls._file.by_type("IfcClassification"):
|
||||
data = classification.get_info()
|
||||
if cls._file.schema == "IFC2X3" and data["EditionDate"]:
|
||||
data["EditionDate"] = ifcopenshell.util.date(data.EditionDate).isoformat()
|
||||
data["EditionDate"] = ifcopenshell.util.date.ifc2datetime(data["EditionDate"]).isoformat()
|
||||
cls.classifications[classification.id()] = data
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user