mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
update BsDD to match new API
+ move Functions from operator to core/tool
This commit is contained in:
committed by
Dion Moult
parent
27f6ac0575
commit
e159151b44
@@ -22,8 +22,8 @@ from . import ui, prop, operator
|
||||
classes = (
|
||||
operator.GetBSDDClassificationProperties,
|
||||
operator.LoadBSDDDomains,
|
||||
operator.SearchBSDDClassifications,
|
||||
operator.SetActiveBSDDDomain,
|
||||
operator.SearchBSDDClass,
|
||||
operator.SetActiveBSDDDictionary,
|
||||
prop.BSDDDomain,
|
||||
prop.BSDDClassification,
|
||||
prop.BSDDPset,
|
||||
|
||||
@@ -22,73 +22,39 @@ import bsdd
|
||||
import json
|
||||
import ifcopenshell
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.core import bsdd as core
|
||||
from blenderbim.tool.bsdd import Bsdd
|
||||
|
||||
|
||||
class LoadBSDDDomains(bpy.types.Operator):
|
||||
bl_idname = "bim.load_bsdd_domains"
|
||||
bl_label = "Load bSDD Domains"
|
||||
bl_label = "Load bSDD Dictionaries"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
props.domains.clear()
|
||||
client = bsdd.Client()
|
||||
|
||||
if props.load_preview_domains:
|
||||
domains = client.Domain()
|
||||
else:
|
||||
domains = [d for d in client.Domain() if d["status"] == "Active"]
|
||||
|
||||
for domain in sorted(domains, key=lambda x: x["name"]):
|
||||
new = props.domains.add()
|
||||
new.name = domain["name"]
|
||||
new.namespace_uri = domain["namespaceUri"]
|
||||
new.default_language_code = domain["defaultLanguageCode"]
|
||||
new.organization_name_owner = domain["organizationNameOwner"]
|
||||
new.status = domain["status"]
|
||||
new.version = domain["version"]
|
||||
core.load_bsdd(context.scene.BIMBSDDProperties, bsdd.Client(), Bsdd)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SetActiveBSDDDomain(bpy.types.Operator):
|
||||
class SetActiveBSDDDictionary(bpy.types.Operator):
|
||||
bl_idname = "bim.set_active_bsdd_domain"
|
||||
bl_label = "Load bSDD Domains"
|
||||
bl_label = "Load bSDD Dictionary"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
name: bpy.props.StringProperty()
|
||||
uri: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
props.active_domain = self.name
|
||||
props.active_uri = self.uri
|
||||
core.set_active_bsdd_dictionary(context, self.name, self.uri)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SearchBSDDClassifications(bpy.types.Operator):
|
||||
class SearchBSDDClass(bpy.types.Operator):
|
||||
bl_idname = "bim.search_bsdd_classifications"
|
||||
bl_label = "Search bSDD Classifications"
|
||||
bl_label = "Search bSDD Class"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
props.classifications.clear()
|
||||
client = bsdd.Client()
|
||||
related_ifc_entities = []
|
||||
if len(props.keyword) < 3:
|
||||
return {"FINISHED"}
|
||||
if props.should_filter_ifc_class and context.active_object:
|
||||
element = tool.Ifc.get_entity(context.active_object)
|
||||
if element:
|
||||
related_ifc_entities = [element.is_a()]
|
||||
results = client.ClassificationSearchOpen(props.keyword, DomainNamespaceUris=[props.active_uri], RelatedIfcEntities=related_ifc_entities)
|
||||
for result in sorted(results["classifications"], key=lambda x: x["referenceCode"]):
|
||||
new = props.classifications.add()
|
||||
new.name = result["name"]
|
||||
new.reference_code = result["referenceCode"]
|
||||
new.description = result.get("description", "")
|
||||
new.namespace_uri = result["namespaceUri"]
|
||||
new.domain_name = result["domainName"]
|
||||
new.domain_namespace_uri = result["domainNamespaceUri"]
|
||||
core.search_class(context, bsdd.Client(), tool.Bsdd, tool.Ifc)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -98,50 +64,5 @@ class GetBSDDClassificationProperties(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
bprops = context.scene.BIMBSDDProperties
|
||||
bprops.classification_psets.clear()
|
||||
bsdd_classification = bprops.classifications[bprops.active_classification_index]
|
||||
client = bsdd.Client()
|
||||
data = client.Classification(bsdd_classification.namespace_uri)
|
||||
|
||||
properties = data.get("classificationProperties", None)
|
||||
if not properties:
|
||||
return {"FINISHED"}
|
||||
|
||||
psets = {}
|
||||
|
||||
for prop in properties:
|
||||
if prop.get("propertyDomainName") != "IFC":
|
||||
continue
|
||||
pset = prop.get("propertySet", None)
|
||||
if not pset:
|
||||
continue
|
||||
psets.setdefault(pset, {})
|
||||
|
||||
predefined_value = prop.get("predefinedValue")
|
||||
if predefined_value:
|
||||
possible_values = [predefined_value]
|
||||
else:
|
||||
possible_values = prop.get("possibleValues", []) or []
|
||||
possible_values = [v["value"] for v in possible_values]
|
||||
|
||||
psets[pset][prop["name"]] = {"data_type": prop["dataType"], "possible_values": possible_values}
|
||||
|
||||
data_type_map = {
|
||||
"String": "string",
|
||||
"Real": "float",
|
||||
"Boolean": "boolean",
|
||||
}
|
||||
|
||||
for pset_name, pset in psets.items():
|
||||
new = bprops.classification_psets.add()
|
||||
new.name = pset_name
|
||||
for name, data in pset.items():
|
||||
new2 = new.properties.add()
|
||||
new2.name = name
|
||||
if data["possible_values"]:
|
||||
new2.enum_items = json.dumps(data["possible_values"])
|
||||
new2.data_type = "enum"
|
||||
else:
|
||||
new2.data_type = data_type_map[data["data_type"]]
|
||||
core.get_class_properties(context, bsdd.Client(), tool.Bsdd)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -33,7 +33,7 @@ from bpy.props import (
|
||||
|
||||
class BSDDDomain(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
namespace_uri: StringProperty(name="URI")
|
||||
uri: StringProperty(name="URI")
|
||||
default_language_code: StringProperty(name="Language")
|
||||
organization_name_owner: StringProperty(name="Organization")
|
||||
status: StringProperty(name="Status")
|
||||
@@ -44,7 +44,7 @@ class BSDDClassification(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
reference_code: StringProperty(name="Reference Code")
|
||||
description: StringProperty(name="Description")
|
||||
namespace_uri: StringProperty(name="Namespace URI")
|
||||
uri: StringProperty(name="Namespace URI")
|
||||
domain_name: StringProperty(name="Domain Name")
|
||||
domain_namespace_uri: StringProperty(name="Domain Namespace URI")
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class BIM_UL_bsdd_domains(UIList):
|
||||
row.label(text=f"{item.name} ({item.organization_name_owner})")
|
||||
op = row.operator("bim.set_active_bsdd_domain", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.name = item.name
|
||||
op.uri = item.namespace_uri
|
||||
op.uri = item.uri
|
||||
|
||||
|
||||
class BIM_UL_bsdd_classifications(UIList):
|
||||
|
||||
@@ -107,13 +107,13 @@ class AddClassificationFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
domain = [d for d in props.domains if d.name == props.active_domain][0]
|
||||
for element in tool.Ifc.get().by_type("IfcClassification"):
|
||||
if element.Name == props.active_domain or element.Location == domain.namespace_uri:
|
||||
if element.Name == props.active_domain or element.Location == domain.uri:
|
||||
return
|
||||
classification = ifcopenshell.api.run(
|
||||
"classification.add_classification", tool.Ifc.get(), classification=props.active_domain
|
||||
)
|
||||
classification.Source = domain.organization_name_owner
|
||||
classification.Location = domain.namespace_uri
|
||||
classification.Location = domain.uri
|
||||
classification.Edition = domain.version
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
|
||||
identification=bsdd_classification.reference_code,
|
||||
name=bsdd_classification.name,
|
||||
)
|
||||
reference.Location = bsdd_classification.namespace_uri
|
||||
reference.Location = bsdd_classification.uri
|
||||
|
||||
for classification_pset in bprops.classification_psets:
|
||||
is_pset = not classification_pset.name.startswith("Qto_")
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
def load_bsdd(props, client, bsdd):
|
||||
props.domains.clear()
|
||||
if props.load_preview_domains:
|
||||
dictionaries = bsdd.get_dictionaries(client)
|
||||
else:
|
||||
dictionaries = bsdd.get_dictionaries(client, "Active")
|
||||
if not props.load_preview_domains:
|
||||
dictionaries = filter(lambda d: d["status"] == "Active", dictionaries)
|
||||
for dictionary in sorted(dictionaries, key=lambda d: d["name"]):
|
||||
new = props.domains.add()
|
||||
bsdd.fill_dictionary_prop(new, dictionary)
|
||||
|
||||
|
||||
def set_active_bsdd_dictionary(context, name, uri):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
props.active_domain = name
|
||||
props.active_uri = uri
|
||||
|
||||
|
||||
def search_class(context, client, bsdd, ifc):
|
||||
props = context.scene.BIMBSDDProperties
|
||||
props.classifications.clear()
|
||||
if len(props.keyword) < 3:
|
||||
return
|
||||
related_entities = bsdd.get_related_ifc_entities(props.keyword, props.should_filter_ifc_class,
|
||||
context.active_object, ifc)
|
||||
response: dict = client.search_class(props.keyword, dictionary_uris=[props.active_uri],
|
||||
related_ifc_entities=related_entities)
|
||||
classes = response.get("classes", [])
|
||||
for _class in sorted(classes, key=lambda c: c["referenceCode"]):
|
||||
bsdd.fill_class_prop(props.classifications.add(), _class)
|
||||
|
||||
|
||||
def get_class_properties(context, client, bsdd):
|
||||
bprops = context.scene.BIMBSDDProperties
|
||||
data = bsdd.get_active_class_data(bprops, client)
|
||||
pset_dict = bsdd.get_property_dict(data)
|
||||
if pset_dict is None:
|
||||
return
|
||||
bsdd.create_classification_psets(bprops, pset_dict)
|
||||
@@ -136,6 +136,20 @@ class Brick:
|
||||
def clear_breadcrumbs(cls, split_screen=False): pass
|
||||
|
||||
|
||||
class Bsdd:
|
||||
def get_dictionaries(cls, client): pass
|
||||
|
||||
def fill_dictionary_prop(cls, prop, dictionary): pass
|
||||
|
||||
def get_related_ifc_entities(cls, keyword, filter_ifc_class, active_object, ifc): pass
|
||||
|
||||
def fill_class_prop(cls, prop, _class): pass
|
||||
|
||||
def get_active_class_data(cls, prop, client): pass
|
||||
|
||||
def get_property_dict(cls, class_data): pass
|
||||
|
||||
def create_classification_psets(cls, props, pset_dic): pass
|
||||
@interface
|
||||
class Collector:
|
||||
def assign(cls, obj): pass
|
||||
|
||||
@@ -20,6 +20,7 @@ from blenderbim.tool.aggregate import Aggregate
|
||||
from blenderbim.tool.blender import Blender
|
||||
from blenderbim.tool.boundary import Boundary
|
||||
from blenderbim.tool.brick import Brick
|
||||
from blenderbim.tool.bsdd import Bsdd
|
||||
from blenderbim.tool.cad import Cad
|
||||
from blenderbim.tool.collector import Collector
|
||||
from blenderbim.tool.context import Context
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import blenderbim.core.tool
|
||||
import json
|
||||
|
||||
|
||||
class Bsdd(blenderbim.core.tool.Bsdd):
|
||||
@classmethod
|
||||
def get_dictionaries(cls, client, status=None) -> list:
|
||||
response = client.get_dictionary()
|
||||
dicts = response.get("dictionaries") or []
|
||||
if status is not None:
|
||||
dicts = filter(lambda d: d["status"] == status, dicts)
|
||||
return dicts
|
||||
|
||||
@classmethod
|
||||
def fill_dictionary_prop(cls, prop, dictionary):
|
||||
prop.name = dictionary["name"]
|
||||
prop.uri = dictionary["uri"]
|
||||
prop.default_language_code = dictionary["defaultLanguageCode"]
|
||||
prop.organization_name_owner = dictionary["organizationNameOwner"]
|
||||
prop.status = dictionary["status"]
|
||||
prop.version = dictionary["version"]
|
||||
|
||||
@classmethod
|
||||
def get_related_ifc_entities(cls, keyword, filter_ifc_class: bool, active_object, ifc):
|
||||
related_ifc_entities = []
|
||||
if len(keyword) < 3:
|
||||
return {"FINISHED"}
|
||||
if filter_ifc_class and active_object:
|
||||
element = ifc.get_entity(active_object)
|
||||
if element:
|
||||
related_ifc_entities = [element.is_a()]
|
||||
return related_ifc_entities
|
||||
|
||||
@classmethod
|
||||
def fill_class_prop(cls, prop, _class: dict):
|
||||
prop.name = _class["name"]
|
||||
prop.reference_code = _class["referenceCode"]
|
||||
prop.description = _class.get("description", "")
|
||||
prop.uri = _class["uri"]
|
||||
prop.domain_name = _class["dictionaryName"]
|
||||
prop.domain_namespace_uri = _class["dictionaryUri"]
|
||||
|
||||
@classmethod
|
||||
def get_active_class_data(cls, prop, client):
|
||||
prop.classification_psets.clear()
|
||||
bsdd_classification = prop.classifications[prop.active_classification_index]
|
||||
return client.get_class(bsdd_classification.uri)
|
||||
|
||||
@classmethod
|
||||
def get_property_dict(cls, class_data: dict):
|
||||
properties = class_data.get("classProperties", None)
|
||||
if not properties:
|
||||
return None
|
||||
|
||||
psets = {}
|
||||
for prop in properties:
|
||||
if prop.get("propertyDictionaryName") == "IFC":
|
||||
continue
|
||||
pset = prop.get("propertySet", None)
|
||||
if not pset:
|
||||
continue
|
||||
psets.setdefault(pset, {})
|
||||
|
||||
predefined_value = prop.get("predefinedValue")
|
||||
if predefined_value:
|
||||
possible_values = [predefined_value]
|
||||
else:
|
||||
possible_values = prop.get("allowedValues", []) or []
|
||||
possible_values = [v["value"] for v in possible_values]
|
||||
|
||||
psets[pset][prop["name"]] = {"data_type": prop["dataType"], "possible_values": possible_values}
|
||||
return psets
|
||||
|
||||
@classmethod
|
||||
def create_classification_psets(cls, props, pset_dict: dict):
|
||||
data_type_map = {
|
||||
"String": "string",
|
||||
"Real": "float",
|
||||
"Boolean": "boolean",
|
||||
}
|
||||
for pset_name, pset in pset_dict.items():
|
||||
new = props.classification_psets.add()
|
||||
new.name = pset_name
|
||||
for name, data in pset.items():
|
||||
new2 = new.properties.add()
|
||||
new2.name = name
|
||||
if data["possible_values"]:
|
||||
new2.enum_items = json.dumps(data["possible_values"])
|
||||
new2.data_type = "enum"
|
||||
else:
|
||||
new2.data_type = data_type_map[data["data_type"]]
|
||||
Reference in New Issue
Block a user