add_prop_template - consider pset template type for prop/measure types

This commit is contained in:
Andrej730
2024-11-15 18:09:19 +05:00
parent dad89cfabd
commit 934869af98
2 changed files with 53 additions and 24 deletions
@@ -18,6 +18,7 @@
import ifcopenshell import ifcopenshell
import ifcopenshell.guid import ifcopenshell.guid
import ifcopenshell.util.pset
from typing import Optional from typing import Optional
@@ -26,8 +27,8 @@ def add_prop_template(
pset_template: ifcopenshell.entity_instance, pset_template: ifcopenshell.entity_instance,
name: str = "NewProperty", name: str = "NewProperty",
description: Optional[str] = None, description: Optional[str] = None,
template_type: str = "P_SINGLEVALUE", template_type: Optional[str] = None,
primary_measure_type: str = "IfcLabel", primary_measure_type: Optional[str] = None,
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
"""Adds new property templates to a property set template """Adds new property templates to a property set template
@@ -57,16 +58,14 @@ def add_prop_template(
:param pset_template: The property set template to add the property :param pset_template: The property set template to add the property
template to. template to.
:type pset_template: ifcopenshell.entity_instance
:param name: The name of the property :param name: The name of the property
:type name: str,optional
:param description: A few words describing what the property stores. :param description: A few words describing what the property stores.
:type description: str,optional :param template_type: The type of the property. If not provided,
:param primary_measure_type: The data type of the property. Consult the P_SINGLEVALUE or Q_LENGTH will be assumed (depending on the pset type).
IFC documentation for the full list of data types. :param primary_measure_type: The data type of the property,
:param primary_measure_type: str,optional doesn't used for quantity set templates.
Consult the IFC documentation for the full list of data types.
:return: The newly created IfcSimplePropertyTemplate. :return: The newly created IfcSimplePropertyTemplate.
:rtype: ifcopenshell.entity_instance
Example: Example:
@@ -85,27 +84,31 @@ def add_prop_template(
name="ChemicalType", description="The class of chemical spillage.", name="ChemicalType", description="The class of chemical spillage.",
primary_measure_type="IfcLabel") primary_measure_type="IfcLabel")
""" """
settings = { assumed_pset_type = ifcopenshell.util.pset.get_pset_template_type(pset_template) or "PSET"
"pset_template": pset_template,
"name": name, if template_type is None:
"description": description, template_type = "Q_LENGTH" if assumed_pset_type == "QTO" else "P_SINGLEVALUE"
"template_type": template_type,
"primary_measure_type": primary_measure_type, if assumed_pset_type == "PSET":
} if primary_measure_type is None:
primary_measure_type = "IfcLabel"
else:
# QTO props doesn't need a primary measure type.
primary_measure_type = None
prop_template = file.create_entity( prop_template = file.create_entity(
"IfcSimplePropertyTemplate", "IfcSimplePropertyTemplate",
**{ **{
"GlobalId": ifcopenshell.guid.new(), "GlobalId": ifcopenshell.guid.new(),
"Name": settings["name"], "Name": name,
"Description": settings["description"], "Description": description,
"PrimaryMeasureType": settings["primary_measure_type"], "PrimaryMeasureType": primary_measure_type,
"TemplateType": settings["template_type"], "TemplateType": template_type,
"AccessState": "READWRITE", "AccessState": "READWRITE",
"Enumerators": None, "Enumerators": None,
} },
) )
has_property_templates = list(settings["pset_template"].HasPropertyTemplates or []) has_property_templates = list(pset_template.HasPropertyTemplates or [])
has_property_templates.append(prop_template) has_property_templates.append(prop_template)
settings["pset_template"].HasPropertyTemplates = has_property_templates pset_template.HasPropertyTemplates = has_property_templates
return prop_template return prop_template
@@ -23,7 +23,7 @@ import ifcopenshell.util.schema
import ifcopenshell.util.type import ifcopenshell.util.type
from ifcopenshell.entity_instance import entity_instance from ifcopenshell.entity_instance import entity_instance
from functools import lru_cache from functools import lru_cache
from typing import List, Optional from typing import List, Optional, Literal
templates: dict[str, "PsetQto"] = {} templates: dict[str, "PsetQto"] = {}
@@ -147,3 +147,29 @@ class PsetQto:
def is_templated(self, name: str) -> bool: def is_templated(self, name: str) -> bool:
return bool(self.get_by_name(name)) return bool(self.get_by_name(name))
def get_pset_template_type(pset_template: entity_instance) -> Literal["PSET", "QTO", None]:
"""Get the type of the pset template.
If type is mixed or not defined, return None."""
# Try to identify whether it's pset or qto from the template type.
template_type = pset_template.TemplateType
if template_type:
if template_type.startswith("PSET_"):
return "PSET"
elif template_type.startswith("QTO_"):
return "QTO"
# Can also be 'NOTDEFINED'.
pset_types = set()
for prop in pset_template.HasPropertyTemplates:
prop_template_type = prop.TemplateType
if prop_template_type:
if prop_template_type.startswith("P_"):
pset_types.add("PSET")
else: # All other values are Q_.
pset_types.add("QTO")
pset_type = next(iter(pset_types)) if len(pset_types) == 1 else None
return pset_type