diff --git a/src/blenderbim/blenderbim/bim/module/resource/prop.py b/src/blenderbim/blenderbim/bim/module/resource/prop.py
index 8f5f3df6b2..08a6a480ce 100644
--- a/src/blenderbim/blenderbim/bim/module/resource/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/resource/prop.py
@@ -41,20 +41,7 @@ quantitytypes_enum = {}
def setup_quantity_types_enum():
- # https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcConstructionResource.htm#Table-7.3.3.7.1.3.H
- resources = {
- "IfcCrewResource": ("IfcQuantityTime",),
- "IfcLaborResource": ("IfcQuantityTime",),
- "IfcSubContractResource": ("IfcQuantityTime",),
- "IfcConstructionEquipmentResource": ("IfcQuantityTime",),
- "IfcConstructionMaterialResource": (
- "IfcQuantityVolume",
- "IfcQuantityArea",
- "IfcQuantityLength",
- "IfcQuantityWeight",
- ),
- "IfcConstructionProductResource": ("IfcQuantityCount",),
- }
+ resources = ifcopenshell.util.resource.RESOURCES_TO_QUANTITIES
for resource, quantities in resources.items():
quantitytypes_enum[resource] = [(q, q, "") for q in quantities]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource_quantity.py b/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource_quantity.py
index 8d3d6de9e9..72eb582af6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource_quantity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource_quantity.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell.util.element
+import ifcopenshell.util.resource
def add_resource_quantity(
@@ -66,6 +67,14 @@ def add_resource_quantity(
"""
settings = {"resource": resource, "ifc_class": ifc_class}
+ resource_type = resource.is_a()
+ supported_quantities = ifcopenshell.util.resource.RESOURCES_TO_QUANTITIES[resource_type]
+ if ifc_class not in supported_quantities:
+ raise ValueError(
+ f"Resource type '{resource_type}' does not support quantity type '{ifc_class}'. "
+ f"Supported quantities: {','.join(supported_quantities)}"
+ )
+
quantity = file.create_entity(settings["ifc_class"], Name="Unnamed")
# 3 IfcPhysicalSimpleQuantity Value
if settings["ifc_class"] == "IfcQuantityCount":
diff --git a/src/ifcopenshell-python/ifcopenshell/util/resource.py b/src/ifcopenshell-python/ifcopenshell/util/resource.py
index bfc1aabed6..adce5bfa3f 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/resource.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/resource.py
@@ -23,6 +23,20 @@ from typing import Union, Any
PRODUCTIVITY_PSET_DATA = Union[dict[str, Any], None]
+# https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcConstructionResource.htm#Table-7.3.3.7.1.3.H
+RESOURCES_TO_QUANTITIES: dict[str, tuple[str, ...]] = {
+ "IfcCrewResource": ("IfcQuantityTime",),
+ "IfcLaborResource": ("IfcQuantityTime",),
+ "IfcSubContractResource": ("IfcQuantityTime",),
+ "IfcConstructionEquipmentResource": ("IfcQuantityTime",),
+ "IfcConstructionMaterialResource": (
+ "IfcQuantityVolume",
+ "IfcQuantityArea",
+ "IfcQuantityLength",
+ "IfcQuantityWeight",
+ ),
+ "IfcConstructionProductResource": ("IfcQuantityCount",),
+}
def get_productivity(resource: ifcopenshell.entity_instance, should_inherit: bool = True) -> PRODUCTIVITY_PSET_DATA:
diff --git a/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py b/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
index bde9451d11..e843e5828b 100644
--- a/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
+++ b/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
@@ -16,27 +16,45 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import pytest
import test.bootstrap
import ifcopenshell.api
+import ifcopenshell.api.resource
+import ifcopenshell.util.resource
class TestAddResourceQuantity(test.bootstrap.IFC4):
def test_run(self):
schema = ifcopenshell.schema_by_name(self.file.schema)
quantity_types = [t.name() for t in schema.declaration_by_name("IfcPhysicalSimpleQuantity").subtypes()]
- self.file.create_entity("IfcProject") # add_resource
- resource = ifcopenshell.api.run("resource.add_resource", self.file, ifc_class="IfcCrewResource")
+ resource_types = [t.name() for t in schema.declaration_by_name("IfcConstructionResource").subtypes()]
- for quantity_type in quantity_types:
- quantity = ifcopenshell.api.run(
- "resource.add_resource_quantity", self.file, resource=resource, ifc_class=quantity_type
- )
- assert quantity.is_a(quantity_type)
- assert quantity.Name == "Unnamed"
- assert quantity[3] == 0.0
- # previous quantity is reassigned and removed
- assert resource.BaseQuantity == quantity
- assert len(self.file.by_type("IfcPhysicalSimpleQuantity")) == 1
+ self.file.create_entity("IfcProject") # add_resource
+
+ for resource_type in resource_types:
+ resource = ifcopenshell.api.resource.add_resource(self.file, ifc_class=resource_type)
+ available_quantities = ifcopenshell.util.resource.RESOURCES_TO_QUANTITIES[resource_type]
+
+ for quantity_type in quantity_types:
+ if quantity_type not in available_quantities:
+ with pytest.raises(ValueError):
+ quantity = ifcopenshell.api.resource.add_resource_quantity(
+ self.file, resource=resource, ifc_class=quantity_type
+ )
+ continue
+ else:
+ quantity = ifcopenshell.api.resource.add_resource_quantity(
+ self.file, resource=resource, ifc_class=quantity_type
+ )
+
+ assert quantity.is_a(quantity_type)
+ assert quantity.Name == "Unnamed"
+ assert quantity[3] == 0.0
+ # previous quantity is reassigned and removed
+ assert resource.BaseQuantity == quantity
+ assert len(self.file.by_type("IfcPhysicalSimpleQuantity")) == 1
+
+ ifcopenshell.api.resource.remove_resource(self.file, resource)
class TestAddResourceQuantityIFC2X3(test.bootstrap.IFC2X3, TestAddResourceQuantity):