mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 02:31:09 +00:00
typing
This commit is contained in:
@@ -29,6 +29,7 @@ import numpy.typing as npt
|
|||||||
import multiprocessing
|
import multiprocessing
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.geom
|
import ifcopenshell.geom
|
||||||
|
import ifcopenshell.ifcopenshell_wrapper as W
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.geolocation
|
import ifcopenshell.util.geolocation
|
||||||
@@ -1032,9 +1033,9 @@ class IfcImporter:
|
|||||||
def create_curve(
|
def create_curve(
|
||||||
self,
|
self,
|
||||||
element: ifcopenshell.entity_instance,
|
element: ifcopenshell.entity_instance,
|
||||||
shape: Union[ifcopenshell.geom.ShapeElementType, ifcopenshell.geom.ShapeType],
|
shape: Union[W.Triangulation, W.TriangulationElement],
|
||||||
) -> bpy.types.Curve:
|
) -> bpy.types.Curve:
|
||||||
if isinstance(shape, ifcopenshell.geom.ShapeElementType):
|
if isinstance(shape, W.TriangulationElement):
|
||||||
geometry = shape.geometry
|
geometry = shape.geometry
|
||||||
else:
|
else:
|
||||||
geometry = shape
|
geometry = shape
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class SearchBSDDClassifications(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
total = core.search_bsdd_class(tool.Bsdd, context.scene.BIMBSDDProperties.keyword)
|
total = core.search_bsdd_class(tool.Bsdd, tool.Bsdd.get_bsdd_props().keyword)
|
||||||
self.report({"INFO"}, f"{total} bSDD classes found.")
|
self.report({"INFO"}, f"{total} bSDD classes found.")
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ class SearchBSDDProperties(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = tool.Bsdd.get_bsdd_props()
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
core.search_bsdd_properties(tool.Bsdd, context.scene.BIMBSDDProperties.keyword, self.obj, self.obj_type)
|
core.search_bsdd_properties(tool.Bsdd, tool.Bsdd.get_bsdd_props().keyword, self.obj, self.obj_type)
|
||||||
self.report({"INFO"}, f"{len(props.properties)} bSDD properties found.")
|
self.report({"INFO"}, f"{len(props.properties)} bSDD properties found.")
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from bpy.props import (
|
|||||||
FloatVectorProperty,
|
FloatVectorProperty,
|
||||||
CollectionProperty,
|
CollectionProperty,
|
||||||
)
|
)
|
||||||
from typing import Union
|
from typing import Union, TYPE_CHECKING, Literal
|
||||||
|
|
||||||
|
|
||||||
def get_active_dictionary(self, context):
|
def get_active_dictionary(self, context):
|
||||||
@@ -54,27 +54,41 @@ def update_active_class_index(self: "BIMBSDDProperties", context: bpy.types.Cont
|
|||||||
|
|
||||||
|
|
||||||
class BSDDDictionary(PropertyGroup):
|
class BSDDDictionary(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
|
||||||
uri: StringProperty(name="URI")
|
uri: StringProperty(name="URI")
|
||||||
default_language_code: StringProperty(name="Language")
|
default_language_code: StringProperty(name="Language")
|
||||||
organization_name_owner: StringProperty(name="Organization")
|
organization_name_owner: StringProperty(name="Organization")
|
||||||
status: StringProperty(name="Status")
|
status: StringProperty(name="Status")
|
||||||
version: StringProperty(name="Version")
|
version: StringProperty(name="Version")
|
||||||
is_active: BoolProperty(
|
is_active: BoolProperty(
|
||||||
name="Is Active", description="Enable to search with this dictionary", default=False, update=update_is_active
|
name="Is Active",
|
||||||
|
description="Enable to search with this dictionary",
|
||||||
|
default=False,
|
||||||
|
update=update_is_active,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
uri: str
|
||||||
|
default_language_code: str
|
||||||
|
organization_name_owner: str
|
||||||
|
status: str
|
||||||
|
version: str
|
||||||
|
is_active: bool
|
||||||
|
|
||||||
|
|
||||||
class BSDDClassification(PropertyGroup):
|
class BSDDClassification(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
|
||||||
reference_code: StringProperty(name="Reference Code")
|
reference_code: StringProperty(name="Reference Code")
|
||||||
uri: StringProperty(name="URI")
|
uri: StringProperty(name="URI")
|
||||||
dictionary_name: StringProperty(name="Dictionary Name")
|
dictionary_name: StringProperty(name="Dictionary Name")
|
||||||
dictionary_namespace_uri: StringProperty(name="Dictionary Namespace URI")
|
dictionary_namespace_uri: StringProperty(name="Dictionary Namespace URI")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
reference_code: str
|
||||||
|
uri: str
|
||||||
|
dictionary_name: str
|
||||||
|
dictionary_namespace_uri: str
|
||||||
|
|
||||||
|
|
||||||
class BSDDProperty(PropertyGroup):
|
class BSDDProperty(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
|
||||||
code: StringProperty(name="Code")
|
code: StringProperty(name="Code")
|
||||||
uri: StringProperty(name="URI")
|
uri: StringProperty(name="URI")
|
||||||
pset: StringProperty(name="Pset")
|
pset: StringProperty(name="Pset")
|
||||||
@@ -82,11 +96,19 @@ class BSDDProperty(PropertyGroup):
|
|||||||
name="Is Selected", description="Select to add or edit this property", default=False, update=update_is_selected
|
name="Is Selected", description="Select to add or edit this property", default=False, update=update_is_selected
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
code: str
|
||||||
|
uri: str
|
||||||
|
pset: str
|
||||||
|
is_selected: bool
|
||||||
|
|
||||||
|
|
||||||
class BSDDPset(PropertyGroup):
|
class BSDDPset(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
|
||||||
properties: CollectionProperty(name="Properties", type=Attribute)
|
properties: CollectionProperty(name="Properties", type=Attribute)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
properties: bpy.types.bpy_prop_collection_idprop[Attribute]
|
||||||
|
|
||||||
|
|
||||||
class BIMBSDDProperties(PropertyGroup):
|
class BIMBSDDProperties(PropertyGroup):
|
||||||
active_dictionary: StringProperty(name="Active Dictionary")
|
active_dictionary: StringProperty(name="Active Dictionary")
|
||||||
@@ -131,6 +153,28 @@ class BIMBSDDProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
classification_psets: CollectionProperty(name="Classification Psets", type=BSDDPset)
|
classification_psets: CollectionProperty(name="Classification Psets", type=BSDDPset)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
active_dictionary: str
|
||||||
|
active_dictionary: str
|
||||||
|
active_uri: str
|
||||||
|
dictionaries: bpy.types.bpy_prop_collection_idprop[BSDDDictionary]
|
||||||
|
active_dictionary_index: int
|
||||||
|
classifications: bpy.types.bpy_prop_collection_idprop[BSDDClassification]
|
||||||
|
active_classification_index: int
|
||||||
|
property_filter_mode: Literal["CLASS", "KEYWORD"]
|
||||||
|
classes: bpy.types.bpy_prop_collection_idprop[BSDDClassification]
|
||||||
|
active_class_index: int
|
||||||
|
properties: bpy.types.bpy_prop_collection_idprop[BSDDProperty]
|
||||||
|
active_property_index: int
|
||||||
|
selected_properties: bpy.types.bpy_prop_collection_idprop[Attribute]
|
||||||
|
keyword: str
|
||||||
|
should_filter_ifc_class: bool
|
||||||
|
use_only_ifc_properties: bool
|
||||||
|
load_preview_dictionaries: bool
|
||||||
|
load_inactive_dictionaries: bool
|
||||||
|
load_test_dictionaries: bool
|
||||||
|
classification_psets: bpy.types.bpy_prop_collection_idprop[BSDDPset]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active_class(self) -> Union[BSDDClassification, None]:
|
def active_class(self) -> Union[BSDDClassification, None]:
|
||||||
return tool.Blender.get_active_uilist_element(self.classes, self.active_class_index)
|
return tool.Blender.get_active_uilist_element(self.classes, self.active_class_index)
|
||||||
|
|||||||
@@ -16,9 +16,15 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import bpy
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from bonsai.bim.module.bsdd.data import BSDDData
|
from bonsai.bim.module.bsdd.data import BSDDData
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDDictionary, BSDDClassification, BSDDProperty
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_bsdd(Panel):
|
class BIM_PT_bsdd(Panel):
|
||||||
@@ -33,7 +39,8 @@ class BIM_PT_bsdd(Panel):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
if not BSDDData.is_loaded:
|
if not BSDDData.is_loaded:
|
||||||
BSDDData.load()
|
BSDDData.load()
|
||||||
props = context.scene.BIMBSDDProperties
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
|
assert self.layout
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
if len(props.dictionaries):
|
if len(props.dictionaries):
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
@@ -70,9 +77,17 @@ class BIM_PT_bsdd(Panel):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_UL_bsdd_dictionaries(UIList):
|
class BIM_UL_bsdd_dictionaries(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
layout: bpy.types.UILayout,
|
||||||
|
data: BIMBSDDProperties,
|
||||||
|
item: BSDDDictionary,
|
||||||
|
icon,
|
||||||
|
active_data,
|
||||||
|
active_propname,
|
||||||
|
) -> None:
|
||||||
if item:
|
if item:
|
||||||
props = context.scene.BIMBSDDProperties
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
if item.status != "Active":
|
if item.status != "Active":
|
||||||
row.label(
|
row.label(
|
||||||
@@ -86,7 +101,16 @@ class BIM_UL_bsdd_dictionaries(UIList):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_UL_bsdd_classifications(UIList):
|
class BIM_UL_bsdd_classifications(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
layout: bpy.types.UILayout,
|
||||||
|
data: BIMBSDDProperties,
|
||||||
|
item: BSDDClassification,
|
||||||
|
icon,
|
||||||
|
active_data,
|
||||||
|
active_propname,
|
||||||
|
) -> None:
|
||||||
if item:
|
if item:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=item.reference_code)
|
row.label(text=item.reference_code)
|
||||||
@@ -95,7 +119,16 @@ class BIM_UL_bsdd_classifications(UIList):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_UL_bsdd_classes(UIList):
|
class BIM_UL_bsdd_classes(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
layout: bpy.types.UILayout,
|
||||||
|
data: BIMBSDDProperties,
|
||||||
|
item: BSDDClassification,
|
||||||
|
icon,
|
||||||
|
active_data,
|
||||||
|
active_propname,
|
||||||
|
) -> None:
|
||||||
if item:
|
if item:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=item.name)
|
row.label(text=item.name)
|
||||||
@@ -103,7 +136,16 @@ class BIM_UL_bsdd_classes(UIList):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_UL_bsdd_properties(UIList):
|
class BIM_UL_bsdd_properties(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
layout: bpy.types.UILayout,
|
||||||
|
data: BIMBSDDProperties,
|
||||||
|
item: BSDDProperty,
|
||||||
|
icon,
|
||||||
|
active_data,
|
||||||
|
active_propname,
|
||||||
|
) -> None:
|
||||||
if item:
|
if item:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
name = item.name
|
name = item.name
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class ReferencesData:
|
|||||||
def active_classification_library(cls):
|
def active_classification_library(cls):
|
||||||
if not IfcStore.classification_file or not IfcStore.classification_file.by_type("IfcClassification"):
|
if not IfcStore.classification_file or not IfcStore.classification_file.by_type("IfcClassification"):
|
||||||
return False
|
return False
|
||||||
props = bpy.context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
||||||
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
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class AddClassification(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
ifcopenshell.api.classification.add_classification(
|
ifcopenshell.api.classification.add_classification(
|
||||||
tool.Ifc.get(),
|
tool.Ifc.get(),
|
||||||
classification=IfcStore.classification_file.by_id(int(props.available_classifications)),
|
classification=IfcStore.classification_file.by_id(int(props.available_classifications)),
|
||||||
@@ -60,7 +60,7 @@ class AddManualClassification(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
attributes = bonsai.bim.helper.export_attributes(props.classification_attributes)
|
attributes = bonsai.bim.helper.export_attributes(props.classification_attributes)
|
||||||
classification = ifcopenshell.api.classification.add_classification(tool.Ifc.get(), classification="Unnamed")
|
classification = ifcopenshell.api.classification.add_classification(tool.Ifc.get(), classification="Unnamed")
|
||||||
ifcopenshell.api.classification.edit_classification(
|
ifcopenshell.api.classification.edit_classification(
|
||||||
@@ -84,7 +84,7 @@ class AddManualClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
objects = [context.active_object.name]
|
objects = [context.active_object.name]
|
||||||
else:
|
else:
|
||||||
objects = [self.obj]
|
objects = [self.obj]
|
||||||
props = context.scene.BIMClassificationReferenceProperties
|
props = tool.Classification.get_classification_reference_props()
|
||||||
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
|
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
|
||||||
products = [
|
products = [
|
||||||
tool.Ifc.get().by_id(ifc_definition_id)
|
tool.Ifc.get().by_id(ifc_definition_id)
|
||||||
@@ -110,7 +110,7 @@ class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
cprops = context.scene.BIMClassificationProperties
|
cprops = tool.Classification.get_classification_props()
|
||||||
bprops = tool.Bsdd.get_bsdd_props()
|
bprops = tool.Bsdd.get_bsdd_props()
|
||||||
if cprops.classification_source == "BSDD":
|
if cprops.classification_source == "BSDD":
|
||||||
dictionaries = [d.uri for d in bprops.dictionaries if d.is_active]
|
dictionaries = [d.uri for d in bprops.dictionaries if d.is_active]
|
||||||
@@ -142,7 +142,7 @@ class EnableAddingManualClassification(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
props.is_adding = True
|
props.is_adding = True
|
||||||
props.active_classification_id = 0
|
props.active_classification_id = 0
|
||||||
props.classification_attributes.clear()
|
props.classification_attributes.clear()
|
||||||
@@ -156,7 +156,7 @@ class DisableAddingManualClassification(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
props.is_adding = False
|
props.is_adding = False
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ class EnableAddingManualClassificationReference(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationReferenceProperties
|
props = tool.Classification.get_classification_reference_props()
|
||||||
props.is_adding = True
|
props.is_adding = True
|
||||||
props.reference_attributes.clear()
|
props.reference_attributes.clear()
|
||||||
bonsai.bim.helper.import_attributes2("IfcClassificationReference", props.reference_attributes)
|
bonsai.bim.helper.import_attributes2("IfcClassificationReference", props.reference_attributes)
|
||||||
@@ -180,7 +180,7 @@ class DisableAddingManualClassificationReference(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationReferenceProperties
|
props = tool.Classification.get_classification_reference_props()
|
||||||
props.is_adding = False
|
props.is_adding = False
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ class EnableEditingClassification(bpy.types.Operator):
|
|||||||
new.string_value = "" if new.is_null else json.dumps(data[name])
|
new.string_value = "" if new.is_null else json.dumps(data[name])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
props.classification_attributes.clear()
|
props.classification_attributes.clear()
|
||||||
bonsai.bim.helper.import_attributes2(
|
bonsai.bim.helper.import_attributes2(
|
||||||
tool.Ifc.get().by_id(self.classification), props.classification_attributes, callback
|
tool.Ifc.get().by_id(self.classification), props.classification_attributes, callback
|
||||||
@@ -218,7 +218,8 @@ class DisableEditingClassification(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMClassificationProperties.active_classification_id = 0
|
props = tool.Classification.get_classification_props()
|
||||||
|
props.active_classification_id = 0
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -246,7 +247,7 @@ class EditClassification(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
|
|
||||||
def callback(attributes, prop):
|
def callback(attributes, prop):
|
||||||
if prop.name == "ReferenceTokens":
|
if prop.name == "ReferenceTokens":
|
||||||
@@ -271,7 +272,7 @@ class EnableEditingClassificationReference(bpy.types.Operator):
|
|||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationReferenceProperties
|
props = tool.Classification.get_classification_reference_props()
|
||||||
props.reference_attributes.clear()
|
props.reference_attributes.clear()
|
||||||
bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.reference), props.reference_attributes)
|
bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.reference), props.reference_attributes)
|
||||||
props.active_reference_id = self.reference
|
props.active_reference_id = self.reference
|
||||||
@@ -285,7 +286,7 @@ class DisableEditingClassificationReference(bpy.types.Operator):
|
|||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMClassificationReferenceProperties.active_reference_id = 0
|
tool.Classification.get_classification_reference_props().active_reference_id = 0
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -337,7 +338,7 @@ class EditClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMClassificationReferenceProperties
|
props = tool.Classification.get_classification_reference_props()
|
||||||
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
|
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
ifcopenshell.api.classification.edit_reference(
|
ifcopenshell.api.classification.edit_reference(
|
||||||
@@ -364,7 +365,7 @@ class AddClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
objects = [context.active_object.name]
|
objects = [context.active_object.name]
|
||||||
else:
|
else:
|
||||||
objects = [self.obj]
|
objects = [self.obj]
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
classification = None
|
classification = None
|
||||||
classification_name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
classification_name = IfcStore.classification_file.by_id(int(props.available_classifications)).Name
|
||||||
for element in tool.Ifc.get().by_type("IfcClassification"):
|
for element in tool.Ifc.get().by_type("IfcClassification"):
|
||||||
@@ -405,8 +406,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
objects = [context.active_object.name]
|
objects = [context.active_object.name]
|
||||||
else:
|
else:
|
||||||
objects = [self.obj]
|
objects = [self.obj]
|
||||||
props = context.scene.BIMClassificationProperties
|
bprops = tool.Bsdd.get_bsdd_props()
|
||||||
bprops = context.scene.BIMBSDDProperties
|
|
||||||
use_only_ifc_properties: bool = bprops.use_only_ifc_properties
|
use_only_ifc_properties: bool = bprops.use_only_ifc_properties
|
||||||
|
|
||||||
bsdd_classification = bprops.classifications[bprops.active_classification_index]
|
bsdd_classification = bprops.classifications[bprops.active_classification_index]
|
||||||
@@ -487,7 +487,7 @@ class ChangeClassificationLevel(bpy.types.Operator):
|
|||||||
parent_id: bpy.props.IntProperty()
|
parent_id: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
props.available_library_references.clear()
|
props.available_library_references.clear()
|
||||||
for reference in IfcStore.classification_file.by_id(self.parent_id).HasReferences:
|
for reference in IfcStore.classification_file.by_id(self.parent_id).HasReferences:
|
||||||
new = props.available_library_references.add()
|
new = props.available_library_references.add()
|
||||||
@@ -509,6 +509,6 @@ class DisableEditingClassificationReferences(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMClassificationProperties
|
props = tool.Classification.get_classification_props()
|
||||||
props.available_library_references.clear()
|
props.available_library_references.clear()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
import bonsai.tool as tool
|
||||||
from bonsai.bim.prop import Attribute
|
from bonsai.bim.prop import Attribute
|
||||||
from bonsai.bim.module.classification.data import ClassificationsData, ClassificationReferencesData
|
from bonsai.bim.module.classification.data import ClassificationsData, ClassificationReferencesData
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
@@ -30,9 +31,12 @@ from bpy.props import (
|
|||||||
FloatVectorProperty,
|
FloatVectorProperty,
|
||||||
CollectionProperty,
|
CollectionProperty,
|
||||||
)
|
)
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|
||||||
def get_available_classifications(self, context):
|
def get_available_classifications(
|
||||||
|
self: "BIMClassificationProperties", context: bpy.types.Context
|
||||||
|
) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||||
if not ClassificationsData.is_loaded:
|
if not ClassificationsData.is_loaded:
|
||||||
ClassificationsData.load()
|
ClassificationsData.load()
|
||||||
return ClassificationsData.data["available_classifications"]
|
return ClassificationsData.data["available_classifications"]
|
||||||
@@ -44,19 +48,26 @@ def get_classifications(self, context):
|
|||||||
return ClassificationReferencesData.data["classifications"]
|
return ClassificationReferencesData.data["classifications"]
|
||||||
|
|
||||||
|
|
||||||
def get_classification_source(self, context):
|
def get_classification_source(
|
||||||
|
self: "BIMClassificationProperties", context: bpy.types.Context
|
||||||
|
) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||||
if not ClassificationsData.is_loaded:
|
if not ClassificationsData.is_loaded:
|
||||||
ClassificationsData.load()
|
ClassificationsData.load()
|
||||||
return ClassificationsData.data["classification_source"]
|
return ClassificationsData.data["classification_source"]
|
||||||
|
|
||||||
|
|
||||||
class ClassificationReference(PropertyGroup):
|
class ClassificationReference(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
|
||||||
identification: StringProperty(name="Identification")
|
identification: StringProperty(name="Identification")
|
||||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||||
has_references: BoolProperty(name="Has References")
|
has_references: BoolProperty(name="Has References")
|
||||||
referenced_source: IntProperty(name="IFC Definition ID")
|
referenced_source: IntProperty(name="IFC Definition ID")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
identification: str
|
||||||
|
ifc_definition_id: int
|
||||||
|
has_references: bool
|
||||||
|
referenced_source: int
|
||||||
|
|
||||||
|
|
||||||
class BIMClassificationProperties(PropertyGroup):
|
class BIMClassificationProperties(PropertyGroup):
|
||||||
is_adding: BoolProperty(name="Is Adding", default=False)
|
is_adding: BoolProperty(name="Is Adding", default=False)
|
||||||
@@ -68,9 +79,25 @@ class BIMClassificationProperties(PropertyGroup):
|
|||||||
active_library_referenced_source: IntProperty(name="Active Library Referenced Source")
|
active_library_referenced_source: IntProperty(name="Active Library Referenced Source")
|
||||||
active_library_reference_index: IntProperty(name="Active Library Reference Index")
|
active_library_reference_index: IntProperty(name="Active Library Reference Index")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
is_adding: bool
|
||||||
|
classification_source: str
|
||||||
|
available_classifications: str
|
||||||
|
classification_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
|
||||||
|
active_classification_id: int
|
||||||
|
available_library_references: bpy.types.bpy_prop_collection_idprop[ClassificationReference]
|
||||||
|
active_library_referenced_source: int
|
||||||
|
active_library_reference_index: int
|
||||||
|
|
||||||
|
|
||||||
class BIMClassificationReferenceProperties(PropertyGroup):
|
class BIMClassificationReferenceProperties(PropertyGroup):
|
||||||
is_adding: BoolProperty(name="Is Adding", default=False)
|
is_adding: BoolProperty(name="Is Adding", default=False)
|
||||||
classifications: EnumProperty(items=get_classifications, name="Classifications")
|
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")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
is_adding: bool
|
||||||
|
classifications: str
|
||||||
|
reference_attributes: bpy.types.bpy_prop_collection_idprop
|
||||||
|
active_reference_id: int
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
import bpy
|
import bpy
|
||||||
import bonsai.bim.helper
|
import bonsai.bim.helper
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
@@ -27,6 +28,10 @@ from bonsai.bim.module.classification.data import (
|
|||||||
MaterialClassificationsData,
|
MaterialClassificationsData,
|
||||||
CostClassificationsData,
|
CostClassificationsData,
|
||||||
)
|
)
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bonsai.bim.module.classification.prop import BIMClassificationProperties, ClassificationReference
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_classifications(Panel):
|
class BIM_PT_classifications(Panel):
|
||||||
@@ -46,7 +51,8 @@ class BIM_PT_classifications(Panel):
|
|||||||
if not ClassificationsData.is_loaded:
|
if not ClassificationsData.is_loaded:
|
||||||
ClassificationsData.load()
|
ClassificationsData.load()
|
||||||
|
|
||||||
self.props = context.scene.BIMClassificationProperties
|
self.props = tool.Classification.get_classification_props()
|
||||||
|
assert self.layout
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text="Source", icon="OUTLINER")
|
row.label(text="Source", icon="OUTLINER")
|
||||||
@@ -110,9 +116,9 @@ class ReferenceUI:
|
|||||||
|
|
||||||
def draw_ui(self, context):
|
def draw_ui(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
self.sprops = context.scene.BIMClassificationProperties
|
self.sprops = tool.Classification.get_classification_props()
|
||||||
self.bprops = context.scene.BIMBSDDProperties
|
self.bprops = tool.Bsdd.get_bsdd_props()
|
||||||
self.props = context.scene.BIMClassificationReferenceProperties
|
self.props = tool.Classification.get_classification_reference_props()
|
||||||
self.file = tool.Ifc.get()
|
self.file = tool.Ifc.get()
|
||||||
|
|
||||||
self.draw_add_ui(context)
|
self.draw_add_ui(context)
|
||||||
@@ -315,7 +321,16 @@ class BIM_PT_cost_classifications(Panel, ReferenceUI):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_UL_classifications(UIList):
|
class BIM_UL_classifications(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
layout: bpy.types.UILayout,
|
||||||
|
data: BIMClassificationProperties,
|
||||||
|
item: ClassificationReference,
|
||||||
|
icon,
|
||||||
|
active_data,
|
||||||
|
active_propname,
|
||||||
|
):
|
||||||
if item:
|
if item:
|
||||||
if item.has_references:
|
if item.has_references:
|
||||||
op = layout.operator("bim.change_classification_level", text="", icon="DISCLOSURE_TRI_RIGHT")
|
op = layout.operator("bim.change_classification_level", text="", icon="DISCLOSURE_TRI_RIGHT")
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ class BIM_PT_object_psets(Panel):
|
|||||||
ObjectPsetsData.load()
|
ObjectPsetsData.load()
|
||||||
|
|
||||||
props = context.active_object.PsetProperties
|
props = context.active_object.PsetProperties
|
||||||
self.bprops = context.scene.BIMBSDDProperties
|
self.bprops = tool.Bsdd.get_bsdd_props()
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
prop_with_search(row, props, "pset_name", text="")
|
prop_with_search(row, props, "pset_name", text="")
|
||||||
if props.pset_name != "BBIM_BSDD" and not props.pset_name.startswith(tool.Bsdd.identifier_url):
|
if props.pset_name != "BBIM_BSDD" and not props.pset_name.startswith(tool.Bsdd.identifier_url):
|
||||||
|
|||||||
@@ -26,20 +26,20 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def import_bsdd_classes(bsdd: tool.Bsdd, obj, obj_type) -> int:
|
def import_bsdd_classes(bsdd: type[tool.Bsdd], obj, obj_type) -> int:
|
||||||
return bsdd.import_classes(obj, obj_type)
|
return bsdd.import_classes(obj, obj_type)
|
||||||
|
|
||||||
|
|
||||||
def search_bsdd_properties(bsdd: tool.Bsdd, keyword: str, obj, obj_type) -> int:
|
def search_bsdd_properties(bsdd: type[tool.Bsdd], keyword: str, obj, obj_type) -> int:
|
||||||
return bsdd.import_properties(obj, obj_type, keyword)
|
return bsdd.import_properties(obj, obj_type, keyword)
|
||||||
|
|
||||||
|
|
||||||
def load_bsdd(bsdd: tool.Bsdd) -> None:
|
def load_bsdd(bsdd: type[tool.Bsdd]) -> None:
|
||||||
bsdd.clear_dictionaries()
|
bsdd.clear_dictionaries()
|
||||||
bsdd.create_dictionaries(bsdd.get_dictionaries())
|
bsdd.create_dictionaries(bsdd.get_dictionaries())
|
||||||
|
|
||||||
|
|
||||||
def search_bsdd_class(bsdd: tool.Bsdd, keyword: str) -> int:
|
def search_bsdd_class(bsdd: type[tool.Bsdd], keyword: str) -> int:
|
||||||
bsdd.clear_classes()
|
bsdd.clear_classes()
|
||||||
related_entities = bsdd.get_related_ifc_entities()
|
related_entities = bsdd.get_related_ifc_entities()
|
||||||
return bsdd.search_class(keyword, related_entities)
|
return bsdd.search_class(keyword, related_entities)
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def unjoin_walls(
|
def unjoin_walls(
|
||||||
ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner: DumbWallJoiner, model: tool.Model
|
ifc: type[tool.Ifc],
|
||||||
|
blender: type[tool.Blender],
|
||||||
|
geometry: type[tool.Geometry],
|
||||||
|
joiner: DumbWallJoiner,
|
||||||
|
model: type[tool.Model],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Unjoin selected walls."""
|
"""Unjoin selected walls."""
|
||||||
for obj in blender.get_selected_objects():
|
for obj in blender.get_selected_objects():
|
||||||
@@ -45,11 +49,11 @@ def unjoin_walls(
|
|||||||
|
|
||||||
|
|
||||||
def extend_walls(
|
def extend_walls(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
blender: tool.Blender,
|
blender: type[tool.Blender],
|
||||||
geometry: tool.Geometry,
|
geometry: type[tool.Geometry],
|
||||||
joiner: DumbWallJoiner,
|
joiner: DumbWallJoiner,
|
||||||
model: tool.Model,
|
model: type[tool.Model],
|
||||||
target: Vector,
|
target: Vector,
|
||||||
connection: Optional[str] = None,
|
connection: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -62,11 +66,11 @@ def extend_walls(
|
|||||||
|
|
||||||
|
|
||||||
def join_walls_LV(
|
def join_walls_LV(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
blender: tool.Blender,
|
blender: type[tool.Blender],
|
||||||
geometry: tool.Geometry,
|
geometry: type[tool.Geometry],
|
||||||
joiner: DumbWallJoiner,
|
joiner: DumbWallJoiner,
|
||||||
model: tool.Model,
|
model: type[tool.Model],
|
||||||
join_type: Literal["L", "V"] = "L",
|
join_type: Literal["L", "V"] = "L",
|
||||||
) -> None:
|
) -> None:
|
||||||
selected_objs = [
|
selected_objs = [
|
||||||
@@ -86,7 +90,7 @@ def join_walls_LV(
|
|||||||
joiner.connect(another_selected_object, active_obj)
|
joiner.connect(another_selected_object, active_obj)
|
||||||
|
|
||||||
|
|
||||||
def offset_walls(ifc: tool.Ifc, blender: tool.Blender, model: tool.Model, offset_type: OffsetType):
|
def offset_walls(ifc: type[tool.Ifc], blender: type[tool.Blender], model: type[tool.Model], offset_type: OffsetType):
|
||||||
objs = [
|
objs = [
|
||||||
obj
|
obj
|
||||||
for obj in blender.get_selected_objects()
|
for obj in blender.get_selected_objects()
|
||||||
@@ -98,7 +102,11 @@ def offset_walls(ifc: tool.Ifc, blender: tool.Blender, model: tool.Model, offset
|
|||||||
|
|
||||||
|
|
||||||
def align_walls(
|
def align_walls(
|
||||||
ifc: tool.Ifc, blender: tool.Blender, model: tool.Model, aligner: DumbWallAligner, align_type: AlignType
|
ifc: type[tool.Ifc],
|
||||||
|
blender: type[tool.Blender],
|
||||||
|
model: type[tool.Model],
|
||||||
|
aligner: DumbWallAligner,
|
||||||
|
align_type: AlignType,
|
||||||
):
|
):
|
||||||
reference_obj = blender.get_active_object(is_selected=True)
|
reference_obj = blender.get_active_object(is_selected=True)
|
||||||
if not (e := ifc.get_entity(reference_obj) or not model.get_usage_type(e) == "LAYER2"):
|
if not (e := ifc.get_entity(reference_obj) or not model.get_usage_type(e) == "LAYER2"):
|
||||||
@@ -122,7 +130,9 @@ def align_walls(
|
|||||||
aligner.align_last_layer(obj)
|
aligner.align_last_layer(obj)
|
||||||
|
|
||||||
|
|
||||||
def align_objects(blender: tool.Blender, model: tool.Model, align_type: Literal["CENTER", "POSITIVE", "NEGATIVE"]):
|
def align_objects(
|
||||||
|
blender: type[tool.Blender], model: type[tool.Model], align_type: Literal["CENTER", "POSITIVE", "NEGATIVE"]
|
||||||
|
):
|
||||||
reference_obj = blender.get_active_object(is_selected=True)
|
reference_obj = blender.get_active_object(is_selected=True)
|
||||||
objs = [o for o in blender.get_selected_objects() if o != reference_obj]
|
objs = [o for o in blender.get_selected_objects() if o != reference_obj]
|
||||||
if not reference_obj or not objs:
|
if not reference_obj or not objs:
|
||||||
@@ -131,9 +141,9 @@ def align_objects(blender: tool.Blender, model: tool.Model, align_type: Literal[
|
|||||||
|
|
||||||
|
|
||||||
def extend_wall_to_slab(
|
def extend_wall_to_slab(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
geometry: tool.Geometry,
|
geometry: type[tool.Geometry],
|
||||||
model: tool.Model,
|
model: type[tool.Model],
|
||||||
slab_obj: bpy.types.Object,
|
slab_obj: bpy.types.Object,
|
||||||
wall_objs: list[bpy.types.Object],
|
wall_objs: list[bpy.types.Object],
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -150,7 +160,11 @@ def extend_wall_to_slab(
|
|||||||
|
|
||||||
|
|
||||||
def join_walls_TZ(
|
def join_walls_TZ(
|
||||||
ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner: DumbWallJoiner, model: tool.Model
|
ifc: type[tool.Ifc],
|
||||||
|
blender: type[tool.Blender],
|
||||||
|
geometry: type[tool.Geometry],
|
||||||
|
joiner: DumbWallJoiner,
|
||||||
|
model: type[tool.Model],
|
||||||
) -> None:
|
) -> None:
|
||||||
selected_objs = [
|
selected_objs = [
|
||||||
o
|
o
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
# Bonsai - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of Bonsai.
|
||||||
|
#
|
||||||
|
# Bonsai 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.
|
||||||
|
#
|
||||||
|
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
import bpy
|
import bpy
|
||||||
@@ -8,6 +27,9 @@ import ifcopenshell.util.element
|
|||||||
import ifcopenshell.util.classification
|
import ifcopenshell.util.classification
|
||||||
from typing import Any, Union, Optional, TYPE_CHECKING
|
from typing import Any, Union, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bonsai.bim.module.bsdd.prop import BIMBSDDProperties
|
||||||
|
|
||||||
|
|
||||||
class Bsdd(bonsai.core.tool.Bsdd):
|
class Bsdd(bonsai.core.tool.Bsdd):
|
||||||
identifier_url = "https://identifier.buildingsmart.org"
|
identifier_url = "https://identifier.buildingsmart.org"
|
||||||
@@ -16,28 +38,29 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
bsdd_properties: dict[str, dict] = {}
|
bsdd_properties: dict[str, dict] = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bsdd_props(cls):
|
def get_bsdd_props(cls) -> BIMBSDDProperties:
|
||||||
return bpy.context.scene.BIMBSDDProperties
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.BIMBSDDProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_class_psets(cls) -> None:
|
def clear_class_psets(cls) -> None:
|
||||||
bpy.context.scene.BIMBSDDProperties.classification_psets.clear()
|
cls.get_bsdd_props().classification_psets.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_classes(cls) -> None:
|
def clear_classes(cls) -> None:
|
||||||
bpy.context.scene.BIMBSDDProperties.classifications.clear()
|
cls.get_bsdd_props().classifications.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_properties(cls) -> None:
|
def clear_properties(cls) -> None:
|
||||||
bpy.context.scene.BIMBSDDProperties.properties.clear()
|
cls.get_bsdd_props().properties.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_dictionaries(cls) -> None:
|
def clear_dictionaries(cls) -> None:
|
||||||
bpy.context.scene.BIMBSDDProperties.dictionaries.clear()
|
cls.get_bsdd_props().dictionaries.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_class_psets(cls, pset_dict: dict[str, dict[str, Any]]) -> None:
|
def create_class_psets(cls, pset_dict: dict[str, dict[str, Any]]) -> None:
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = cls.get_bsdd_props()
|
||||||
data_type_map = {
|
data_type_map = {
|
||||||
"String": "string",
|
"String": "string",
|
||||||
"Real": "float",
|
"Real": "float",
|
||||||
@@ -60,7 +83,7 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_dictionaries(cls, dictionaries: list[bsdd.DictionaryContractV1]) -> None:
|
def create_dictionaries(cls, dictionaries: list[bsdd.DictionaryContractV1]) -> None:
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = cls.get_bsdd_props()
|
||||||
for dictionary in sorted(dictionaries, key=lambda d: d["name"]):
|
for dictionary in sorted(dictionaries, key=lambda d: d["name"]):
|
||||||
new = props.dictionaries.add()
|
new = props.dictionaries.add()
|
||||||
new.name = dictionary["name"]
|
new.name = dictionary["name"]
|
||||||
@@ -72,7 +95,7 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_active_class_data(cls) -> Union[bsdd.ClassContractV1, dict]:
|
def get_active_class_data(cls) -> Union[bsdd.ClassContractV1, dict]:
|
||||||
prop = bpy.context.scene.BIMBSDDProperties
|
prop = cls.get_bsdd_props()
|
||||||
bsdd_classification = prop.classifications[prop.active_classification_index]
|
bsdd_classification = prop.classifications[prop.active_classification_index]
|
||||||
if not bsdd_classification:
|
if not bsdd_classification:
|
||||||
return {}
|
return {}
|
||||||
@@ -80,18 +103,18 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_active_dictionary_uri(cls) -> str:
|
def get_active_dictionary_uri(cls) -> str:
|
||||||
return bpy.context.scene.BIMBSDDProperties.active_uri
|
return cls.get_bsdd_props().active_uri
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_dictionary(cls, uri: str) -> bsdd.DictionaryContractV1:
|
def get_dictionary(cls, uri: str) -> bsdd.DictionaryContractV1:
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = cls.get_bsdd_props()
|
||||||
response = cls.client.get_dictionary(dictionary_uri=uri, include_test_dictionaries=props.load_test_dictionaries)
|
response = cls.client.get_dictionary(dictionary_uri=uri, include_test_dictionaries=props.load_test_dictionaries)
|
||||||
if dicts := response.get("dictionaries"):
|
if dicts := response.get("dictionaries"):
|
||||||
return dicts[0]
|
return dicts[0]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_dictionaries(cls) -> list[bsdd.DictionaryContractV1]:
|
def get_dictionaries(cls) -> list[bsdd.DictionaryContractV1]:
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = cls.get_bsdd_props()
|
||||||
response = cls.client.get_dictionary(include_test_dictionaries=props.load_test_dictionaries)
|
response = cls.client.get_dictionary(include_test_dictionaries=props.load_test_dictionaries)
|
||||||
dicts = response.get("dictionaries") or []
|
dicts = response.get("dictionaries") or []
|
||||||
statuses = ["Active"]
|
statuses = ["Active"]
|
||||||
@@ -165,7 +188,7 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
should_paginate: bool = True,
|
should_paginate: bool = True,
|
||||||
):
|
):
|
||||||
cprops = bpy.context.scene.BIMClassificationProperties
|
cprops = tool.Classification.get_classification_props()
|
||||||
bprops = cls.get_bsdd_props()
|
bprops = cls.get_bsdd_props()
|
||||||
dictionary_uris = (
|
dictionary_uris = (
|
||||||
[d.uri for d in bprops.dictionaries if d.is_active]
|
[d.uri for d in bprops.dictionaries if d.is_active]
|
||||||
@@ -202,13 +225,13 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_active_bsdd(cls, name: str, uri: str) -> None:
|
def set_active_bsdd(cls, name: str, uri: str) -> None:
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = cls.get_bsdd_props()
|
||||||
props.active_dictionary = name
|
props.active_dictionary = name
|
||||||
props.active_uri = uri
|
props.active_uri = uri
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def should_filter_ifc_class(cls) -> bool:
|
def should_filter_ifc_class(cls) -> bool:
|
||||||
return bpy.context.scene.BIMBSDDProperties.should_filter_ifc_class
|
return cls.get_bsdd_props().should_filter_ifc_class
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bsdd_class(cls, uri: str) -> dict:
|
def get_bsdd_class(cls, uri: str) -> dict:
|
||||||
|
|||||||
@@ -22,10 +22,23 @@ import ifcopenshell.api
|
|||||||
import ifcopenshell.util.classification
|
import ifcopenshell.util.classification
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from typing import Union, assert_never
|
from typing import Union, assert_never, TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bonsai.bim.module.classification.prop import BIMClassificationReferenceProperties, BIMClassificationProperties
|
||||||
|
|
||||||
|
|
||||||
class Classification(bonsai.core.tool.Classification):
|
class Classification(bonsai.core.tool.Classification):
|
||||||
|
@classmethod
|
||||||
|
def get_classification_props(cls) -> BIMClassificationProperties:
|
||||||
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.BIMClassificationProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_classification_reference_props(cls) -> BIMClassificationReferenceProperties:
|
||||||
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.BIMClassificationReferenceProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_location(cls, classification: ifcopenshell.entity_instance) -> Union[str, None]:
|
def get_location(cls, classification: ifcopenshell.entity_instance) -> Union[str, None]:
|
||||||
schema = classification.file.schema
|
schema = classification.file.schema
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ class TestAddClassificationReferenceFromBSDD(NewFile):
|
|||||||
bpy.ops.bim.load_bsdd_domains()
|
bpy.ops.bim.load_bsdd_domains()
|
||||||
uri = "https://identifier.buildingsmart.org/uri/molio/cciconstruction/1.0"
|
uri = "https://identifier.buildingsmart.org/uri/molio/cciconstruction/1.0"
|
||||||
bpy.ops.bim.set_active_bsdd_domain(name="CCI Construction", uri=uri)
|
bpy.ops.bim.set_active_bsdd_domain(name="CCI Construction", uri=uri)
|
||||||
props = context.scene.BIMBSDDProperties
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
bpy.context.scene.BIMClassificationProperties.classification_source = "BSDD"
|
tool.Classification.get_classification_props().classification_source = "BSDD"
|
||||||
props.should_filter_ifc_class = True
|
props.should_filter_ifc_class = True
|
||||||
props.keyword = "Room"
|
props.keyword = "Room"
|
||||||
bpy.ops.bim.search_bsdd_classifications()
|
bpy.ops.bim.search_bsdd_classifications()
|
||||||
@@ -70,8 +70,8 @@ class TestAddClassificationReferenceFromBSDD(NewFile):
|
|||||||
bpy.ops.bim.load_bsdd_domains()
|
bpy.ops.bim.load_bsdd_domains()
|
||||||
uri = "https://identifier.buildingsmart.org/uri/molio/cciconstruction/1.0"
|
uri = "https://identifier.buildingsmart.org/uri/molio/cciconstruction/1.0"
|
||||||
bpy.ops.bim.set_active_bsdd_domain(name="CCI Construction", uri=uri)
|
bpy.ops.bim.set_active_bsdd_domain(name="CCI Construction", uri=uri)
|
||||||
props = context.scene.BIMBSDDProperties
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
bpy.context.scene.BIMClassificationProperties.classification_source = "BSDD"
|
tool.Classification.get_classification_props().classification_source = "BSDD"
|
||||||
props.should_filter_ifc_class = True
|
props.should_filter_ifc_class = True
|
||||||
props.keyword = "Room"
|
props.keyword = "Room"
|
||||||
bpy.ops.bim.search_bsdd_classifications()
|
bpy.ops.bim.search_bsdd_classifications()
|
||||||
@@ -103,12 +103,12 @@ class TestAddClassificationReferenceFromBSDD(NewFile):
|
|||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
assert element
|
assert element
|
||||||
|
|
||||||
props = context.scene.BIMBSDDProperties
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
props.load_preview_domains = True
|
props.load_preview_domains = True
|
||||||
bpy.ops.bim.load_bsdd_domains()
|
bpy.ops.bim.load_bsdd_domains()
|
||||||
uri = "https://identifier.buildingsmart.org/uri/ifcairport/ifcairport/0.9"
|
uri = "https://identifier.buildingsmart.org/uri/ifcairport/ifcairport/0.9"
|
||||||
bpy.ops.bim.set_active_bsdd_domain(name="IFC Airport", uri=uri)
|
bpy.ops.bim.set_active_bsdd_domain(name="IFC Airport", uri=uri)
|
||||||
bpy.context.scene.BIMClassificationProperties.classification_source = "BSDD"
|
tool.Classification.get_classification_props().classification_source = "BSDD"
|
||||||
props.should_filter_ifc_class = False # Important due to class mismatch.
|
props.should_filter_ifc_class = False # Important due to class mismatch.
|
||||||
props.keyword = "check-in conveyor"
|
props.keyword = "check-in conveyor"
|
||||||
bpy.ops.bim.search_bsdd_classifications()
|
bpy.ops.bim.search_bsdd_classifications()
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ class TestSetupActiveBsddClassification(NewFile):
|
|||||||
filepath = "test/files/temp/test.ifc"
|
filepath = "test/files/temp/test.ifc"
|
||||||
ifc_file.write(filepath)
|
ifc_file.write(filepath)
|
||||||
bpy.ops.bim.load_project(filepath=filepath)
|
bpy.ops.bim.load_project(filepath=filepath)
|
||||||
props = bpy.context.scene.BIMBSDDProperties
|
props = tool.Bsdd.get_bsdd_props()
|
||||||
assert props.active_domain == name
|
assert props.active_domain == name
|
||||||
assert props.active_uri == base_uri
|
assert props.active_uri == base_uri
|
||||||
|
|
||||||
|
|||||||
@@ -351,19 +351,18 @@ def log_internal_cpp_errors(f: ifcopenshell.file, filename: str, logger: Logger)
|
|||||||
logger.error(m)
|
logger.error(m)
|
||||||
|
|
||||||
|
|
||||||
entity_attribute_map: dict[tuple[str, str], tuple[entity_type, tuple[attribute]]] = {}
|
entity_attribute_map: dict[tuple[str, str], tuple[entity_type, tuple[attribute, ...]]] = {}
|
||||||
|
|
||||||
|
|
||||||
def get_entity_attributes(schema: schema_definition, entity: str) -> tuple[entity_type, tuple[attribute]]:
|
def get_entity_attributes(schema: schema_definition, entity: str) -> tuple[entity_type, tuple[attribute, ...]]:
|
||||||
cache_key = schema.name(), entity
|
cache_key = schema.name(), entity
|
||||||
from_cache = entity_attribute_map.get(cache_key)
|
from_cache = entity_attribute_map.get(cache_key)
|
||||||
if from_cache:
|
if from_cache:
|
||||||
return from_cache
|
return from_cache
|
||||||
|
|
||||||
entity_attrs = (
|
ent = schema.declaration_by_name(entity).as_entity()
|
||||||
ent := schema.declaration_by_name(entity),
|
assert ent
|
||||||
ent.all_attributes(),
|
entity_attrs = (ent, ent.all_attributes())
|
||||||
)
|
|
||||||
|
|
||||||
entity_attribute_map[cache_key] = entity_attrs
|
entity_attribute_map[cache_key] = entity_attrs
|
||||||
return entity_attrs
|
return entity_attrs
|
||||||
|
|||||||
@@ -17,12 +17,14 @@
|
|||||||
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.guid
|
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
|
import ifcpatch
|
||||||
|
import logging
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher(ifcpatch.BasePatcher):
|
||||||
def __init__(self, file, logger):
|
def __init__(self, file: ifcopenshell.file, logger: Union[logging.Logger, None] = None):
|
||||||
"""Merge identical styles together
|
"""Merge identical styles together
|
||||||
|
|
||||||
Some software may create an obscene number of styles instead of reusing
|
Some software may create an obscene number of styles instead of reusing
|
||||||
@@ -35,8 +37,7 @@ class Patcher:
|
|||||||
|
|
||||||
ifcpatch.execute({"file": model, "recipe": "MergeStyles", "arguments": []})
|
ifcpatch.execute({"file": model, "recipe": "MergeStyles", "arguments": []})
|
||||||
"""
|
"""
|
||||||
self.file = file
|
super().__init__(file, logger)
|
||||||
self.logger = logger
|
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
for ifc_class in ("IfcColourRgb", "IfcSurfaceStyleShading", "IfcPresentationStyle"):
|
for ifc_class in ("IfcColourRgb", "IfcSurfaceStyleShading", "IfcPresentationStyle"):
|
||||||
|
|||||||
Reference in New Issue
Block a user