mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
typing
This commit is contained in:
@@ -24,6 +24,7 @@ import ifcopenshell.util.attribute
|
|||||||
import ifcopenshell.util.doc
|
import ifcopenshell.util.doc
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from bonsai.bim.ifc import IfcStore
|
from bonsai.bim.ifc import IfcStore
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
@@ -49,7 +50,7 @@ class PsetTemplatesData:
|
|||||||
cls.data["prop_templates"] = cls.prop_templates()
|
cls.data["prop_templates"] = cls.prop_templates()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def primary_measure_type(cls):
|
def primary_measure_type(cls) -> list[tuple[str, str, str]]:
|
||||||
ifc_file = IfcStore.pset_template_file
|
ifc_file = IfcStore.pset_template_file
|
||||||
if not ifc_file:
|
if not ifc_file:
|
||||||
return []
|
return []
|
||||||
@@ -61,7 +62,7 @@ class PsetTemplatesData:
|
|||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def property_template_type(cls):
|
def property_template_type(cls) -> list[tuple[str, str, str]]:
|
||||||
ifc_file = IfcStore.pset_template_file
|
ifc_file = IfcStore.pset_template_file
|
||||||
if not ifc_file:
|
if not ifc_file:
|
||||||
return []
|
return []
|
||||||
@@ -96,7 +97,7 @@ class PsetTemplatesData:
|
|||||||
return [(str(t.id()), t.Name, "") for t in IfcStore.pset_template_file.by_type("IfcPropertySetTemplate")]
|
return [(str(t.id()), t.Name, "") for t in IfcStore.pset_template_file.by_type("IfcPropertySetTemplate")]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def pset_template(cls):
|
def pset_template(cls) -> dict[str, Any]:
|
||||||
props = bpy.context.scene.BIMPsetTemplateProperties
|
props = bpy.context.scene.BIMPsetTemplateProperties
|
||||||
template_id = props.pset_templates
|
template_id = props.pset_templates
|
||||||
if not template_id:
|
if not template_id:
|
||||||
@@ -109,7 +110,7 @@ class PsetTemplatesData:
|
|||||||
return info
|
return info
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def prop_templates(cls):
|
def prop_templates(cls) -> list[dict[str, Any]]:
|
||||||
props = bpy.context.scene.BIMPsetTemplateProperties
|
props = bpy.context.scene.BIMPsetTemplateProperties
|
||||||
template_id = props.pset_templates
|
template_id = props.pset_templates
|
||||||
if not template_id:
|
if not template_id:
|
||||||
|
|||||||
+16
-15
@@ -22,7 +22,19 @@ import ifcopenshell.api
|
|||||||
import ifcopenshell.util.date
|
import ifcopenshell.util.date
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Any, Optional, Union
|
from typing import Any, Optional, Union, Literal, get_args
|
||||||
|
|
||||||
|
|
||||||
|
SUPPORTED_COLUMN = Literal[
|
||||||
|
"HIERARCHY",
|
||||||
|
"TYPE", # CREW, LABOR, EQUIPMENT, SUBCONTRACTOR, MATERIAL, PRODUCT.
|
||||||
|
"ACTIVITY/RESOURCE NAME",
|
||||||
|
"DESCRIPTION",
|
||||||
|
"COST",
|
||||||
|
"QUANTITY NAME",
|
||||||
|
"LABOR OUTPUT",
|
||||||
|
"EQUIPMENT OUTPUT",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Csv2Ifc:
|
class Csv2Ifc:
|
||||||
@@ -32,7 +44,7 @@ class Csv2Ifc:
|
|||||||
Notes about format:
|
Notes about format:
|
||||||
- empty rows are skipped.
|
- empty rows are skipped.
|
||||||
- 'HIERARCHY' must be the first column.
|
- 'HIERARCHY' must be the first column.
|
||||||
- See SUPPORTED_COLUMNS below for the list of supported columns.
|
- See SUPPORTED_COLUMN above for the list of supported columns.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -42,17 +54,6 @@ class Csv2Ifc:
|
|||||||
csv2ifc.execute()
|
csv2ifc.execute()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUPPORTED_COLUMNS = (
|
|
||||||
"HIERARCHY",
|
|
||||||
"TYPE", # CREW, LABOR, EQUIPMENT, SUBCONTRACTOR, MATERIAL, PRODUCT.
|
|
||||||
"ACTIVITY/RESOURCE NAME",
|
|
||||||
"DESCRIPTION",
|
|
||||||
"COST",
|
|
||||||
"QUANTITY NAME",
|
|
||||||
"LABOR OUTPUT",
|
|
||||||
"EQUIPMENT OUTPUT",
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, csv: str, ifc_file: Optional[ifcopenshell.file] = None):
|
def __init__(self, csv: str, ifc_file: Optional[ifcopenshell.file] = None):
|
||||||
"""
|
"""
|
||||||
:param csv: CSV filepath to load resources from.
|
:param csv: CSV filepath to load resources from.
|
||||||
@@ -78,7 +79,7 @@ class Csv2Ifc:
|
|||||||
|
|
||||||
def parse_csv(self) -> None:
|
def parse_csv(self) -> None:
|
||||||
self.parents = {}
|
self.parents = {}
|
||||||
self.headers: dict[str, int] = {}
|
self.headers: dict[SUPPORTED_COLUMN, int] = {}
|
||||||
with open(self.csv, "r") as csv_file:
|
with open(self.csv, "r") as csv_file:
|
||||||
reader = csv.reader(csv_file)
|
reader = csv.reader(csv_file)
|
||||||
for row in reader:
|
for row in reader:
|
||||||
@@ -86,7 +87,7 @@ class Csv2Ifc:
|
|||||||
if not row[0]:
|
if not row[0]:
|
||||||
continue
|
continue
|
||||||
if row[0] == "HIERARCHY":
|
if row[0] == "HIERARCHY":
|
||||||
missing_columns = set(self.SUPPORTED_COLUMNS) - set(row)
|
missing_columns = set(get_args(SUPPORTED_COLUMN)) - set(row)
|
||||||
if missing_columns:
|
if missing_columns:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Header is missing some of the required columns: {', '.join(missing_columns)}."
|
f"Header is missing some of the required columns: {', '.join(missing_columns)}."
|
||||||
|
|||||||
@@ -17,15 +17,16 @@
|
|||||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
import ifcopenshell.api.pset
|
||||||
import ifcopenshell.util.pset
|
import ifcopenshell.util.pset
|
||||||
from typing import Optional, Any
|
from typing import Optional, Any, Union
|
||||||
|
|
||||||
|
|
||||||
def edit_qto(
|
def edit_qto(
|
||||||
file: ifcopenshell.file,
|
file: ifcopenshell.file,
|
||||||
qto: ifcopenshell.entity_instance,
|
qto: ifcopenshell.entity_instance,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
properties: Optional[dict[str, Any]] = None,
|
properties: Optional[dict[str, Union[ifcopenshell.entity_instance, float, int]]] = None,
|
||||||
pset_template: Optional[ifcopenshell.entity_instance] = None,
|
pset_template: Optional[ifcopenshell.entity_instance] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Edits a quantity set and its quantities
|
"""Edits a quantity set and its quantities
|
||||||
@@ -40,10 +41,8 @@ def edit_qto(
|
|||||||
It is not allowed to have None quantities in IFC.
|
It is not allowed to have None quantities in IFC.
|
||||||
|
|
||||||
:param qto: The IfcElementQuantity to edit.
|
:param qto: The IfcElementQuantity to edit.
|
||||||
:type qto: ifcopenshell.entity_instance
|
|
||||||
:param name: A new name for the quantity set. If no name is specified,
|
:param name: A new name for the quantity set. If no name is specified,
|
||||||
the quantity set name is not changed.
|
the quantity set name is not changed.
|
||||||
:type name: str, optional
|
|
||||||
:param properties: A dictionary of properties. The keys must be a string
|
:param properties: A dictionary of properties. The keys must be a string
|
||||||
of the name of the quantity. The data type of the value will be
|
of the name of the quantity. The data type of the value will be
|
||||||
determined by the quantity set template. If no quantity set
|
determined by the quantity set template. If no quantity set
|
||||||
@@ -53,13 +52,11 @@ def edit_qto(
|
|||||||
become IfcBoolean, and integers will become IfcInteger. If more
|
become IfcBoolean, and integers will become IfcInteger. If more
|
||||||
control is desired, you may explicitly specify IFC data objects
|
control is desired, you may explicitly specify IFC data objects
|
||||||
directly.
|
directly.
|
||||||
:type properties: dict
|
|
||||||
:param pset_template: If a quantity set template is provided, this will
|
:param pset_template: If a quantity set template is provided, this will
|
||||||
be used to determine data types. If no user-defined template is
|
be used to determine data types. If no user-defined template is
|
||||||
provided, the built-in buildingSMART templates will be loaded.
|
provided, the built-in buildingSMART templates will be loaded.
|
||||||
:type pset_template: ifcopenshell.entity_instance, optional
|
:type pset_template: ifcopenshell.entity_instance, optional
|
||||||
:return: None
|
:return: None
|
||||||
:rtype: None
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -121,6 +118,9 @@ def edit_qto(
|
|||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
|
file: ifcopenshell.file
|
||||||
|
settings: dict[str, Any]
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.qto_idx = 5
|
self.qto_idx = 5
|
||||||
if self.settings["qto"].is_a("IfcPhysicalComplexQuantity"):
|
if self.settings["qto"].is_a("IfcPhysicalComplexQuantity"):
|
||||||
@@ -132,22 +132,22 @@ class Usecase:
|
|||||||
new_properties = self.add_new_properties()
|
new_properties = self.add_new_properties()
|
||||||
self.extend_qto_with_new_properties(new_properties)
|
self.extend_qto_with_new_properties(new_properties)
|
||||||
|
|
||||||
def update_qto_name(self):
|
def update_qto_name(self) -> None:
|
||||||
if self.settings["name"]:
|
if self.settings["name"]:
|
||||||
self.settings["qto"].Name = self.settings["name"]
|
self.settings["qto"].Name = self.settings["name"]
|
||||||
|
|
||||||
def load_qto_template(self):
|
def load_qto_template(self) -> None:
|
||||||
if self.settings["pset_template"]:
|
if self.settings["pset_template"]:
|
||||||
self.pset_template = self.settings["pset_template"]
|
self.pset_template = self.settings["pset_template"]
|
||||||
else:
|
else:
|
||||||
self.psetqto = ifcopenshell.util.pset.get_template(self.file.schema_identifier)
|
self.psetqto = ifcopenshell.util.pset.get_template(self.file.schema_identifier)
|
||||||
self.qto_template = self.psetqto.get_by_name(self.settings["qto"].Name)
|
self.qto_template = self.psetqto.get_by_name(self.settings["qto"].Name)
|
||||||
|
|
||||||
def update_existing_properties(self):
|
def update_existing_properties(self) -> None:
|
||||||
for prop in self.settings["qto"][self.qto_idx] or []:
|
for prop in self.settings["qto"][self.qto_idx] or []:
|
||||||
self.update_existing_property(prop)
|
self.update_existing_property(prop)
|
||||||
|
|
||||||
def update_existing_property(self, prop):
|
def update_existing_property(self, prop: ifcopenshell.entity_instance) -> None:
|
||||||
if prop.Name not in self.settings["properties"]:
|
if prop.Name not in self.settings["properties"]:
|
||||||
return
|
return
|
||||||
value = self.settings["properties"][prop.Name]
|
value = self.settings["properties"][prop.Name]
|
||||||
@@ -162,7 +162,7 @@ class Usecase:
|
|||||||
prop[3] = float(value)
|
prop[3] = float(value)
|
||||||
del self.settings["properties"][name]
|
del self.settings["properties"][name]
|
||||||
|
|
||||||
def add_new_properties(self):
|
def add_new_properties(self) -> list[ifcopenshell.entity_instance]:
|
||||||
properties = []
|
properties = []
|
||||||
for name, value in self.settings["properties"].items():
|
for name, value in self.settings["properties"].items():
|
||||||
if value is None:
|
if value is None:
|
||||||
@@ -184,12 +184,12 @@ class Usecase:
|
|||||||
)
|
)
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
def extend_qto_with_new_properties(self, new_properties):
|
def extend_qto_with_new_properties(self, new_properties: list[ifcopenshell.entity_instance]) -> None:
|
||||||
props = list(self.settings["qto"][self.qto_idx]) if self.settings["qto"][self.qto_idx] else []
|
props = list(self.settings["qto"][self.qto_idx]) if self.settings["qto"][self.qto_idx] else []
|
||||||
props.extend(new_properties)
|
props.extend(new_properties)
|
||||||
self.settings["qto"][self.qto_idx] = props
|
self.settings["qto"][self.qto_idx] = props
|
||||||
|
|
||||||
def get_canonical_property_type(self, name, value):
|
def get_canonical_property_type(self, name: str, value: Union[ifcopenshell.entity_instance, float, int]) -> str:
|
||||||
if isinstance(value, ifcopenshell.entity_instance):
|
if isinstance(value, ifcopenshell.entity_instance):
|
||||||
result = value.is_a().replace("Ifc", "").replace("Measure", "")
|
result = value.is_a().replace("Ifc", "").replace("Measure", "")
|
||||||
# Sigh, IFC inconsistencies
|
# Sigh, IFC inconsistencies
|
||||||
@@ -205,7 +205,8 @@ class Usecase:
|
|||||||
return prop_template.TemplateType[2:].lower().capitalize()
|
return prop_template.TemplateType[2:].lower().capitalize()
|
||||||
return "Length"
|
return "Length"
|
||||||
|
|
||||||
def get_primary_measure_type(self, name, previous_value=None):
|
# TODO: unused code.
|
||||||
|
def get_primary_measure_type(self, name: str, previous_value: Optional[Any] = None) -> str:
|
||||||
if not self.qto_template:
|
if not self.qto_template:
|
||||||
return previous_value.is_a() if previous_value else "IfcLabel"
|
return previous_value.is_a() if previous_value else "IfcLabel"
|
||||||
for prop_template in self.qto_template.HasPropertyTemplates:
|
for prop_template in self.qto_template.HasPropertyTemplates:
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ def get_quantity(
|
|||||||
if quantity[0] != name:
|
if quantity[0] != name:
|
||||||
continue
|
continue
|
||||||
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
||||||
# 3 IfcPhysicalSimpleQuantity.Unit
|
# 3 IfcPhysicalSimpleQuantity.XXXValue
|
||||||
result = quantity[3]
|
result = quantity[3]
|
||||||
elif quantity.is_a("IfcPhysicalComplexQuantity"):
|
elif quantity.is_a("IfcPhysicalComplexQuantity"):
|
||||||
data = {k: v for k, v in quantity.get_info().items() if v is not None and k != "Name"}
|
data = {k: v for k, v in quantity.get_info().items() if v is not None and k != "Name"}
|
||||||
@@ -299,7 +299,7 @@ def get_quantities(
|
|||||||
# 0 IfcPhysicalQuantity.Name
|
# 0 IfcPhysicalQuantity.Name
|
||||||
quantity_name = quantity[0]
|
quantity_name = quantity[0]
|
||||||
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
||||||
# 3 IfcPhysicalSimpleQuantity.Unit
|
# 3 IfcPhysicalSimpleQuantity.XXXValue
|
||||||
results[quantity_name] = quantity[3]
|
results[quantity_name] = quantity[3]
|
||||||
if verbose:
|
if verbose:
|
||||||
results[quantity_name] = {
|
results[quantity_name] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user