mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 18:43:26 +00:00
bSDD searches now work on type classes as well as predefined types
This commit is contained in:
@@ -300,7 +300,6 @@ class IfcImporter:
|
||||
tool.Spatial.run_spatial_import_spatial_decomposition()
|
||||
if default_container := tool.Spatial.guess_default_container():
|
||||
tool.Spatial.set_default_container(default_container)
|
||||
tool.Loader.setup_active_bsdd_classification()
|
||||
self.update_progress(100)
|
||||
bpy.context.window_manager.progress_end()
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import bonsai.tool as tool
|
||||
import bpy
|
||||
import json
|
||||
import bsdd
|
||||
import ifcopenshell.util.type
|
||||
import ifcopenshell.util.element
|
||||
from typing import Any, Union, Optional, TYPE_CHECKING
|
||||
|
||||
|
||||
@@ -131,9 +133,17 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
||||
active_object = bpy.context.active_object
|
||||
related_ifc_entities = []
|
||||
if cls.should_filter_ifc_class() and active_object:
|
||||
element = tool.Ifc.get_entity(active_object)
|
||||
if element:
|
||||
related_ifc_entities = [element.is_a()]
|
||||
if element := tool.Ifc.get_entity(active_object):
|
||||
ifc_class = element.is_a()
|
||||
if element.is_a("IfcElementType"):
|
||||
ifc_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, schema=tool.Ifc.get().schema)[
|
||||
0
|
||||
]
|
||||
related_ifc_entities = [ifc_class]
|
||||
if (
|
||||
predefined_type := ifcopenshell.util.element.get_predefined_type(element)
|
||||
) and predefined_type != "NOTDEFINED":
|
||||
related_ifc_entities.append(ifc_class + predefined_type)
|
||||
return related_ifc_entities
|
||||
|
||||
@classmethod
|
||||
@@ -152,23 +162,24 @@ class Bsdd(bonsai.core.tool.Bsdd):
|
||||
else [props.active_dictionary]
|
||||
)
|
||||
for dictionary_uri in dictionary_uris:
|
||||
response = cls.client.get_classes(
|
||||
dictionary_uri=dictionary_uri,
|
||||
use_nested_classes=False,
|
||||
search_text=keyword,
|
||||
related_ifc_entity=related_ifc_entities[0] if related_ifc_entities else None,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
)
|
||||
dictionary_name = response.get("name", "")
|
||||
dictionary_namespace_uri = response.get("uri", "")
|
||||
for _class in sorted(response.get("classes", []), key=lambda c: c["referenceCode"]):
|
||||
prop = props.classifications.add()
|
||||
prop.name = _class["name"]
|
||||
prop.reference_code = _class["referenceCode"]
|
||||
prop.uri = _class["uri"]
|
||||
prop.dictionary_name = dictionary_name
|
||||
prop.dictionary_namespace_uri = dictionary_namespace_uri
|
||||
for related_ifc_entity in related_ifc_entities or [None]:
|
||||
response = cls.client.get_classes(
|
||||
dictionary_uri=dictionary_uri,
|
||||
use_nested_classes=False,
|
||||
search_text=keyword,
|
||||
related_ifc_entity=related_ifc_entity,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
)
|
||||
dictionary_name = response.get("name", "")
|
||||
dictionary_namespace_uri = response.get("uri", "")
|
||||
for _class in sorted(response.get("classes", []), key=lambda c: c["referenceCode"]):
|
||||
prop = props.classifications.add()
|
||||
prop.name = _class["name"]
|
||||
prop.reference_code = _class["referenceCode"]
|
||||
prop.uri = _class["uri"]
|
||||
prop.dictionary_name = dictionary_name
|
||||
prop.dictionary_namespace_uri = dictionary_namespace_uri
|
||||
|
||||
total_results = response.get("count", response.get("classesCount"))
|
||||
# For now, hard limit at 1000 results because any more and Blender
|
||||
|
||||
@@ -1171,47 +1171,6 @@ class Loader(bonsai.core.tool.Loader):
|
||||
|
||||
return mesh
|
||||
|
||||
@classmethod
|
||||
def setup_active_bsdd_classification(cls) -> None:
|
||||
ifc_file = tool.Ifc.get()
|
||||
schema = ifc_file.schema
|
||||
|
||||
# In IFC2X3 IfcClassification doesn't have an attribute for uri.
|
||||
if schema == "IFC2X3":
|
||||
classifications = [c for c in ifc_file.by_type("IfcClassification") if c.Name]
|
||||
if not classifications:
|
||||
return
|
||||
pattern = r"^https://identifier\.buildingsmart\.org/uri/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([0-9]+\.[0-9]+)"
|
||||
|
||||
# No inverse attribute in IFC2X3...
|
||||
for ref in ifc_file.by_type("IfcClassificationReference"):
|
||||
if (
|
||||
not (uri := ref.Location)
|
||||
or not uri.startswith("https://identifier.buildingsmart.org/uri/")
|
||||
or not (pattern_match := re.match(pattern, uri))
|
||||
or not (classification := ref.ReferencedSource)
|
||||
or classification not in classifications
|
||||
or not classification.is_a("IfcClassification")
|
||||
):
|
||||
continue
|
||||
tool.Bsdd.set_active_bsdd(classification.Name, pattern_match.group(0))
|
||||
return
|
||||
|
||||
attr_name = "Specification" if schema == "IFC4X3" else "Location"
|
||||
bsdd_classification, uri, name = None, None, None
|
||||
for c in ifc_file.by_type("IfcClassification"):
|
||||
if (
|
||||
(uri := getattr(c, attr_name))
|
||||
and uri.startswith("https://identifier.buildingsmart.org/uri/")
|
||||
and (name := c.Name)
|
||||
):
|
||||
bsdd_classification = c
|
||||
break
|
||||
if not bsdd_classification:
|
||||
return
|
||||
assert name and uri
|
||||
tool.Bsdd.set_active_bsdd(name, uri)
|
||||
|
||||
@classmethod
|
||||
def is_native_swept_disk_solid(
|
||||
cls, element: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
|
||||
|
||||
Reference in New Issue
Block a user