This commit is contained in:
Andrej730
2024-07-25 16:41:02 +05:00
parent 33e188b321
commit eac4e80ee9
5 changed files with 62 additions and 23 deletions
+33 -5
View File
@@ -1,4 +1,32 @@
def get_class_properties(client, bsdd): # BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 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/>.
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING:
import bpy
import ifcopenshell
import bsdd
import blenderbim.tool as tool
def get_class_properties(client: bsdd.Client, bsdd: tool.Bsdd) -> None:
bsdd.clear_class_psets() bsdd.clear_class_psets()
data = bsdd.get_active_class_data(client) data = bsdd.get_active_class_data(client)
pset_dict = bsdd.get_property_dict(data) pset_dict = bsdd.get_property_dict(data)
@@ -7,7 +35,7 @@ def get_class_properties(client, bsdd):
bsdd.create_class_psets(pset_dict) bsdd.create_class_psets(pset_dict)
def load_bsdd(client, bsdd): def load_bsdd(client: bsdd.Client, bsdd: tool.Bsdd) -> None:
bsdd.clear_domains() bsdd.clear_domains()
if bsdd.should_load_preview_domains: if bsdd.should_load_preview_domains:
dictionaries = bsdd.get_dictionaries(client) dictionaries = bsdd.get_dictionaries(client)
@@ -16,15 +44,15 @@ def load_bsdd(client, bsdd):
bsdd.create_dictionaries(dictionaries) bsdd.create_dictionaries(dictionaries)
def search_class(keyword: str, client, bsdd): def search_class(keyword: str, client: bsdd.Client, bsdd: tool.Bsdd) -> None:
bsdd.clear_classes() bsdd.clear_classes()
if len(keyword) < 3: if len(keyword) < 3:
return return
related_entities = bsdd.get_related_ifc_entities(keyword) related_entities = bsdd.get_related_ifc_entities(keyword)
active_dictionary_uri = bsdd.get_active_dictionary_uri() active_dictionary_uri = bsdd.get_active_dictionary_uri()
classes: dict = bsdd.search_class(client, keyword, [active_dictionary_uri], related_entities) classes = bsdd.search_class(client, keyword, [active_dictionary_uri], related_entities)
bsdd.create_classes(classes) bsdd.create_classes(classes)
def set_active_bsdd_dictionary(name: str, uri: str, bsdd): def set_active_bsdd_dictionary(name: str, uri: str, bsdd: tool.Bsdd) -> None:
bsdd.set_active_bsdd(name, uri) bsdd.set_active_bsdd(name, uri)
+1
View File
@@ -139,6 +139,7 @@ class Brick:
def clear_breadcrumbs(cls, split_screen=False): pass def clear_breadcrumbs(cls, split_screen=False): pass
@interface
class Bsdd: class Bsdd:
def clear_class_psets(cls): pass def clear_class_psets(cls): pass
def clear_classes(cls): pass def clear_classes(cls): pass
+23 -13
View File
@@ -2,10 +2,11 @@ import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
import bpy import bpy
import json import json
import bsdd
from typing import Any, Union, Optional
class Bsdd(blenderbim.core.tool.Bsdd): class Bsdd(blenderbim.core.tool.Bsdd):
@classmethod @classmethod
def clear_class_psets(cls) -> None: def clear_class_psets(cls) -> None:
bpy.context.scene.BIMBSDDProperties.classification_psets.clear() bpy.context.scene.BIMBSDDProperties.classification_psets.clear()
@@ -19,7 +20,7 @@ class Bsdd(blenderbim.core.tool.Bsdd):
bpy.context.scene.BIMBSDDProperties.domains.clear() bpy.context.scene.BIMBSDDProperties.domains.clear()
@classmethod @classmethod
def create_class_psets(cls, pset_dict: dict): def create_class_psets(cls, pset_dict: dict[str, dict[str, Any]]) -> None:
props = bpy.context.scene.BIMBSDDProperties props = bpy.context.scene.BIMBSDDProperties
data_type_map = { data_type_map = {
"String": "string", "String": "string",
@@ -39,7 +40,7 @@ class Bsdd(blenderbim.core.tool.Bsdd):
new2.data_type = data_type_map[data["data_type"]] new2.data_type = data_type_map[data["data_type"]]
@classmethod @classmethod
def create_classes(cls, class_dict): def create_classes(cls, class_dict: list[bsdd.ClassSearchResponseClassContractV1]) -> None:
props = bpy.context.scene.BIMBSDDProperties props = bpy.context.scene.BIMBSDDProperties
for _class in sorted(class_dict, key=lambda c: c["referenceCode"]): for _class in sorted(class_dict, key=lambda c: c["referenceCode"]):
prop = props.classifications.add() prop = props.classifications.add()
@@ -51,7 +52,7 @@ class Bsdd(blenderbim.core.tool.Bsdd):
prop.domain_namespace_uri = _class["dictionaryUri"] prop.domain_namespace_uri = _class["dictionaryUri"]
@classmethod @classmethod
def create_dictionaries(cls, dictionaries: dict): def create_dictionaries(cls, dictionaries: list[bsdd.DictionaryContractV1]) -> None:
props = bpy.context.scene.BIMBSDDProperties props = bpy.context.scene.BIMBSDDProperties
for dictionary in sorted(dictionaries, key=lambda d: d["name"]): for dictionary in sorted(dictionaries, key=lambda d: d["name"]):
new = props.domains.add() new = props.domains.add()
@@ -63,7 +64,7 @@ class Bsdd(blenderbim.core.tool.Bsdd):
new.version = dictionary["version"] new.version = dictionary["version"]
@classmethod @classmethod
def get_active_class_data(cls, client): def get_active_class_data(cls, client: bsdd.Client) -> Union[bsdd.ClassContractV1, dict]:
prop = bpy.context.scene.BIMBSDDProperties prop = bpy.context.scene.BIMBSDDProperties
bsdd_classification = prop.classifications[prop.active_classification_index] bsdd_classification = prop.classifications[prop.active_classification_index]
if not bsdd_classification: if not bsdd_classification:
@@ -75,15 +76,15 @@ class Bsdd(blenderbim.core.tool.Bsdd):
return bpy.context.scene.BIMBSDDProperties.active_uri return bpy.context.scene.BIMBSDDProperties.active_uri
@classmethod @classmethod
def get_dictionaries(cls, client, status=None) -> list: def get_dictionaries(cls, client: bsdd.Client, status: Optional[str] = None) -> list[bsdd.DictionaryContractV1]:
response = client.get_dictionary() response = client.get_dictionary()
dicts = response.get("dictionaries") or [] dicts = response.get("dictionaries") or []
if status is not None: if status is not None:
dicts = filter(lambda d: d["status"] == status, dicts) dicts = list(filter(lambda d: d["status"] == status, dicts))
return dicts return dicts
@classmethod @classmethod
def get_property_dict(cls, class_data: dict): def get_property_dict(cls, class_data: Union[bsdd.ClassContractV1, dict]) -> Union[dict[str, dict[str, Any]], None]:
properties = class_data.get("classProperties", None) properties = class_data.get("classProperties", None)
if not properties: if not properties:
return None return None
@@ -108,9 +109,11 @@ class Bsdd(blenderbim.core.tool.Bsdd):
return psets return psets
@classmethod @classmethod
def get_related_ifc_entities(cls, keyword): def get_related_ifc_entities(cls, keyword: str) -> list[str]:
active_object = bpy.context.active_object active_object = bpy.context.active_object
related_ifc_entities = [] related_ifc_entities = []
# TODO: keyword length seems to be already double-checked in core.
# And {"FINISHED"} return value is never used.
if len(keyword) < 3: if len(keyword) < 3:
return {"FINISHED"} return {"FINISHED"}
if cls.should_filter_ifc_class() and active_object: if cls.should_filter_ifc_class() and active_object:
@@ -120,13 +123,20 @@ class Bsdd(blenderbim.core.tool.Bsdd):
return related_ifc_entities return related_ifc_entities
@classmethod @classmethod
def search_class(cls, client, keyword, dictionary_uris, related_ifc_entities) -> dict: def search_class(
response = client.search_class(keyword, dictionary_uris=dictionary_uris, cls,
related_ifc_entities=related_ifc_entities) client: bsdd.Client,
keyword: str,
dictionary_uris: Union[list[str], None],
related_ifc_entities: Union[list[str], None],
) -> list[bsdd.ClassSearchResponseClassContractV1]:
response = client.search_class(
keyword, dictionary_uris=dictionary_uris, related_ifc_entities=related_ifc_entities
)
return response.get("classes", []) return response.get("classes", [])
@classmethod @classmethod
def set_active_bsdd(cls, name, uri): def set_active_bsdd(cls, name: str, uri: str) -> None:
props = bpy.context.scene.BIMBSDDProperties props = bpy.context.scene.BIMBSDDProperties
props.active_domain = name props.active_domain = name
props.active_uri = uri props.active_uri = uri
+2 -2
View File
@@ -725,8 +725,8 @@ class Client:
def search_class( def search_class(
self, self,
search_text: str, search_text: str,
dictionary_uris=None, dictionary_uris: Optional[list[str]] = None,
related_ifc_entities=None, related_ifc_entities: Optional[list[str]] = None,
version: int = 1, version: int = 1,
offset: int = 0, offset: int = 0,
limit: int = 100, limit: int = 100,
+3 -3
View File
@@ -24,7 +24,7 @@ import zipfile
import functools import functools
import ifcopenshell import ifcopenshell
from pathlib import Path from pathlib import Path
from typing import Optional, Any, Union, Callable, Generator from typing import Optional, Any, Union, Callable, Generator, Literal
from . import ifcopenshell_wrapper from . import ifcopenshell_wrapper
from .entity_instance import entity_instance from .entity_instance import entity_instance
@@ -406,7 +406,7 @@ class file:
return e return e
@property @property
def schema(self) -> str: def schema(self) -> Literal["IFC2X3", "IFC4", "IFC4X3"]:
"""General IFC schema version: IFC2X3, IFC4, IFC4X3.""" """General IFC schema version: IFC2X3, IFC4, IFC4X3."""
prefixes = ("IFC", "X", "_ADD", "_TC") prefixes = ("IFC", "X", "_ADD", "_TC")
reg = "".join(f"(?P<{s}>{s}\d+)?" for s in prefixes) reg = "".join(f"(?P<{s}>{s}\d+)?" for s in prefixes)
@@ -668,5 +668,5 @@ class file:
return file(ifcopenshell_wrapper.read(s)) return file(ifcopenshell_wrapper.read(s))
@staticmethod @staticmethod
def from_pointer(v): def from_pointer(v) -> "file":
return file_dict.get(v)() return file_dict.get(v)()