mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Merge branch 'v0.6.0' of github.com:IfcOpenShell/IfcOpenShell into v0.6.0
This commit is contained in:
@@ -471,39 +471,28 @@ class IfcParser:
|
|||||||
continue
|
continue
|
||||||
results[item_key] = {"ifc": None, "raw": raw, "material": material, "attributes": {"Name": item.name}}
|
results[item_key] = {"ifc": None, "raw": raw, "material": material, "attributes": {"Name": item.name}}
|
||||||
|
|
||||||
def add_automatic_qtos(self, ifc_class, obj):
|
def add_automatic_qtos(self, ifc_class: str, obj):
|
||||||
if not obj.data:
|
if not obj.data:
|
||||||
return
|
return
|
||||||
qto_names = self.get_applicable_qtos(ifc_class)
|
applicable_qtos = schema.ifc.psetqto.get_applicable(ifc_class, qto_only=True)
|
||||||
for name in qto_names:
|
for applicable_qto in applicable_qtos:
|
||||||
if name not in schema.ifc.psetqto.qtos:
|
|
||||||
continue
|
|
||||||
has_automatic_value = False
|
has_automatic_value = False
|
||||||
props = schema.ifc.psetqto.qtos[name]["HasPropertyTemplates"].keys()
|
|
||||||
guessed_values = {}
|
guessed_values = {}
|
||||||
for prop_name in props:
|
prop_names = [p.Name for p in applicable_qto.HasPropertyTemplates]
|
||||||
value = self.qto_calculator.guess_quantity(prop_name, props, obj)
|
for prop_name in prop_names:
|
||||||
|
value = self.qto_calculator.guess_quantity(prop_name, prop_names, obj)
|
||||||
if value:
|
if value:
|
||||||
guessed_values[prop_name] = value
|
guessed_values[prop_name] = value
|
||||||
has_automatic_value = True
|
has_automatic_value = True
|
||||||
if has_automatic_value:
|
if has_automatic_value:
|
||||||
qto = obj.BIMObjectProperties.qtos.add()
|
qto = obj.BIMObjectProperties.qtos.add()
|
||||||
qto.name = name
|
qto.name = applicable_qto.Name
|
||||||
for prop_name in props:
|
for prop_name in prop_names:
|
||||||
prop = qto.properties.add()
|
prop = qto.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
if prop_name in guessed_values:
|
if prop_name in guessed_values:
|
||||||
prop.string_value = str(guessed_values[prop_name])
|
prop.string_value = str(guessed_values[prop_name])
|
||||||
|
|
||||||
def get_applicable_qtos(self, ifc_class):
|
|
||||||
results = []
|
|
||||||
empty = ifcopenshell.file(schema=self.ifc_export_settings.schema)
|
|
||||||
element = empty.create_entity(ifc_class)
|
|
||||||
for ifc_class, qto_names in schema.ifc.applicable_qtos.items():
|
|
||||||
if element.is_a(ifc_class):
|
|
||||||
results.extend(qto_names)
|
|
||||||
return results
|
|
||||||
|
|
||||||
def get_product_relating_structure(self, product, obj):
|
def get_product_relating_structure(self, product, obj):
|
||||||
relating_structure = obj.BIMObjectProperties.relating_structure
|
relating_structure = obj.BIMObjectProperties.relating_structure
|
||||||
if relating_structure:
|
if relating_structure:
|
||||||
@@ -1701,13 +1690,15 @@ class IfcExporter:
|
|||||||
pset["ifc"] = self.file.create_entity("IfcMaterialProperties", **pset["attributes"])
|
pset["ifc"] = self.file.create_entity("IfcMaterialProperties", **pset["attributes"])
|
||||||
|
|
||||||
def create_qto_properties(self, qto):
|
def create_qto_properties(self, qto):
|
||||||
if qto["attributes"]["Name"] in schema.ifc.psetqto.qtos:
|
qto_template = schema.ifc.psetqto.get_by_name(qto["attributes"]["Name"])
|
||||||
return self.create_templated_qto_properties(qto)
|
if qto_template:
|
||||||
|
return self.create_templated_qto_properties(qto, qto_template)
|
||||||
return self.create_custom_qto_properties(qto)
|
return self.create_custom_qto_properties(qto)
|
||||||
|
|
||||||
def create_pset_properties(self, pset):
|
def create_pset_properties(self, pset):
|
||||||
if pset["attributes"]["Name"] in schema.ifc.psetqto.psets:
|
pset_template = schema.ifc.psetqto.get_by_name(pset["attributes"]["Name"])
|
||||||
return self.create_templated_pset_properties(pset)
|
if pset_template:
|
||||||
|
return self.create_templated_pset_properties(pset, pset_template)
|
||||||
return self.create_custom_pset_properties(pset)
|
return self.create_custom_pset_properties(pset)
|
||||||
|
|
||||||
def create_custom_pset_properties(self, pset):
|
def create_custom_pset_properties(self, pset):
|
||||||
@@ -1737,15 +1728,15 @@ class IfcExporter:
|
|||||||
)
|
)
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
def create_templated_pset_properties(self, pset):
|
def create_templated_pset_properties(self, pset, pset_template):
|
||||||
properties = []
|
properties = []
|
||||||
templates = schema.ifc.psetqto.psets[pset["attributes"]["Name"]]["HasPropertyTemplates"]
|
for prop in pset_template.HasPropertyTemplates:
|
||||||
for name, data in templates.items():
|
name = prop.Name
|
||||||
if name not in pset["raw"]:
|
if name not in pset["raw"]:
|
||||||
continue
|
continue
|
||||||
if data.TemplateType == "P_SINGLEVALUE" or data.TemplateType == "P_ENUMERATEDVALUE":
|
if prop.TemplateType == "P_SINGLEVALUE" or prop.TemplateType == "P_ENUMERATEDVALUE":
|
||||||
if data.PrimaryMeasureType:
|
if prop.PrimaryMeasureType:
|
||||||
value_type = data.PrimaryMeasureType
|
value_type = prop.PrimaryMeasureType
|
||||||
else:
|
else:
|
||||||
# The IFC spec is missing some, so we provide a fallback
|
# The IFC spec is missing some, so we provide a fallback
|
||||||
value_type = "IfcLabel"
|
value_type = "IfcLabel"
|
||||||
@@ -1755,7 +1746,8 @@ class IfcExporter:
|
|||||||
properties.append(
|
properties.append(
|
||||||
self.file.create_entity("IfcPropertySingleValue", **{"Name": name, "NominalValue": nominal_value})
|
self.file.create_entity("IfcPropertySingleValue", **{"Name": name, "NominalValue": nominal_value})
|
||||||
)
|
)
|
||||||
invalid_pset_keys = [k for k in pset["raw"].keys() if k not in templates.keys()]
|
templates_names = [prop.Name for prop in qto_template.HasPropertyTemplates]
|
||||||
|
invalid_pset_keys = [k for k in pset["raw"].keys() if k not in templates_names]
|
||||||
if invalid_pset_keys:
|
if invalid_pset_keys:
|
||||||
self.ifc_export_settings.logger.error(
|
self.ifc_export_settings.logger.error(
|
||||||
"One or more properties were invalid in the pset {}: {}".format(
|
"One or more properties were invalid in the pset {}: {}".format(
|
||||||
@@ -1764,20 +1756,21 @@ class IfcExporter:
|
|||||||
)
|
)
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
def create_templated_qto_properties(self, qto):
|
def create_templated_qto_properties(self, qto, qto_template):
|
||||||
properties = []
|
properties = []
|
||||||
templates = schema.ifc.psetqto.qtos[qto["attributes"]["Name"]]["HasPropertyTemplates"]
|
for prop in qto_template.HasPropertyTemplates:
|
||||||
for name, data in templates.items():
|
name = prop.Name
|
||||||
if name not in qto["raw"]:
|
if name not in qto["raw"]:
|
||||||
continue
|
continue
|
||||||
if data.TemplateType[0:2] == "Q_":
|
if prop.TemplateType[0:2] == "Q_":
|
||||||
value_basename = data.TemplateType[2:].title()
|
value_basename = prop.TemplateType[2:].title()
|
||||||
value_name = f"{value_basename}Value"
|
value_name = f"{value_basename}Value"
|
||||||
class_name = f"IfcQuantity{value_basename}"
|
class_name = f"IfcQuantity{value_basename}"
|
||||||
properties.append(
|
properties.append(
|
||||||
self.file.create_entity(class_name, **{"Name": name, value_name: float(qto["raw"][name])})
|
self.file.create_entity(class_name, **{"Name": name, value_name: float(qto["raw"][name])})
|
||||||
)
|
)
|
||||||
invalid_qto_keys = [k for k in qto["raw"].keys() if k not in templates.keys()]
|
templates_names = [prop.Name for prop in qto_template.HasPropertyTemplates]
|
||||||
|
invalid_qto_keys = [k for k in qto["raw"].keys() if k not in templates_names]
|
||||||
if invalid_qto_keys:
|
if invalid_qto_keys:
|
||||||
self.ifc_export_settings.logger.error(
|
self.ifc_export_settings.logger.error(
|
||||||
"One or more properties were invalid in the qto {}/{}: {}".format(
|
"One or more properties were invalid in the qto {}/{}: {}".format(
|
||||||
|
|||||||
@@ -1382,8 +1382,9 @@ class IfcImporter:
|
|||||||
def add_pset(self, pset, props):
|
def add_pset(self, pset, props):
|
||||||
new_pset = props.psets.add()
|
new_pset = props.psets.add()
|
||||||
new_pset.name = pset.Name
|
new_pset.name = pset.Name
|
||||||
if new_pset.name in schema.ifc.psetqto.psets:
|
pset_template = schema.ifc.psetqto.get_by_name(new_pset.name)
|
||||||
for prop_name in schema.ifc.psetqto.psets[new_pset.name]["HasPropertyTemplates"].keys():
|
if pset_template:
|
||||||
|
for prop_name in (p.Name for p in pset_template.HasPropertyTemplates):
|
||||||
prop = new_pset.properties.add()
|
prop = new_pset.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
try:
|
try:
|
||||||
@@ -1409,8 +1410,9 @@ class IfcImporter:
|
|||||||
def add_qto(self, qto, obj):
|
def add_qto(self, qto, obj):
|
||||||
new_qto = obj.BIMObjectProperties.qtos.add()
|
new_qto = obj.BIMObjectProperties.qtos.add()
|
||||||
new_qto.name = str(qto.Name)
|
new_qto.name = str(qto.Name)
|
||||||
if new_qto.name in schema.ifc.psetqto.qtos:
|
qto_template = schema.ifc.psetqto.get_by_name(new_qto.name)
|
||||||
for prop_name in schema.ifc.psetqto.qtos[new_qto.name]["HasPropertyTemplates"].keys():
|
if qto_template:
|
||||||
|
for prop_name in (p.Name for p in qto_template.HasPropertyTemplates):
|
||||||
prop = new_qto.properties.add()
|
prop = new_qto.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
for prop in qto.Quantities:
|
for prop in qto.Quantities:
|
||||||
|
|||||||
@@ -492,56 +492,46 @@ class AddQto(bpy.types.Operator):
|
|||||||
bl_label = "Add Qto"
|
bl_label = "Add Qto"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.applicable_qtos_cache = {}
|
|
||||||
name = bpy.context.active_object.BIMObjectProperties.qto_name
|
name = bpy.context.active_object.BIMObjectProperties.qto_name
|
||||||
if name not in schema.ifc.psetqto.qtos:
|
qto_template = schema.ifc.psetqto.get_by_name(name)
|
||||||
|
if not qto_template:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
if "/" not in obj.name or obj.BIMObjectProperties.qtos.find(name) != -1:
|
if "/" not in obj.name or obj.BIMObjectProperties.qtos.find(name) != -1:
|
||||||
continue
|
continue
|
||||||
applicable_qtos = self.get_applicable_qtos(obj.name.split("/")[0])
|
applicable_qtos = schema.ifc.psetqto.get_applicable_names(obj.name.split("/")[0], qto_only=True)
|
||||||
if name not in applicable_qtos:
|
if name not in applicable_qtos:
|
||||||
continue
|
continue
|
||||||
qto = obj.BIMObjectProperties.qtos.add()
|
qto = obj.BIMObjectProperties.qtos.add()
|
||||||
qto.name = name
|
qto.name = name
|
||||||
for prop_name in schema.ifc.psetqto.qtos[name]["HasPropertyTemplates"].keys():
|
for prop_name in (p.Name for p in qto_template.HasPropertyTemplates):
|
||||||
prop = qto.properties.add()
|
prop = qto.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def get_applicable_qtos(self, ifc_class):
|
|
||||||
if ifc_class not in self.applicable_qtos_cache:
|
|
||||||
self.applicable_qtos_cache[ifc_class] = schema.ifc.psetqto.get_applicable_names(ifc_class, qto_only=True)
|
|
||||||
return self.applicable_qtos_cache[ifc_class]
|
|
||||||
|
|
||||||
|
|
||||||
class AddPset(bpy.types.Operator):
|
class AddPset(bpy.types.Operator):
|
||||||
bl_idname = "bim.add_pset"
|
bl_idname = "bim.add_pset"
|
||||||
bl_label = "Add Pset"
|
bl_label = "Add Pset"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.applicable_psets_cache = {}
|
|
||||||
name = bpy.context.active_object.BIMObjectProperties.pset_name
|
name = bpy.context.active_object.BIMObjectProperties.pset_name
|
||||||
if name not in schema.ifc.psetqto.psets:
|
pset_template = schema.ifc.psetqto.get_by_name(name)
|
||||||
|
if not pset_template:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
if "/" not in obj.name or obj.BIMObjectProperties.psets.find(name) != -1:
|
if "/" not in obj.name or obj.BIMObjectProperties.psets.find(name) != -1:
|
||||||
continue
|
continue
|
||||||
applicable_psets = self.get_applicable_psets(obj.name.split("/")[0])
|
applicable_psets = schema.ifc.psetqto.get_applicable_names(obj.name.split("/")[0], pset_only=True)
|
||||||
if name not in applicable_psets:
|
if name not in applicable_psets:
|
||||||
continue
|
continue
|
||||||
pset = obj.BIMObjectProperties.psets.add()
|
pset = obj.BIMObjectProperties.psets.add()
|
||||||
pset.name = name
|
pset.name = name
|
||||||
for prop_name in schema.ifc.psetqto.psets[name]["HasPropertyTemplates"].keys():
|
for prop_name in (p.Name for p in pset_template.HasPropertyTemplates):
|
||||||
prop = pset.properties.add()
|
prop = pset.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def get_applicable_psets(self, ifc_class):
|
|
||||||
if ifc_class not in self.applicable_psets_cache:
|
|
||||||
self.applicable_psets_cache[ifc_class] = schema.ifc.psetqto.get_applicable_names(ifc_class, pset_only=True)
|
|
||||||
return self.applicable_psets_cache[ifc_class]
|
|
||||||
|
|
||||||
|
|
||||||
class RemovePset(bpy.types.Operator):
|
class RemovePset(bpy.types.Operator):
|
||||||
bl_idname = "bim.remove_pset"
|
bl_idname = "bim.remove_pset"
|
||||||
@@ -582,13 +572,14 @@ class AddMaterialPset(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
material = bpy.context.active_object.active_material
|
material = bpy.context.active_object.active_material
|
||||||
name = material.BIMMaterialProperties.pset_name
|
name = material.BIMMaterialProperties.pset_name
|
||||||
if name not in schema.ifc.psetqto.psets:
|
pset_template = schema.ifc.psetqto.get_by_name(name)
|
||||||
|
if not pset_template:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
if material.BIMMaterialProperties.psets.find(name) != -1:
|
if material.BIMMaterialProperties.psets.find(name) != -1:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
pset = material.BIMMaterialProperties.psets.add()
|
pset = material.BIMMaterialProperties.psets.add()
|
||||||
pset.name = name
|
pset.name = name
|
||||||
for prop_name in schema.ifc.psetqto.psets[name]["HasPropertyTemplates"].keys():
|
for prop_name in (p.Name for p in pset_template.HasPropertyTemplates):
|
||||||
prop = pset.properties.add()
|
prop = pset.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -2371,18 +2362,20 @@ class CopyPropertyToSelection(bpy.types.Operator):
|
|||||||
prop_value: bpy.props.StringProperty()
|
prop_value: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.applicable_psets_cache = {}
|
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
if "/" not in obj.name:
|
if "/" not in obj.name:
|
||||||
continue
|
continue
|
||||||
pset = obj.BIMObjectProperties.psets.get(self.pset_name)
|
pset = obj.BIMObjectProperties.psets.get(self.pset_name)
|
||||||
if not pset:
|
if not pset:
|
||||||
applicable_psets = self.get_applicable_psets(obj.name.split("/")[0])
|
applicable_psets = schema.ifc.psetqto.get_applicable(obj.name.split("/")[0], pset_only=True)
|
||||||
if self.pset_name not in applicable_psets:
|
for pset_template in applicable_psets:
|
||||||
|
if pset_template.Name == self.pset_name:
|
||||||
|
break
|
||||||
|
else:
|
||||||
continue
|
continue
|
||||||
pset = obj.BIMObjectProperties.psets.add()
|
pset = obj.BIMObjectProperties.psets.add()
|
||||||
pset.name = self.pset_name
|
pset.name = self.pset_name
|
||||||
for template_prop_name in schema.ifc.psetqto.psets[self.pset_name]["HasPropertyTemplates"].keys():
|
for template_prop_name in (p.Name for p in pset_template.HasPropertyTemplates):
|
||||||
prop = pset.properties.add()
|
prop = pset.properties.add()
|
||||||
prop.name = template_prop_name
|
prop.name = template_prop_name
|
||||||
prop = pset.properties.get(self.prop_name)
|
prop = pset.properties.get(self.prop_name)
|
||||||
@@ -2390,11 +2383,6 @@ class CopyPropertyToSelection(bpy.types.Operator):
|
|||||||
prop.string_value = self.prop_value
|
prop.string_value = self.prop_value
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def get_applicable_psets(self, ifc_class):
|
|
||||||
if ifc_class not in self.applicable_psets_cache:
|
|
||||||
self.applicable_psets_cache[ifc_class] = schema.ifc.psetqto.get_applicable_names(ifc_class, pset_only=True)
|
|
||||||
return self.applicable_psets_cache[ifc_class]
|
|
||||||
|
|
||||||
|
|
||||||
class CopyAttributeToSelection(bpy.types.Operator):
|
class CopyAttributeToSelection(bpy.types.Operator):
|
||||||
bl_idname = "bim.copy_attribute_to_selection"
|
bl_idname = "bim.copy_attribute_to_selection"
|
||||||
@@ -3193,11 +3181,12 @@ class GuessQuantity(bpy.types.Operator):
|
|||||||
prop.string_value = str(round(quantity, 3))
|
prop.string_value = str(round(quantity, 3))
|
||||||
|
|
||||||
def add_qto(self, obj, name):
|
def add_qto(self, obj, name):
|
||||||
if name not in schema.ifc.psetqto.qtos:
|
qto_template = schema.ifc.psetqto.get_by_name(name)
|
||||||
|
if not qto_template:
|
||||||
return
|
return
|
||||||
qto = obj.BIMObjectProperties.qtos.add()
|
qto = obj.BIMObjectProperties.qtos.add()
|
||||||
qto.name = name
|
qto.name = name
|
||||||
for prop_name in schema.ifc.psetqto.qtos[name]["HasPropertyTemplates"].keys():
|
for prop_name in (p.Name for p in qto_template.HasPropertyTemplates):
|
||||||
prop = qto.properties.add()
|
prop = qto.properties.add()
|
||||||
prop.name = prop_name
|
prop.name = prop_name
|
||||||
return qto
|
return qto
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class IfcSchema:
|
|||||||
|
|
||||||
self.property_files = []
|
self.property_files = []
|
||||||
property_paths = self.data_dir.joinpath("pset").glob("*.ifc")
|
property_paths = self.data_dir.joinpath("pset").glob("*.ifc")
|
||||||
self.psetqto = ifcopenshell.util.pset.PsetQto("IFC4", use_cache=True)
|
self.psetqto = ifcopenshell.util.pset.PsetQto("IFC4")
|
||||||
for path in property_paths:
|
for path in property_paths:
|
||||||
self.psetqto.templates.append(ifcopenshell.open(path))
|
self.psetqto.templates.append(ifcopenshell.open(path))
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
from typing import List, Generator
|
from functools import lru_cache
|
||||||
|
from typing import List, Generator, Optional
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from ifcopenshell.entity_instance import entity_instance
|
from ifcopenshell.entity_instance import entity_instance
|
||||||
@@ -11,34 +12,15 @@ class PsetQto:
|
|||||||
"IFC4": "Pset_IFC4_ADD2.ifc",
|
"IFC4": "Pset_IFC4_ADD2.ifc",
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, schema: str, templates=None, use_cache=False) -> None:
|
def __init__(self, schema: str, templates=None) -> None:
|
||||||
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(schema)
|
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(schema)
|
||||||
if not templates:
|
if not templates:
|
||||||
folder_path = pathlib.Path(__file__).parent.absolute()
|
folder_path = pathlib.Path(__file__).parent.absolute()
|
||||||
path = folder_path.joinpath("schema", self.templates_path[schema])
|
path = folder_path.joinpath("schema", self.templates_path[schema])
|
||||||
templates = [ifcopenshell.open(path)]
|
templates = [ifcopenshell.open(path)]
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
# Caching reduce request time. For 100 get_applicable_names requests ~3.6 s -> ~2 s
|
|
||||||
self.use_cache = use_cache
|
|
||||||
self.psets = {}
|
|
||||||
self.qtos = {}
|
|
||||||
self.applicable_psets = {}
|
|
||||||
self.applicable_qtos = {}
|
|
||||||
if use_cache:
|
|
||||||
for template in templates:
|
|
||||||
self.cache_template(template)
|
|
||||||
|
|
||||||
def cache_template(self, template):
|
|
||||||
for prop_set in template.by_type("IfcPropertySetTemplate"):
|
|
||||||
if prop_set.Name[0:4] == "Qto_":
|
|
||||||
self.qtos[prop_set.Name] = {"HasPropertyTemplates": {p.Name: p for p in prop_set.HasPropertyTemplates}}
|
|
||||||
entity = prop_set.ApplicableEntity if prop_set.ApplicableEntity else "IfcRoot"
|
|
||||||
self.applicable_qtos.setdefault(entity, []).append(prop_set.Name)
|
|
||||||
else:
|
|
||||||
self.psets[prop_set.Name] = {"HasPropertyTemplates": {p.Name: p for p in prop_set.HasPropertyTemplates}}
|
|
||||||
entity = prop_set.ApplicableEntity if prop_set.ApplicableEntity else "IfcRoot"
|
|
||||||
self.applicable_psets.setdefault(entity, []).append(prop_set.Name)
|
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
def get_applicable(
|
def get_applicable(
|
||||||
self, ifc_class="", predefined_type="", pset_only=False, qto_only=False
|
self, ifc_class="", predefined_type="", pset_only=False, qto_only=False
|
||||||
) -> Generator[entity_instance, entity_instance, None]:
|
) -> Generator[entity_instance, entity_instance, None]:
|
||||||
@@ -58,22 +40,9 @@ class PsetQto:
|
|||||||
|
|
||||||
def get_applicable_names(self, ifc_class: str, predefined_type="", pset_only=False, qto_only=False) -> List[str]:
|
def get_applicable_names(self, ifc_class: str, predefined_type="", pset_only=False, qto_only=False) -> List[str]:
|
||||||
"""Return names instead of objects for other use eg. enum"""
|
"""Return names instead of objects for other use eg. enum"""
|
||||||
if self.use_cache:
|
|
||||||
results = []
|
|
||||||
entity = self.schema.declaration_by_name(ifc_class)
|
|
||||||
if not qto_only:
|
|
||||||
for applicable_class, pset_names in self.applicable_psets.items():
|
|
||||||
if self.is_applicable(entity, applicable_class):
|
|
||||||
results.extend(pset_names)
|
|
||||||
if not pset_only:
|
|
||||||
for applicable_class, pset_names in self.applicable_qtos.items():
|
|
||||||
if self.is_applicable(entity, applicable_class):
|
|
||||||
results.extend(pset_names)
|
|
||||||
return results
|
|
||||||
|
|
||||||
return [prop_set.Name for prop_set in self.get_applicable(ifc_class, predefined_type, pset_only, qto_only)]
|
return [prop_set.Name for prop_set in self.get_applicable(ifc_class, predefined_type, pset_only, qto_only)]
|
||||||
|
|
||||||
def is_applicable(self, entity: entity_instance, applicables: str, predefined_type=""):
|
def is_applicable(self, entity: entity_instance, applicables: str, predefined_type="") -> bool:
|
||||||
"""applicables can have multiple possible patterns :
|
"""applicables can have multiple possible patterns :
|
||||||
IfcBoilerType (IfcClass)
|
IfcBoilerType (IfcClass)
|
||||||
IfcBoilerType/STEAM (IfcClass/PREDEFINEDTYPE)
|
IfcBoilerType/STEAM (IfcClass/PREDEFINEDTYPE)
|
||||||
@@ -95,3 +64,14 @@ class PsetQto:
|
|||||||
if entity.supertype():
|
if entity.supertype():
|
||||||
return self.is_applicable(entity.supertype(), applicable_class)
|
return self.is_applicable(entity.supertype(), applicable_class)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def get_by_name(self, name: str) -> Optional[entity_instance]:
|
||||||
|
for template in self.templates:
|
||||||
|
for prop_set in template.by_type("IfcPropertySetTemplate"):
|
||||||
|
if prop_set.Name == name:
|
||||||
|
return prop_set
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_templated(self, name: str) -> bool:
|
||||||
|
return bool(self.get_by_name(name))
|
||||||
|
|||||||
Reference in New Issue
Block a user