mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Purge all data classes from API.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
if product.Decomposes and product.Decomposes[0].is_a("IfcRelAggregates"):
|
||||
obj = product.Decomposes[0].RelatingObject
|
||||
cls.products[product_id] = {"type": obj.is_a(), "Name": obj.Name, "id": int(obj.id())}
|
||||
else:
|
||||
cls.products[product_id] = {"type": None, "Name": None, "id": None}
|
||||
@@ -1,68 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.attribute
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(file.schema)
|
||||
cls.products[product_id] = []
|
||||
declaration = schema.declaration_by_name(product.is_a())
|
||||
for attribute in declaration.all_attributes():
|
||||
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
||||
value = getattr(product, attribute.name())
|
||||
list_type = None
|
||||
enum_items = ()
|
||||
|
||||
if isinstance(data_type, tuple):
|
||||
list_type = data_type[1]
|
||||
data_type = data_type[0]
|
||||
|
||||
if data_type in ["entity", "list", "string", "enum"]:
|
||||
value = None if value is None else str(value)
|
||||
elif data_type == "float":
|
||||
value = None if value is None else float(value)
|
||||
elif data_type == "integer":
|
||||
value = None if value is None else int(value)
|
||||
|
||||
if data_type == "enum":
|
||||
enum_items = ifcopenshell.util.attribute.get_enum_items(attribute)
|
||||
|
||||
cls.products[product_id].append(
|
||||
{
|
||||
"name": attribute.name(),
|
||||
"value": value,
|
||||
"type": data_type,
|
||||
"enum_items": enum_items,
|
||||
"list_type": list_type,
|
||||
"is_optional": attribute.optional(),
|
||||
"is_null": getattr(product, attribute.name()) is None,
|
||||
}
|
||||
)
|
||||
@@ -1,52 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
boundaries = {}
|
||||
spaces = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.boundaries = {}
|
||||
cls.spaces = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls._file = file
|
||||
for boundary in cls._file.by_type("IfcRelSpaceBoundary"):
|
||||
data = boundary.get_info()
|
||||
data["RelatingSpace"] = data["RelatingSpace"].id() if data["RelatingSpace"] else None
|
||||
data["RelatedBuildingElement"] = (
|
||||
data["RelatedBuildingElement"].id() if data["RelatedBuildingElement"] else None
|
||||
)
|
||||
del data["ConnectionGeometry"]
|
||||
if cls._file.schema == "IFC2X3":
|
||||
pass
|
||||
else:
|
||||
if boundary.is_a("IfcRelSpaceBoundary1stLevel"):
|
||||
data["ParentBoundary"] = data["ParentBoundary"].id() if data["ParentBoundary"] else None
|
||||
if boundary.is_a("IfcRelSpaceBoundary2ndLevel"):
|
||||
data["CorrespondingBoundary"] = (
|
||||
data["CorrespondingBoundary"].id() if data["CorrespondingBoundary"] else None
|
||||
)
|
||||
cls.boundaries[boundary.id()] = data
|
||||
cls.spaces.setdefault(data["RelatingSpace"], []).append(boundary.id())
|
||||
cls.is_loaded = True
|
||||
@@ -1,94 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
products = {}
|
||||
classifications = {}
|
||||
references = {}
|
||||
library_file = None
|
||||
library_classifications = {}
|
||||
library_references = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.products = {}
|
||||
cls.classifications = {}
|
||||
cls.references = {}
|
||||
cls.library_file = None
|
||||
cls.library_classifications = {}
|
||||
cls.library_references = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
if product_id:
|
||||
return cls.load_product_classifications(product_id)
|
||||
cls.load_classifications()
|
||||
cls.load_references()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_product_classifications(cls, product_id):
|
||||
product = cls._file.by_id(product_id)
|
||||
cls.products[product_id] = []
|
||||
if not product.HasAssociations:
|
||||
return
|
||||
for association in product.HasAssociations:
|
||||
if association.is_a("IfcRelAssociatesClassification"):
|
||||
cls.products[product_id].append(association.RelatingClassification.id())
|
||||
|
||||
@classmethod
|
||||
def load_classifications(cls):
|
||||
cls.classifications = {}
|
||||
for classification in cls._file.by_type("IfcClassification"):
|
||||
data = classification.get_info()
|
||||
if cls._file.schema == "IFC2X3" and data["EditionDate"]:
|
||||
data["EditionDate"] = ifcopenshell.util.date.ifc2datetime(data["EditionDate"]).isoformat()
|
||||
cls.classifications[classification.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_references(cls):
|
||||
cls.references = {}
|
||||
for reference in cls._file.by_type("IfcClassificationReference"):
|
||||
data = reference.get_info()
|
||||
if reference.ReferencedSource:
|
||||
# data["ReferencedSource"] = cls.get_referenced_source(reference.ReferencedSource)
|
||||
data["ReferencedSource"] = reference.ReferencedSource.id()
|
||||
cls.references[reference.id()] = data
|
||||
|
||||
@classmethod
|
||||
def get_referenced_source(cls, reference):
|
||||
if reference.is_a("IfcClassification"):
|
||||
return reference
|
||||
elif reference.is_a("IfcClassificationReference") and reference.ReferencedSource:
|
||||
return cls.get_referenced_source(reference.ReferencedSource)
|
||||
|
||||
@classmethod
|
||||
def load_library(cls, filepath):
|
||||
cls.library_file = ifcopenshell.open(filepath)
|
||||
cls.library_classifications = {}
|
||||
for classification in cls.library_file.by_type("IfcClassification"):
|
||||
cls.library_classifications[classification.id()] = classification.Name
|
||||
@@ -1,105 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
products = {}
|
||||
objectives = {}
|
||||
metrics = {}
|
||||
references = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.products = {}
|
||||
cls.objectives = {}
|
||||
cls.metrics = {}
|
||||
cls.references = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
if product_id:
|
||||
return cls.load_product(product_id)
|
||||
cls.load_objectives()
|
||||
cls.load_metrics()
|
||||
cls.load_references()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_product(cls, product_id):
|
||||
product = cls._file.by_id(product_id)
|
||||
cls.products[product_id] = []
|
||||
if not product.HasAssociations:
|
||||
return
|
||||
for association in product.HasAssociations:
|
||||
if association.is_a("IfcRelAssociatesConstraint"):
|
||||
if not association.RelatingConstraint.is_a("IfcObjective"):
|
||||
continue # not yet implemented
|
||||
cls.products[product_id].append(association.RelatingConstraint.id())
|
||||
|
||||
@classmethod
|
||||
def load_objectives(cls):
|
||||
cls.objectives = {}
|
||||
for constraint in cls._file.by_type("IfcObjective"):
|
||||
data = constraint.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
|
||||
if cls._file.schema == "IFC2X3":
|
||||
for attribute in ["CreationTime"]:
|
||||
if data[attribute]:
|
||||
data[attribute] = ifcopenshell.util.date.ifc2datetime(data[attribute]).isoformat()
|
||||
data["BenchmarkValues"] = [metric.id() for metric in constraint.BenchmarkValues or []]
|
||||
cls.objectives[constraint.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_metrics(cls):
|
||||
cls.metrics = {}
|
||||
for metric in cls._file.by_type("IfcMetric"):
|
||||
data = metric.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
data["ConstrainedObjects"] = []
|
||||
for association in cls._file.by_type("IfcRelAssociatesConstraint"):
|
||||
if association.RelatingConstraint.id() == metric.id():
|
||||
data["ConstrainedObjects"] = [o.id() for o in association.RelatedObjects or []]
|
||||
if metric.DataValue:
|
||||
data["DataValue"] = data["DataValue"].id()
|
||||
if metric.ReferencePath:
|
||||
data["ReferencePath"] = data["ReferencePath"].id()
|
||||
cls.metrics[metric.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_references(cls):
|
||||
cls.references = {}
|
||||
for reference in cls._file.by_type("IfcReference"):
|
||||
data = reference.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
cls.references[refenrece.id()] = data
|
||||
@@ -1,43 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
contexts = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.contexts = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.contexts = {}
|
||||
for context in file.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
subcontexts = {}
|
||||
for subcontext in context.HasSubContexts:
|
||||
subcontexts[int(subcontext.id())] = {
|
||||
"ContextType": subcontext.ContextType,
|
||||
"ContextIdentifier": subcontext.ContextIdentifier,
|
||||
"TargetView": subcontext.TargetView,
|
||||
}
|
||||
cls.contexts[int(context.id())] = {"ContextType": context.ContextType, "HasSubContexts": subcontexts}
|
||||
cls.is_loaded = True
|
||||
@@ -1,254 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.cost
|
||||
|
||||
|
||||
class CostValueTrait:
|
||||
@classmethod
|
||||
def load_cost_values(cls, root_element, data):
|
||||
data["CostValues"] = []
|
||||
data["CategoryValues"] = {}
|
||||
data["UnitBasisValueComponent"] = None
|
||||
data["UnitBasisUnitSymbol"] = None
|
||||
data["TotalAppliedValue"] = 0.0
|
||||
data["TotalCost"] = 0.0
|
||||
if root_element.is_a("IfcCostItem"):
|
||||
values = root_element.CostValues
|
||||
elif root_element.is_a("IfcConstructionResource"):
|
||||
values = root_element.BaseCosts
|
||||
for cost_value in values or []:
|
||||
cls.load_cost_value(root_element, data, cost_value)
|
||||
data["CostValues"].append(cost_value.id())
|
||||
data["TotalAppliedValue"] += cls.cost_values[cost_value.id()]["AppliedValue"]
|
||||
if cost_value.UnitBasis:
|
||||
cost_value_data = cls.cost_values[cost_value.id()]
|
||||
data["UnitBasisValueComponent"] = cost_value_data["UnitBasis"]["ValueComponent"]
|
||||
data["UnitBasisUnitSymbol"] = cost_value_data["UnitBasis"]["UnitSymbol"]
|
||||
if data["UnitBasisValueComponent"]:
|
||||
data["TotalCost"] = data["TotalCostQuantity"] / data["UnitBasisValueComponent"] * data["TotalAppliedValue"]
|
||||
else:
|
||||
data["TotalCost"] = data["TotalCostQuantity"] * data["TotalAppliedValue"]
|
||||
|
||||
@classmethod
|
||||
def load_cost_value(cls, root_element, root_element_data, cost_value):
|
||||
value_data = cost_value.get_info()
|
||||
del value_data["AppliedValue"]
|
||||
if value_data["UnitBasis"]:
|
||||
data = cost_value.UnitBasis.get_info()
|
||||
data["ValueComponent"] = data["ValueComponent"].wrappedValue
|
||||
data["UnitComponent"] = data["UnitComponent"].id()
|
||||
data["UnitSymbol"] = ifcopenshell.util.unit.get_unit_symbol(cost_value.UnitBasis.UnitComponent)
|
||||
value_data["UnitBasis"] = data
|
||||
if value_data["ApplicableDate"]:
|
||||
value_data["ApplicableDate"] = ifcopenshell.util.date.ifc2datetime(value_data["ApplicableDate"])
|
||||
if value_data["FixedUntilDate"]:
|
||||
value_data["FixedUntilDate"] = ifcopenshell.util.date.ifc2datetime(value_data["FixedUntilDate"])
|
||||
value_data["Components"] = [c.id() for c in value_data["Components"] or []]
|
||||
value_data["AppliedValue"] = cls.calculate_applied_value(root_element, cost_value)
|
||||
|
||||
if cost_value.Category not in [None, "*"]:
|
||||
root_element_data["CategoryValues"].setdefault(cost_value.Category, 0)
|
||||
root_element_data["CategoryValues"][cost_value.Category] += value_data["AppliedValue"]
|
||||
|
||||
value_data["Formula"] = ifcopenshell.util.cost.serialise_cost_value(cost_value)
|
||||
|
||||
cls.cost_values[cost_value.id()] = value_data
|
||||
for component in cost_value.Components or []:
|
||||
cls.load_cost_value(root_element, root_element_data, component)
|
||||
|
||||
@classmethod
|
||||
def calculate_applied_value(cls, root_element, cost_value, category_filter=None):
|
||||
if cost_value.ArithmeticOperator and cost_value.Components:
|
||||
component_values = []
|
||||
for component in cost_value.Components:
|
||||
component_values.append(cls.calculate_applied_value(root_element, component, category_filter))
|
||||
if cost_value.ArithmeticOperator == "ADD":
|
||||
return sum(component_values)
|
||||
result = component_values.pop(0)
|
||||
if cost_value.ArithmeticOperator == "DIVIDE":
|
||||
for value in component_values:
|
||||
try:
|
||||
result /= value
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
elif cost_value.ArithmeticOperator == "MULTIPLY":
|
||||
for value in component_values:
|
||||
result *= value
|
||||
elif cost_value.ArithmeticOperator == "SUBTRACT":
|
||||
for value in component_values:
|
||||
result -= value
|
||||
return result
|
||||
if cost_value.Category is None:
|
||||
return cls.get_primitive_applied_value(cost_value.AppliedValue)
|
||||
elif cost_value.Category == "*":
|
||||
if root_element.IsNestedBy:
|
||||
return cls.sum_child_root_elements(root_element)
|
||||
else:
|
||||
return cls.get_primitive_applied_value(cost_value.AppliedValue)
|
||||
elif cost_value.Category:
|
||||
if root_element.IsNestedBy:
|
||||
return cls.sum_child_root_elements(root_element, category_filter=cost_value.Category)
|
||||
else:
|
||||
return cls.get_primitive_applied_value(cost_value.AppliedValue)
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def sum_child_root_elements(cls, root_element, category_filter=None):
|
||||
result = 0
|
||||
for rel in root_element.IsNestedBy:
|
||||
for child_root_element in rel.RelatedObjects:
|
||||
if root_element.is_a("IfcCostItem"):
|
||||
values = child_root_element.CostValues
|
||||
elif root_element.is_a("IfcConstructionResource"):
|
||||
values = child_root_element.BaseCosts
|
||||
for child_cost_value in values or []:
|
||||
if category_filter and child_cost_value.Category != category_filter:
|
||||
continue
|
||||
child_applied_value = cls.calculate_applied_value(child_root_element, child_cost_value)
|
||||
child_quantity = cls.get_total_quantity(child_root_element)
|
||||
if child_cost_value.UnitBasis:
|
||||
value_component = child_cost_value.UnitBasis.ValueComponent.wrappedValue
|
||||
result += child_quantity / value_component * child_applied_value
|
||||
else:
|
||||
result += child_quantity * child_applied_value
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def get_total_quantity(cls, root_element):
|
||||
if root_element.is_a("IfcCostItem"):
|
||||
return sum([q[3] for q in root_element.CostQuantities or []]) or 1.0
|
||||
elif root_element.is_a("IfcConstructionResource"):
|
||||
return root_element.BaseQuantity[3] if root_element.BaseQuantity else 1.0
|
||||
|
||||
@classmethod
|
||||
def get_primitive_applied_value(cls, applied_value):
|
||||
if not applied_value:
|
||||
return 0.0
|
||||
elif isinstance(applied_value, float):
|
||||
return applied_value
|
||||
elif hasattr(applied_value, "wrappedValue") and isinstance(applied_value.wrappedValue, float):
|
||||
return applied_value.wrappedValue
|
||||
elif applied_value.is_a("IfcMeasureWithUnit"):
|
||||
return applied_value.ValueComponent
|
||||
assert False, "Applied value {applied_value} not implemented"
|
||||
|
||||
|
||||
class Data(CostValueTrait):
|
||||
is_loaded = False
|
||||
cost_schedules = {}
|
||||
cost_items = {}
|
||||
physical_quantities = {}
|
||||
cost_values = {}
|
||||
categories = []
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.cost_schedules = {}
|
||||
cls.cost_items = {}
|
||||
cls.physical_quantities = {}
|
||||
cls.cost_values = {}
|
||||
cls.categories = []
|
||||
|
||||
@classmethod
|
||||
def set_categories(cls, categories):
|
||||
cls.categories = categories
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls.file = file
|
||||
cls.cost_schedules = {}
|
||||
cls.cost_items = {}
|
||||
cls.physical_quantities = {}
|
||||
cls.cost_values = {}
|
||||
|
||||
for cost_schedule in cls.file.by_type("IfcCostSchedule"):
|
||||
data = cost_schedule.get_info()
|
||||
del data["OwnerHistory"]
|
||||
if data["SubmittedOn"]:
|
||||
data["SubmittedOn"] = ifcopenshell.util.date.ifc2datetime(data["SubmittedOn"])
|
||||
if data["UpdateDate"]:
|
||||
data["UpdateDate"] = ifcopenshell.util.date.ifc2datetime(data["UpdateDate"])
|
||||
data["Controls"] = []
|
||||
for rel in cost_schedule.Controls:
|
||||
for related_object in rel.RelatedObjects:
|
||||
if related_object.is_a("IfcCostItem"):
|
||||
data["Controls"].append(related_object.id())
|
||||
break # We are only allowed one summary cost item
|
||||
cls.cost_schedules[cost_schedule.id()] = data
|
||||
|
||||
for cost_item in cls.file.by_type("IfcCostItem"):
|
||||
data = cost_item.get_info()
|
||||
del data["OwnerHistory"]
|
||||
del data["CostValues"]
|
||||
data["IsNestedBy"] = []
|
||||
data["Controls"] = {}
|
||||
for rel in cost_item.IsNestedBy:
|
||||
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects if o.is_a("IfcCostItem")]
|
||||
parametric_quantities = []
|
||||
for rel in cost_item.Controls:
|
||||
for related_object in rel.RelatedObjects or []:
|
||||
quantities = cls.get_object_quantities(cost_item, related_object)
|
||||
data["Controls"][related_object.id()] = quantities
|
||||
parametric_quantities.extend(quantities)
|
||||
cls.cost_items[cost_item.id()] = data
|
||||
cls.load_cost_item_quantities(cost_item, data, parametric_quantities)
|
||||
cls.load_cost_values(cost_item, data)
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def get_object_quantities(cls, cost_item, element):
|
||||
if not element.is_a("IfcObject"):
|
||||
return []
|
||||
results = []
|
||||
for relationship in element.IsDefinedBy:
|
||||
if not relationship.is_a("IfcRelDefinesByProperties"):
|
||||
continue
|
||||
qto = relationship.RelatingPropertyDefinition
|
||||
if not qto.is_a("IfcElementQuantity"):
|
||||
continue
|
||||
for prop in qto.Quantities:
|
||||
if prop in cost_item.CostQuantities or []:
|
||||
results.append(prop.id())
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def load_cost_item_quantities(cls, cost_item, data, parametric_quantities):
|
||||
data["CostQuantities"] = []
|
||||
data["TotalCostQuantity"] = cls.get_total_quantity(cost_item)
|
||||
for quantity in cost_item.CostQuantities or []:
|
||||
if quantity.id() in parametric_quantities:
|
||||
continue
|
||||
quantity_data = quantity.get_info()
|
||||
del quantity_data["Unit"]
|
||||
cls.physical_quantities[quantity.id()] = quantity_data
|
||||
data["CostQuantities"].append(quantity.id())
|
||||
data["Unit"] = None
|
||||
data["UnitSymbol"] = "?"
|
||||
if cost_item.CostQuantities:
|
||||
quantity = cost_item.CostQuantities[0]
|
||||
unit = ifcopenshell.util.unit.get_property_unit(quantity, cls.file)
|
||||
if unit:
|
||||
data["Unit"] = unit.id()
|
||||
data["UnitSymbol"] = ifcopenshell.util.unit.get_unit_symbol(unit)
|
||||
else:
|
||||
data["Unit"] = None
|
||||
data["UnitSymbol"] = None
|
||||
@@ -1,83 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
products = {}
|
||||
references = {}
|
||||
information = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.products = {}
|
||||
cls.references = {}
|
||||
cls.information = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
if product_id:
|
||||
return cls.load_product(product_id)
|
||||
cls.load_references()
|
||||
cls.load_information()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_product(cls, product_id):
|
||||
product = cls._file.by_id(product_id)
|
||||
cls.products[product_id] = []
|
||||
if not product.HasAssociations:
|
||||
return
|
||||
for association in product.HasAssociations:
|
||||
if association.is_a("IfcRelAssociatesDocument"):
|
||||
cls.products[product_id].append(association.RelatingDocument.id())
|
||||
|
||||
@classmethod
|
||||
def load_information(cls):
|
||||
cls.information = {}
|
||||
for information in cls._file.by_type("IfcDocumentInformation"):
|
||||
data = information.get_info()
|
||||
if cls._file.schema == "IFC2X3":
|
||||
for attribute in ["CreationTime", "LastRevisionTime", "ValidFrom", "ValidUntil"]:
|
||||
if data[attribute]:
|
||||
data[attribute] = ifcopenshell.util.date.ifc2datetime(data[attribute]).isoformat()
|
||||
if data["ElectronicFormat"]:
|
||||
data["ElectronicFormat"] = "{}/{}".format(
|
||||
information.ElectronicFormat.MimeContentType, information.ElectronicFormat.MimeSubtype
|
||||
)
|
||||
cls.information[information.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_references(cls):
|
||||
cls.references = {}
|
||||
for reference in cls._file.by_type("IfcDocumentReference"):
|
||||
data = reference.get_info()
|
||||
if cls._file.schema == "IFC2X3":
|
||||
if reference.ReferenceToDocument:
|
||||
data["ReferencedDocument"] = reference.ReferenceToDocument[0].id()
|
||||
elif reference.ReferencedDocument:
|
||||
data["ReferencedDocument"] = reference.ReferencedDocument.id()
|
||||
cls.references[reference.id()] = data
|
||||
@@ -1,52 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
representations = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
cls.representations = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
cls.products[product_id] = []
|
||||
product = file.by_id(product_id)
|
||||
representations = []
|
||||
if product.is_a("IfcProduct") and product.Representation:
|
||||
representations = product.Representation.Representations
|
||||
elif product.is_a("IfcTypeProduct"):
|
||||
representations = [rm.MappedRepresentation for rm in product.RepresentationMaps or []]
|
||||
for representation in representations:
|
||||
c = representation.ContextOfItems
|
||||
rep_id = int(representation.id())
|
||||
cls.representations[rep_id] = {
|
||||
"RepresentationIdentifier": representation.RepresentationIdentifier,
|
||||
"RepresentationType": representation.RepresentationType,
|
||||
"ContextOfItems": {
|
||||
"ContextType": c.ContextType,
|
||||
"ContextIdentifier": c.ContextIdentifier,
|
||||
"TargetView": c.TargetView if c.is_a("IfcGeometricRepresentationSubContext") else "",
|
||||
},
|
||||
}
|
||||
cls.products[product_id].append(rep_id)
|
||||
@@ -1,58 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
map_conversion = {}
|
||||
projected_crs = {}
|
||||
true_north = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.map_conversion = {}
|
||||
cls.projected_crs = {}
|
||||
cls.true_north = None
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.map_conversion = {}
|
||||
cls.projected_crs = {}
|
||||
cls.true_north = {}
|
||||
if file.schema == "IFC2X3":
|
||||
return
|
||||
for context in file.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
if not context.HasCoordinateOperation:
|
||||
continue
|
||||
map_conversion = context.HasCoordinateOperation[0]
|
||||
cls.map_conversion = map_conversion.get_info()
|
||||
cls.map_conversion["SourceCRS"] = cls.map_conversion["SourceCRS"].id()
|
||||
cls.map_conversion["TargetCRS"] = cls.map_conversion["TargetCRS"].id()
|
||||
cls.projected_crs = map_conversion.TargetCRS.get_info()
|
||||
if cls.projected_crs["MapUnit"]:
|
||||
cls.projected_crs["MapUnit"] = map_conversion.TargetCRS.MapUnit.get_info()
|
||||
break
|
||||
for context in file.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
if not context.TrueNorth:
|
||||
continue
|
||||
cls.true_north = context.TrueNorth.DirectionRatios
|
||||
break
|
||||
cls.is_loaded = True
|
||||
@@ -1,45 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
products = {}
|
||||
groups = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.products = {}
|
||||
cls.groups = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls.products = {}
|
||||
cls.groups = {}
|
||||
for group in file.by_type("IfcGroup", include_subtypes=False):
|
||||
if group.IsGroupedBy:
|
||||
for rel in group.IsGroupedBy:
|
||||
for product in rel.RelatedObjects:
|
||||
cls.products.setdefault(product.id(), []).append(group.id())
|
||||
data = group.get_info()
|
||||
data["HasAssignments"] = group.HasAssignments
|
||||
data["IsGroupedBy"] = group.IsGroupedBy
|
||||
del data["OwnerHistory"]
|
||||
cls.groups[group.id()] = data
|
||||
cls.is_loaded = True
|
||||
@@ -1,53 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
items = {}
|
||||
layers = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.items = {}
|
||||
cls.layers = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
cls.load_layers()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_layers(cls):
|
||||
cls.layers = {}
|
||||
cls.items = {}
|
||||
for layer in cls._file.by_type("IfcPresentationLayerAssignment"):
|
||||
data = layer.get_info()
|
||||
if layer.AssignedItems:
|
||||
for item in layer.AssignedItems:
|
||||
cls.items.setdefault(item.id(), []).append(layer.id())
|
||||
del data["AssignedItems"]
|
||||
cls.layers[layer.id()] = data
|
||||
@@ -1,139 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
materials = {}
|
||||
constituent_sets = {}
|
||||
constituents = {}
|
||||
layer_sets_usages = {}
|
||||
layer_sets = {}
|
||||
layers = {}
|
||||
profile_set_usages = {}
|
||||
profile_sets = {}
|
||||
profiles = {}
|
||||
lists = {}
|
||||
products = {}
|
||||
_file = None
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.materials = {}
|
||||
cls.constituent_sets = {}
|
||||
cls.constituents = {}
|
||||
cls.layer_set_usages = {}
|
||||
cls.layer_sets = {}
|
||||
cls.layers = {}
|
||||
cls.profile_set_usages = {}
|
||||
cls.profile_sets = {}
|
||||
cls.profiles = {}
|
||||
cls.lists = {}
|
||||
cls.products = {}
|
||||
cls._file = None
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
if product_id:
|
||||
return cls.load_product_material(product_id)
|
||||
cls.load_materials()
|
||||
cls.load_constituents()
|
||||
cls.load_layers()
|
||||
cls.load_layer_usages()
|
||||
cls.load_profiles()
|
||||
cls.load_profile_usages()
|
||||
cls.load_lists()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_materials(cls):
|
||||
cls.materials = {}
|
||||
cls.load_element("IfcMaterial", cls.materials)
|
||||
|
||||
@classmethod
|
||||
def load_constituents(cls):
|
||||
cls.constituent_sets = {}
|
||||
cls.constituents = {}
|
||||
cls.load_element("IfcMaterialConstituent", cls.constituents)
|
||||
cls.load_element("IfcMaterialConstituentSet", cls.constituent_sets)
|
||||
|
||||
@classmethod
|
||||
def load_layers(cls):
|
||||
cls.layer_sets = {}
|
||||
cls.layers = {}
|
||||
cls.load_element("IfcMaterialLayer", cls.layers)
|
||||
cls.load_element("IfcMaterialLayerSet", cls.layer_sets)
|
||||
|
||||
@classmethod
|
||||
def load_layer_usages(cls):
|
||||
cls.layer_set_usages = {}
|
||||
cls.load_element("IfcMaterialLayerSetUsage", cls.layer_set_usages)
|
||||
|
||||
@classmethod
|
||||
def load_profile_usages(cls):
|
||||
cls.profile_set_usages = {}
|
||||
cls.load_element("IfcMaterialProfileSetUsage", cls.profile_set_usages)
|
||||
|
||||
@classmethod
|
||||
def load_profiles(cls):
|
||||
cls.profile_sets = {}
|
||||
cls.profiles = {}
|
||||
cls.load_element("IfcMaterialProfile", cls.profiles)
|
||||
cls.load_element("IfcMaterialProfileSet", cls.profile_sets)
|
||||
|
||||
@classmethod
|
||||
def load_lists(cls):
|
||||
cls.lists = {}
|
||||
cls.load_element("IfcMaterialList", cls.lists)
|
||||
|
||||
@classmethod
|
||||
def load_product_material(cls, product_id):
|
||||
cls.products[product_id] = {}
|
||||
for association in cls._file.by_id(product_id).HasAssociations:
|
||||
if association.is_a("IfcRelAssociatesMaterial"):
|
||||
cls.load_association(association, product_id)
|
||||
|
||||
@classmethod
|
||||
def load_element(cls, ifc_class, to_dict):
|
||||
try:
|
||||
elements = cls._file.by_type(ifc_class)
|
||||
except:
|
||||
return
|
||||
for element in elements:
|
||||
to_dict[element.id()] = cls.get_simple_info(element)
|
||||
|
||||
@classmethod
|
||||
def get_simple_info(cls, element):
|
||||
info = element.get_info()
|
||||
for key, value in info.items():
|
||||
if isinstance(value, ifcopenshell.entity_instance):
|
||||
info[key] = value.id()
|
||||
elif isinstance(value, tuple) and value and isinstance(value[0], ifcopenshell.entity_instance):
|
||||
info[key] = [v.id() for v in value]
|
||||
return info
|
||||
|
||||
@classmethod
|
||||
def load_association(cls, association, product_id):
|
||||
material_select = association.RelatingMaterial
|
||||
cls.products[product_id] = {"type": material_select.is_a(), "id": material_select.id()}
|
||||
@@ -1,84 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
people = {}
|
||||
organisations = {}
|
||||
addresses = {}
|
||||
roles = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.people = {}
|
||||
cls.organisations = {}
|
||||
cls.addresses = {}
|
||||
cls.roles = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.people = {}
|
||||
cls.organisations = {}
|
||||
cls.addresses = {}
|
||||
cls.roles = {}
|
||||
for person in file.by_type("IfcPerson"):
|
||||
data = person.get_info()
|
||||
data["is_engaged"] = bool(person.EngagedIn)
|
||||
cls.people[person.id()] = data
|
||||
|
||||
roles = []
|
||||
if data["Roles"]:
|
||||
for role in data["Roles"]:
|
||||
roles.append(role.id())
|
||||
data["Roles"] = roles
|
||||
|
||||
addresses = []
|
||||
if data["Addresses"]:
|
||||
for address in data["Addresses"]:
|
||||
addresses.append(address.id())
|
||||
data["Addresses"] = addresses
|
||||
|
||||
for organisation in file.by_type("IfcOrganization"):
|
||||
data = organisation.get_info()
|
||||
data["is_engaged"] = (
|
||||
bool(organisation.IsRelatedBy) or bool(organisation.Relates) or bool(organisation.Engages)
|
||||
)
|
||||
cls.organisations[organisation.id()] = data
|
||||
|
||||
roles = []
|
||||
if data["Roles"]:
|
||||
for role in data["Roles"]:
|
||||
roles.append(role.id())
|
||||
data["Roles"] = roles
|
||||
|
||||
addresses = []
|
||||
if data["Addresses"]:
|
||||
for address in data["Addresses"]:
|
||||
addresses.append(address.id())
|
||||
data["Addresses"] = addresses
|
||||
|
||||
for address in file.by_type("IfcAddress"):
|
||||
cls.addresses[address.id()] = address.get_info()
|
||||
|
||||
for role in file.by_type("IfcActorRole"):
|
||||
cls.roles[role.id()] = role.get_info()
|
||||
cls.is_loaded = True
|
||||
@@ -1,36 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
profiles = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.profiles = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.profiles = {}
|
||||
for profile in file.by_type("IfcProfileDef"):
|
||||
cls.profiles[profile.id()] = profile.get_info()
|
||||
cls.is_loaded = True
|
||||
@@ -1,141 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.util.pset
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
psets = {}
|
||||
qtos = {}
|
||||
properties = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
cls.psets = {}
|
||||
cls.qtos = {}
|
||||
cls.properties = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
cls.products[product_id] = {"psets": set(), "qtos": set()}
|
||||
if product.is_a("IfcTypeObject"):
|
||||
cls.add_type_product_psets(product, product_id)
|
||||
elif product.is_a("IfcMaterialDefinition"):
|
||||
cls.add_material_psets(product, product_id)
|
||||
elif product.is_a("IfcProfileDef"):
|
||||
cls.add_profile_psets(product, product_id)
|
||||
else:
|
||||
cls.add_product_psets(product, product_id)
|
||||
|
||||
@classmethod
|
||||
def add_type_product_psets(cls, product, product_id):
|
||||
if not hasattr(product, "HasPropertySets") or not product.HasPropertySets:
|
||||
return # TODO
|
||||
for definition in product.HasPropertySets:
|
||||
if definition.is_a("IfcPropertySet"):
|
||||
cls.add_pset(definition, product_id)
|
||||
|
||||
@classmethod
|
||||
def add_material_psets(cls, product, product_id):
|
||||
if not product.HasProperties:
|
||||
return
|
||||
for pset in product.HasProperties:
|
||||
cls.add_pset(pset, product_id)
|
||||
|
||||
@classmethod
|
||||
def add_profile_psets(cls, product, product_id):
|
||||
if not product.HasProperties:
|
||||
return
|
||||
for pset in product.HasProperties:
|
||||
cls.add_pset(pset, product_id)
|
||||
|
||||
@classmethod
|
||||
def add_product_psets(cls, product, product_id):
|
||||
if not hasattr(product, "IsDefinedBy") or not product.IsDefinedBy:
|
||||
return
|
||||
for definition in product.IsDefinedBy:
|
||||
if not definition.is_a("IfcRelDefinesByProperties"):
|
||||
continue
|
||||
if definition.RelatingPropertyDefinition.is_a("IfcPropertySet"):
|
||||
cls.add_pset(definition.RelatingPropertyDefinition, product_id)
|
||||
elif definition.RelatingPropertyDefinition.is_a("IfcElementQuantity"):
|
||||
cls.add_qto(definition.RelatingPropertyDefinition, product_id)
|
||||
|
||||
@classmethod
|
||||
def add_pset(cls, pset, product_id):
|
||||
data = pset.get_info()
|
||||
if not pset.is_a("IfcMaterialProperties") and not pset.is_a("IfcProfileProperties"):
|
||||
del data["OwnerHistory"]
|
||||
del data["HasProperties"]
|
||||
if hasattr(pset, "HasProperties"):
|
||||
props = pset.HasProperties or []
|
||||
elif hasattr(pset, "Properties"):
|
||||
props = pset.Properties or []
|
||||
# TODO: support more than single values
|
||||
data["Properties"] = [p.id() for p in props if p.is_a("IfcPropertyEnumeratedValue") or p.is_a("IfcPropertySingleValue")]
|
||||
cls.psets[pset.id()] = data
|
||||
cls.products[product_id]["psets"].add(pset.id())
|
||||
for prop in props:
|
||||
# TODO: support more than single values
|
||||
if prop.is_a("IfcPropertySingleValue"):
|
||||
cls.load_prop(prop)
|
||||
elif prop.is_a("IfcPropertyEnumeratedValue"):
|
||||
cls.load_prop_enum(prop)
|
||||
|
||||
@classmethod
|
||||
def load_prop(cls, prop):
|
||||
data = prop.get_info()
|
||||
if prop.is_a("IfcProperty"):
|
||||
# TODO: support units
|
||||
del data["Unit"]
|
||||
if prop.NominalValue is not None:
|
||||
data["NominalValue"] = prop.NominalValue.wrappedValue
|
||||
elif prop.is_a("IfcPhysicalQuantity"):
|
||||
# TODO: support units
|
||||
del data["Unit"]
|
||||
# For convenience, which trumps correctness in this case
|
||||
data["NominalValue"] = prop[3]
|
||||
cls.properties[prop.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_prop_enum(cls, prop):
|
||||
data = prop.get_info()
|
||||
enumerations = [enum.wrappedValue for enum in data["EnumerationValues"]]
|
||||
data["NominalValue"] = str(enumerations)
|
||||
cls.properties[prop.id()] = data
|
||||
|
||||
@classmethod
|
||||
def add_qto(cls, qto, product_id):
|
||||
data = qto.get_info()
|
||||
del data["OwnerHistory"]
|
||||
del data["Quantities"]
|
||||
# TODO: support more than just simple quantities
|
||||
# We call it properties for convenience, not for correctness
|
||||
data["Properties"] = [q.id() for q in qto.Quantities or [] if q.is_a("IfcPhysicalSimpleQuantity")]
|
||||
cls.qtos[qto.id()] = data
|
||||
cls.products[product_id]["qtos"].add(qto.id())
|
||||
for quantity in qto.Quantities or []:
|
||||
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
||||
cls.load_prop(quantity)
|
||||
@@ -1,55 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
pset_templates = {}
|
||||
prop_templates = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.pset_templates = {}
|
||||
cls.prop_templates = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls._file = file
|
||||
|
||||
cls.pset_templates = {}
|
||||
cls.prop_templates = {}
|
||||
|
||||
for pset_template in cls._file.by_type("IfcPropertySetTemplate"):
|
||||
data = pset_template.get_info()
|
||||
data["HasPropertyTemplates"] = [e.id() for e in pset_template.HasPropertyTemplates or []]
|
||||
if "OwnerHistory" in data:
|
||||
del data["OwnerHistory"]
|
||||
cls.pset_templates[pset_template.id()] = data
|
||||
|
||||
for prop_template in cls._file.by_type("IfcSimplePropertyTemplate"):
|
||||
data = prop_template.get_info()
|
||||
cls.prop_templates[prop_template.id()] = {
|
||||
"GlobalId": data["GlobalId"],
|
||||
"Name": data["Name"],
|
||||
"Description": data["Description"],
|
||||
"PrimaryMeasureType": data["PrimaryMeasureType"],
|
||||
"TemplateType": data["TemplateType"],
|
||||
"Enumerators": data["Enumerators"]
|
||||
}
|
||||
cls.is_loaded = True
|
||||
@@ -1,90 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
from ifcopenshell.api.cost.data import CostValueTrait
|
||||
|
||||
|
||||
class Data(CostValueTrait):
|
||||
is_loaded = False
|
||||
resources = {}
|
||||
resource_times = {}
|
||||
cost_values = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.resources = {}
|
||||
cls.resource_times = {}
|
||||
cls.cost_values = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
cls.load_resources()
|
||||
cls.load_resource_times()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_resources(cls):
|
||||
cls.resources = {}
|
||||
cls.cost_values = {}
|
||||
for resource in cls._file.by_type("IfcResource"):
|
||||
data = resource.get_info()
|
||||
del data["OwnerHistory"]
|
||||
data["IsNestedBy"] = []
|
||||
for rel in resource.IsNestedBy:
|
||||
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects]
|
||||
data["Nests"] = []
|
||||
for rel in resource.Nests:
|
||||
[data["Nests"].append(rel.RelatingObject.id())]
|
||||
data["ResourceOf"] = []
|
||||
for rel in resource.ResourceOf:
|
||||
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
|
||||
data["HasContext"] = (
|
||||
resource.HasContext[0].RelatingContext.id()
|
||||
if resource.HasContext
|
||||
else None
|
||||
)
|
||||
if resource.Usage:
|
||||
data["Usage"] = data["Usage"].id()
|
||||
data["TotalCostQuantity"] = cls.get_total_quantity(resource)
|
||||
if resource.BaseQuantity:
|
||||
data["BaseQuantity"] = resource.BaseQuantity.get_info()
|
||||
del data["BaseQuantity"]["Unit"]
|
||||
if resource.BaseCosts:
|
||||
data["BaseCosts"] = [e.id() for e in resource.BaseCosts]
|
||||
cls.load_cost_values(resource, data)
|
||||
cls.resources[resource.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_resource_times(cls):
|
||||
cls.resource_times = {}
|
||||
for resource_time in cls._file.by_type("IfcResourceTime"):
|
||||
data = resource_time.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
elif "Work" in key or key == "LevelingDelay":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
cls.resource_times[resource_time.id()] = data
|
||||
@@ -1,36 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
cls.products[product_id] = {
|
||||
"type": product.is_a(),
|
||||
"PredefinedType": product.PredefinedType if hasattr(product, "PredefinedType") else None,
|
||||
"ObjectType": product.ObjectType if hasattr(product, "ObjectType") else None,
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.date
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
work_schedules = {}
|
||||
work_calendars = {}
|
||||
work_times = {}
|
||||
recurrence_patterns = {}
|
||||
time_periods = {}
|
||||
tasks = {}
|
||||
task_times = {}
|
||||
lag_times = {}
|
||||
sequences = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.work_schedules = {}
|
||||
cls.work_calendars = {}
|
||||
cls.work_times = {}
|
||||
cls.recurrence_patterns = {}
|
||||
cls.time_periods = {}
|
||||
cls.tasks = {}
|
||||
cls.task_times = {}
|
||||
cls.lag_times = {}
|
||||
cls.sequences = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
cls.load_work_schedules()
|
||||
cls.load_work_calendars()
|
||||
cls.load_work_times()
|
||||
cls.load_recurrence_patterns()
|
||||
cls.load_time_periods()
|
||||
cls.load_tasks()
|
||||
cls.load_task_times()
|
||||
cls.load_lag_times()
|
||||
cls.load_sequences()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_work_schedules(cls):
|
||||
cls.work_schedules = {}
|
||||
for work_schedule in cls._file.by_type("IfcWorkSchedule"):
|
||||
data = work_schedule.get_info()
|
||||
del data["OwnerHistory"]
|
||||
if data["Creators"]:
|
||||
data["Creators"] = [p.id() for p in data["Creators"]]
|
||||
data["CreationDate"] = ifcopenshell.util.date.ifc2datetime(
|
||||
data["CreationDate"]
|
||||
)
|
||||
data["StartTime"] = ifcopenshell.util.date.ifc2datetime(data["StartTime"])
|
||||
if data["FinishTime"]:
|
||||
data["FinishTime"] = ifcopenshell.util.date.ifc2datetime(
|
||||
data["FinishTime"]
|
||||
)
|
||||
data["RelatedObjects"] = []
|
||||
for rel in work_schedule.Controls:
|
||||
for obj in rel.RelatedObjects:
|
||||
if obj.is_a("IfcTask"):
|
||||
data["RelatedObjects"].append(obj.id())
|
||||
cls.work_schedules[work_schedule.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_work_calendars(cls):
|
||||
cls.work_calendars = {}
|
||||
for work_calendar in cls._file.by_type("IfcWorkCalendar"):
|
||||
data = work_calendar.get_info()
|
||||
del data["OwnerHistory"]
|
||||
data["WorkingTimes"] = [t.id() for t in work_calendar.WorkingTimes or []]
|
||||
data["ExceptionTimes"] = [
|
||||
t.id() for t in work_calendar.ExceptionTimes or []
|
||||
]
|
||||
cls.work_calendars[work_calendar.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_work_times(cls):
|
||||
cls.work_times = {}
|
||||
for work_time in cls._file.by_type("IfcWorkTime"):
|
||||
data = work_time.get_info()
|
||||
data["Start"] = (
|
||||
ifcopenshell.util.date.ifc2datetime(data["Start"])
|
||||
if data["Start"]
|
||||
else None
|
||||
)
|
||||
data["Finish"] = (
|
||||
ifcopenshell.util.date.ifc2datetime(data["Finish"])
|
||||
if data["Finish"]
|
||||
else None
|
||||
)
|
||||
data["RecurrencePattern"] = (
|
||||
work_time.RecurrencePattern.id()
|
||||
if work_time.RecurrencePattern
|
||||
else None
|
||||
)
|
||||
cls.work_times[work_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_recurrence_patterns(cls):
|
||||
cls.recurrence_patterns = {}
|
||||
for recurrence_pattern in cls._file.by_type("IfcRecurrencePattern"):
|
||||
data = recurrence_pattern.get_info()
|
||||
data["TimePeriods"] = [t.id() for t in recurrence_pattern.TimePeriods or []]
|
||||
cls.recurrence_patterns[recurrence_pattern.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_time_periods(cls):
|
||||
cls.time_periods = {}
|
||||
for time_period in cls._file.by_type("IfcTimePeriod"):
|
||||
cls.time_periods[time_period.id()] = {
|
||||
"StartTime": ifcopenshell.util.date.ifc2datetime(time_period.StartTime),
|
||||
"EndTime": ifcopenshell.util.date.ifc2datetime(time_period.EndTime),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def load_tasks(cls):
|
||||
cls.tasks = {}
|
||||
for task in cls._file.by_type("IfcTask"):
|
||||
data = task.get_info()
|
||||
del data["OwnerHistory"]
|
||||
data["HasAssignmentsWorkCalendar"] = []
|
||||
data["RelatedObjects"] = []
|
||||
data["Inputs"] = []
|
||||
data["Controls"] = []
|
||||
data["Outputs"] = []
|
||||
data["Resources"] = []
|
||||
data["IsPredecessorTo"] = []
|
||||
data["IsSuccessorFrom"] = []
|
||||
if task.TaskTime:
|
||||
data["TaskTime"] = data["TaskTime"].id()
|
||||
for rel in task.IsNestedBy:
|
||||
[
|
||||
data["RelatedObjects"].append(o.id())
|
||||
for o in rel.RelatedObjects
|
||||
if o.is_a("IfcTask")
|
||||
]
|
||||
data["Nests"] = [r.RelatingObject.id() for r in task.Nests or []]
|
||||
[
|
||||
data["Outputs"].append(r.RelatingProduct.id())
|
||||
for r in task.HasAssignments
|
||||
if r.is_a("IfcRelAssignsToProduct")
|
||||
]
|
||||
[
|
||||
data["Resources"].extend(
|
||||
[o.id() for o in r.RelatedObjects if o.is_a("IfcResource")]
|
||||
)
|
||||
for r in task.OperatesOn
|
||||
]
|
||||
[
|
||||
data["Controls"].extend(
|
||||
[o.id() for o in r.RelatedObjects if o.is_a("IfcControl")]
|
||||
)
|
||||
for r in task.OperatesOn
|
||||
]
|
||||
[
|
||||
data["Inputs"].extend(
|
||||
[o.id() for o in r.RelatedObjects if o.is_a("IfcProduct")]
|
||||
)
|
||||
for r in task.OperatesOn
|
||||
]
|
||||
[
|
||||
data["IsPredecessorTo"].append(rel.id())
|
||||
for rel in task.IsPredecessorTo or []
|
||||
]
|
||||
[
|
||||
data["IsSuccessorFrom"].append(rel.id())
|
||||
for rel in task.IsSuccessorFrom or []
|
||||
]
|
||||
[
|
||||
data["HasAssignmentsWorkCalendar"].append(rel.RelatingControl.id())
|
||||
for rel in task.HasAssignments or []
|
||||
if rel.is_a("IfcRelAssignsToControl")
|
||||
and rel.RelatingControl.is_a("IfcWorkCalendar")
|
||||
]
|
||||
cls.tasks[task.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_task_times(cls):
|
||||
cls.task_times = {}
|
||||
for task_time in cls._file.by_type("IfcTaskTime"):
|
||||
data = task_time.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
elif key == "ScheduleDuration":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
cls.task_times[task_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_lag_times(cls):
|
||||
cls.lag_times = {}
|
||||
for lag_time in cls._file.by_type("IfcLagTime"):
|
||||
data = lag_time.get_info()
|
||||
if data["LagValue"]:
|
||||
if data["LagValue"].is_a("IfcDuration"):
|
||||
data["LagValue"] = ifcopenshell.util.date.ifc2datetime(
|
||||
data["LagValue"].wrappedValue
|
||||
)
|
||||
else:
|
||||
data["LagValue"] = float(data["LagValue"].wrappedValue)
|
||||
cls.lag_times[lag_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_sequences(cls):
|
||||
cls.sequences = {}
|
||||
for sequence in cls._file.by_type("IfcRelSequence"):
|
||||
data = sequence.get_info()
|
||||
data["RelatingProcess"] = sequence.RelatingProcess.id()
|
||||
data["RelatedProcess"] = sequence.RelatedProcess.id()
|
||||
data["TimeLag"] = sequence.TimeLag.id() if sequence.TimeLag else None
|
||||
cls.sequences[sequence.id()] = data
|
||||
@@ -1,69 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
spatial_elements = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
cls.spatial_elements = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
if product_id:
|
||||
return cls.load_product(file, product_id)
|
||||
cls.load_spatial_elements(file)
|
||||
|
||||
@classmethod
|
||||
def load_product(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
if not hasattr(product, "ContainedInStructure"):
|
||||
cls.products[product_id] = None
|
||||
elif product.ContainedInStructure:
|
||||
structure = product.ContainedInStructure[0].RelatingStructure
|
||||
cls.products[product_id] = {"type": structure.is_a(), "Name": structure.Name, "id": int(structure.id())}
|
||||
else:
|
||||
cls.products[product_id] = {"type": None, "Name": None, "id": None}
|
||||
|
||||
@classmethod
|
||||
def load_spatial_elements(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.spatial_elements = {}
|
||||
ifc_class = "IfcSpatialElement"
|
||||
if file.schema == "IFC2X3":
|
||||
ifc_class = "IfcSpatialStructureElement"
|
||||
for element in file.by_type(ifc_class):
|
||||
decomposes = None
|
||||
if element.Decomposes:
|
||||
decomposes = element.Decomposes[0].RelatingObject.id()
|
||||
is_decomposed_by = []
|
||||
if element.IsDecomposedBy:
|
||||
for rel in element.IsDecomposedBy:
|
||||
is_decomposed_by.extend([e.id() for e in rel.RelatedObjects])
|
||||
cls.spatial_elements[element.id()] = {
|
||||
"Name": element.Name,
|
||||
"LongName": element.LongName,
|
||||
"Decomposes": decomposes,
|
||||
"IsDecomposedBy": is_decomposed_by,
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
connections = {}
|
||||
boundary_conditions = {}
|
||||
connects_structural_members = {}
|
||||
members = {}
|
||||
structural_activities = {}
|
||||
structural_loads = {}
|
||||
connects_structural_activities = {}
|
||||
|
||||
load_cases = {}
|
||||
load_case_combinations = {}
|
||||
load_groups = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.connections = {}
|
||||
cls.boundary_conditions = {}
|
||||
cls.connects_structural_members = {}
|
||||
cls.members = {}
|
||||
cls.structural_activities = {}
|
||||
cls.structural_loads = {}
|
||||
cls.connects_structural_activities = {}
|
||||
|
||||
cls.load_cases = {}
|
||||
cls.load_case_combinations = {}
|
||||
cls.load_groups = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id=None):
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
if product_id:
|
||||
product = cls._file.by_id(product_id)
|
||||
if product.is_a("IfcStructuralConnection"):
|
||||
return cls.load_structural_connection(product_id)
|
||||
if product.is_a("IfcStructuralMember"):
|
||||
return cls.load_structural_member(product_id)
|
||||
# if product.is_a("IfcStructuralAction"):
|
||||
# return cls.load_structural_action(product_id)
|
||||
cls.load_structural_load_cases()
|
||||
cls.load_structural_load_case_combinations()
|
||||
cls.load_structural_load_groups()
|
||||
cls.load_structural_activities()
|
||||
cls.load_structural_loads()
|
||||
cls.load_boundary_conditions()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_structural_load_cases(cls):
|
||||
cls.load_cases = {}
|
||||
|
||||
for case in cls._file.by_type("IfcStructuralLoadCase"):
|
||||
data = case.get_info()
|
||||
del data["OwnerHistory"]
|
||||
is_grouped_by = []
|
||||
for rel in case.IsGroupedBy or []:
|
||||
is_grouped_by.extend([o.id() for o in rel.RelatedObjects])
|
||||
data["IsGroupedBy"] = is_grouped_by
|
||||
cls.load_cases[case.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_structural_load_case_combinations(cls):
|
||||
cls.load_case_combinations = {}
|
||||
|
||||
for case in cls._file.by_type("IfcStructuralLoadGroup", include_subtypes=False):
|
||||
if case.PredefinedType != "LOAD_COMBINATION":
|
||||
continue
|
||||
data = case.get_info()
|
||||
del data["OwnerHistory"]
|
||||
|
||||
is_grouped_by = []
|
||||
for load_group in case.IsGroupedBy or []:
|
||||
is_grouped_by.append(load_group.id())
|
||||
data["IsGroupedBy"] = is_grouped_by
|
||||
|
||||
cls.load_case_combinations[case.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_structural_load_groups(cls):
|
||||
cls.load_groups = {}
|
||||
|
||||
for case in cls._file.by_type("IfcStructuralLoadGroup", include_subtypes=False):
|
||||
if case.PredefinedType == "LOAD_COMBINATION":
|
||||
continue
|
||||
data = case.get_info()
|
||||
del data["OwnerHistory"]
|
||||
|
||||
is_grouped_by = []
|
||||
for rel in case.IsGroupedBy or []:
|
||||
is_grouped_by.extend([o.id() for o in rel.RelatedObjects])
|
||||
data["IsGroupedBy"] = is_grouped_by
|
||||
|
||||
cls.load_groups[case.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_structural_activities(cls):
|
||||
cls.structural_activities = {}
|
||||
for activity in cls._file.by_type("IfcStructuralActivity"):
|
||||
data = activity.get_info()
|
||||
del data["OwnerHistory"]
|
||||
del data["ObjectPlacement"]
|
||||
del data["Representation"]
|
||||
data["AppliedLoad"] = data["AppliedLoad"].id() if data["AppliedLoad"] else None
|
||||
data["AssignedToStructuralItem"] = None
|
||||
if activity.AssignedToStructuralItem:
|
||||
data["AssignedToStructuralItem"] = activity.AssignedToStructuralItem[0].RelatingElement.id()
|
||||
cls.structural_activities[activity.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_structural_connection(cls, product_id):
|
||||
connection = cls._file.by_id(product_id)
|
||||
data = connection.get_info()
|
||||
del data["OwnerHistory"]
|
||||
|
||||
data["ObjectPlacement"] = data["ObjectPlacement"].id() if data["ObjectPlacement"] is not None else None
|
||||
data["Representation"] = data["Representation"].id() if data["Representation"] is not None else None
|
||||
if connection.is_a("IfcStructuralCurveConnection"):
|
||||
data["Axis"] = data["Axis"].id() if data["Axis"] is not None else None
|
||||
if connection.is_a("IfcStructuralPointConnection"):
|
||||
data["ConditionCoordinateSystem"] = (
|
||||
data["ConditionCoordinateSystem"].id() if data["ConditionCoordinateSystem"] is not None else None
|
||||
)
|
||||
|
||||
data["ConnectsStructuralMembers"] = []
|
||||
|
||||
if connection.AppliedCondition:
|
||||
cls.load_boundary_condition(connection.AppliedCondition)
|
||||
data["AppliedCondition"] = connection.AppliedCondition.id()
|
||||
|
||||
for rel in connection.ConnectsStructuralMembers or []:
|
||||
cls.load_connects_structural_member(rel)
|
||||
data["ConnectsStructuralMembers"].append(rel.id())
|
||||
|
||||
cls.connections[connection.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_boundary_condition(cls, boundary_condition):
|
||||
data = boundary_condition.get_info()
|
||||
for key, value in data.items():
|
||||
if not value or key in ["Name", "type", "id"]:
|
||||
continue
|
||||
data[key] = value.wrappedValue
|
||||
cls.boundary_conditions[boundary_condition.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_connects_structural_member(cls, rel):
|
||||
rel_data = rel.get_info()
|
||||
del rel_data["OwnerHistory"]
|
||||
rel_data["RelatingStructuralMember"] = rel.RelatingStructuralMember.id()
|
||||
rel_data["RelatedStructuralConnection"] = rel.RelatedStructuralConnection.id()
|
||||
rel_data["ConditionCoordinateSystem"] = (
|
||||
rel_data["ConditionCoordinateSystem"].id() if rel_data["ConditionCoordinateSystem"] is not None else None
|
||||
) # TODO: consider orientation
|
||||
|
||||
if rel.is_a("IfcRelConnectsWithEccentricity"):
|
||||
rel_data["ConnectionConstraint"] = rel.ConnectionConstraint.id() # TODO
|
||||
|
||||
if rel.AppliedCondition:
|
||||
cls.load_boundary_condition(rel.AppliedCondition)
|
||||
rel_data["AppliedCondition"] = rel.AppliedCondition.id()
|
||||
|
||||
cls.connects_structural_members[rel.id()] = rel_data
|
||||
|
||||
@classmethod
|
||||
def load_structural_loads(cls):
|
||||
cls.structural_loads = {}
|
||||
for load in cls._file.by_type("IfcStructuralLoad"):
|
||||
cls.load_structural_load(load)
|
||||
|
||||
@classmethod
|
||||
def load_structural_load(cls, load):
|
||||
cls.structural_loads[load.id()] = load.get_info()
|
||||
|
||||
@classmethod
|
||||
def load_boundary_conditions(cls):
|
||||
cls.boundary_conditions = {}
|
||||
for bc in cls._file.by_type("IfcBoundaryCondition"):
|
||||
cls.load_boundary_condition(bc)
|
||||
|
||||
@classmethod
|
||||
def load_connects_structural_activity(cls, rel):
|
||||
rel_data = rel.get_info()
|
||||
del rel_data["OwnerHistory"]
|
||||
rel_data["RelatingElement"] = rel.RelatingElement.id()
|
||||
rel_data["RelatedStructuralActivity"] = rel.RelatedStructuralActivity.id()
|
||||
|
||||
if rel.RelatedStructuralActivity.AppliedLoad:
|
||||
cls.load_structural_load(rel.RelatedStructuralActivity.AppliedLoad)
|
||||
# rel_data["AppliedCondition"] = rel.RelatedStructuralActivity.AppliedLoad.id()
|
||||
|
||||
cls.connects_structural_activities[rel.id()] = rel_data
|
||||
|
||||
@classmethod
|
||||
def load_structural_member(cls, product_id):
|
||||
member = cls._file.by_id(product_id)
|
||||
data = member.get_info()
|
||||
|
||||
del data["OwnerHistory"]
|
||||
|
||||
data["ObjectPlacement"] = data["ObjectPlacement"].id() if data["ObjectPlacement"] is not None else None
|
||||
data["Representation"] = data["Representation"].id() if data["Representation"] is not None else None
|
||||
if member.is_a("IfcStructuralCurveMember"):
|
||||
data["Axis"] = data["Axis"].id() if data["Axis"] is not None else None
|
||||
|
||||
data["ConnectsStructuralActivities"] = []
|
||||
data["ConnectedBy"] = []
|
||||
|
||||
for activity in member.AssignedStructuralActivity or []:
|
||||
cls.load_connects_structural_activity(activity)
|
||||
data["ConnectsStructuralActivities"].append(activity.id())
|
||||
|
||||
for rel in member.ConnectedBy or []:
|
||||
cls.load_connects_structural_member(rel)
|
||||
data["ConnectedBy"].append(rel.id())
|
||||
|
||||
cls.members[member.id()] = data
|
||||
@@ -1,33 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
styles = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.styles = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, style_id):
|
||||
if not file:
|
||||
return
|
||||
data = file.by_id(style_id).get_info()
|
||||
data["Styles"] = [s.id() for s in data["Styles"]]
|
||||
cls.styles[style_id] = data
|
||||
@@ -1,43 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
products = {}
|
||||
systems = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.products = {}
|
||||
cls.systems = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
cls.products = {}
|
||||
cls.systems = {}
|
||||
for system in file.by_type("IfcSystem", include_subtypes=False):
|
||||
if system.IsGroupedBy:
|
||||
for rel in system.IsGroupedBy:
|
||||
for product in rel.RelatedObjects:
|
||||
cls.products.setdefault(product.id(), []).append(system.id())
|
||||
data = system.get_info()
|
||||
del data["OwnerHistory"]
|
||||
cls.systems[system.id()] = data
|
||||
cls.is_loaded = True
|
||||
@@ -1,68 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
types = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
cls.types = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
cls.file = file
|
||||
product = file.by_id(product_id)
|
||||
if product.is_a("IfcTypeObject"):
|
||||
cls.load_type(product_id)
|
||||
else:
|
||||
cls.load_product(product_id)
|
||||
|
||||
@classmethod
|
||||
def load_type(cls, product_id):
|
||||
product = cls.file.by_id(product_id)
|
||||
cls.types[product_id] = None
|
||||
if cls.file.schema == "IFC2X3":
|
||||
if getattr(product, "ObjectTypeOf", None):
|
||||
cls.types[product_id] = [o.id() for o in product.ObjectTypeOf[0].RelatedObjects]
|
||||
else:
|
||||
if getattr(product, "Types", None):
|
||||
cls.types[product_id] = [o.id() for o in product.Types[0].RelatedObjects]
|
||||
|
||||
@classmethod
|
||||
def load_product(cls, product_id):
|
||||
product = cls.file.by_id(product_id)
|
||||
if cls.file.schema == "IFC2X3" and not hasattr(product, "IsDefinedBy"):
|
||||
cls.products[product_id] = None
|
||||
elif cls.file.schema != "IFC2X3" and not hasattr(product, "IsTypedBy"):
|
||||
cls.products[product_id] = None
|
||||
elif hasattr(product, "IsTypedBy") and product.IsTypedBy:
|
||||
type = product.IsTypedBy[0].RelatingType
|
||||
cls.products[product_id] = {"type": type.is_a(), "Name": type.Name, "id": int(type.id())}
|
||||
elif hasattr(product, "IsDefinedBy") and product.IsDefinedBy:
|
||||
cls.products[product_id] = {"type": None, "Name": None}
|
||||
for rel in product.IsDefinedBy:
|
||||
if rel.is_a("IfcRelDefinesByType"):
|
||||
type = rel.RelatingType
|
||||
cls.products[product_id] = {"type": type.is_a(), "Name": type.Name, "id": int(type.id())}
|
||||
else:
|
||||
cls.products[product_id] = {"type": None, "Name": None, "id": None}
|
||||
@@ -1,72 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
units = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.unit_assignment = []
|
||||
cls.units = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file):
|
||||
if not file:
|
||||
return
|
||||
cls.file = file
|
||||
cls.unit_assignment = []
|
||||
cls.units = {}
|
||||
unit_assignment = cls.file.by_type("IfcUnitAssignment")
|
||||
if not unit_assignment:
|
||||
return
|
||||
for unit in unit_assignment[0].Units:
|
||||
cls.unit_assignment.append(unit.id())
|
||||
for unit in (
|
||||
cls.file.by_type("IfcDerivedUnit") + cls.file.by_type("IfcNamedUnit") + cls.file.by_type("IfcMonetaryUnit")
|
||||
):
|
||||
cls.load_unit(unit)
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_unit(cls, unit):
|
||||
if unit.is_a("IfcDerivedUnit"):
|
||||
data = unit.get_info()
|
||||
data["Elements"] = [{"Unit": e.Unit.id(), "Exponent": e.Exponent} for e in unit.Elements]
|
||||
for element in unit.Elements:
|
||||
cls.load_unit(element.Unit)
|
||||
cls.units[unit.id()] = data
|
||||
elif unit.is_a("IfcNamedUnit"):
|
||||
data = unit.get_info()
|
||||
if unit.is_a("IfcSIUnit"):
|
||||
data["Dimensions"] = ifcopenshell.util.unit.get_si_dimensions(unit.Name)
|
||||
else:
|
||||
data["Dimensions"] = unit.Dimensions.get_info()
|
||||
if unit.is_a("IfcConversionBasedUnit"):
|
||||
conversion_factor = unit.ConversionFactor.get_info()
|
||||
cls.load_unit(unit.ConversionFactor.UnitComponent)
|
||||
conversion_factor["UnitComponent"] = unit.ConversionFactor.UnitComponent.id()
|
||||
data["ConversionFactor"] = conversion_factor
|
||||
cls.units[unit.id()] = data
|
||||
elif unit.is_a("IfcMonetaryUnit"):
|
||||
cls.units[unit.id()] = unit.get_info()
|
||||
@@ -1,80 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
openings = {}
|
||||
fillings = {}
|
||||
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.products = {}
|
||||
cls.openings = {}
|
||||
cls.fillings = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, file, product_id):
|
||||
if not file:
|
||||
return
|
||||
cls.products[product_id] = set()
|
||||
if product_id in cls.fillings:
|
||||
del cls.fillings[product_id]
|
||||
product = file.by_id(product_id)
|
||||
for rel in file.by_type("IfcRelVoidsElement"):
|
||||
building_element = rel.RelatingBuildingElement
|
||||
if building_element != product:
|
||||
continue
|
||||
opening = rel.RelatedOpeningElement
|
||||
opening_id = int(opening.id())
|
||||
cls.products[product_id].add(opening_id)
|
||||
cls.openings[opening_id] = {"Name": opening.Name, "HasFillings": set()}
|
||||
for rel in file.by_type("IfcRelFillsElement"):
|
||||
opening = rel.RelatingOpeningElement
|
||||
opening_id = int(opening.id())
|
||||
filling = rel.RelatedBuildingElement
|
||||
filling_id = int(filling.id())
|
||||
|
||||
if filling_id == product_id and opening_id not in cls.openings:
|
||||
cls.openings[opening_id] = {"Name": opening.Name, "HasFillings": set()}
|
||||
|
||||
if opening_id not in cls.openings:
|
||||
continue
|
||||
|
||||
cls.fillings[filling_id] = {"Name": filling.Name, "FillsVoid": opening_id}
|
||||
cls.openings[opening_id]["HasFillings"].add(filling_id)
|
||||
return # See bug #1224
|
||||
# if not hasattr(product, "HasOpenings") or not product.HasOpenings:
|
||||
# return
|
||||
# for rel_voids_element in product.HasOpenings:
|
||||
# opening = rel_voids_element.RelatedOpeningElement
|
||||
# opening_id = int(opening.id())
|
||||
# fillings = []
|
||||
# if opening.HasFillings:
|
||||
# for rel_fills_element in opening.HasFillings:
|
||||
# filling = rel_fills_element.RelatedBuildingElement
|
||||
# filling_id = int(filling.id())
|
||||
# fillings.append(filling_id)
|
||||
# cls.fillings[filling_id] = {
|
||||
# "Name": filling.Name,
|
||||
# }
|
||||
# cls.openings[opening_id] = {
|
||||
# "Name": opening.Name,
|
||||
# "HasFillings": fillings,
|
||||
# }
|
||||
# cls.products[product_id].append(opening_id)
|
||||
Reference in New Issue
Block a user