mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 23:20:56 +00:00
Add per-property/quantity Unit-override support to edit_pset/edit_qto, plus unit-scale and candidate-unit helpers
edit_pset()'s unpack_unit_value() couldn't distinguish "no Unit dict was
passed" from "{"Unit": None, ...} passed to explicitly clear an existing
override" -- both collapsed to a bare None, and every consuming call site
checked truthiness, so there was no way to actually clear a previously-set
property Unit override once one existed. Fixed with a private _NO_UNIT
sentinel; bare (unwrapped) values still leave Unit untouched exactly as
before.
edit_qto() had no Unit-handling capability at all: neither
update_existing_property() nor add_new_properties() ever read or wrote a
quantity's Unit attribute. Added the same {"Unit": ..., "NominalValue": ...}
wrapped-dict convention edit_pset() already supports, disambiguated from
the pre-existing IfcPhysicalComplexQuantity dict convention
({"Discrimination": ..., "HasQuantities": ...}) by checking for a "Unit"
key -- a complex-quantity spec never contains one.
ifcopenshell.util.unit gains two small helpers:
- get_unit_scale(unit): dispatches to get_derived_unit_scale/
get_named_unit_scale depending on unit type, also used to de-duplicate
calculate_unit_scale()'s own inline dispatch of the same logic.
- get_candidate_units(ifc_file, unit_type): all units in a file matching a
given unit type, unlike get_project_unit()'s single-default lookup.
Adds regression tests for all of the above, including explicit-clear,
bare-value-preserves-override, and complex-quantity-routing-unaffected
cases.
This commit is contained in:
@@ -188,6 +188,36 @@ class TestEditPsetIFC2X3(test.bootstrap.IFC2X3):
|
||||
assert unit.Prefix == "GIGA"
|
||||
assert unit.Name == "PASCAL"
|
||||
|
||||
def test_explicitly_clearing_a_propertys_unit_override(self):
|
||||
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
custom_unit = self.file.createIfcSIUnit(UnitType="PRESSUREUNIT", Prefix="GIGA", Name="PASCAL")
|
||||
pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="Foo_Bar")
|
||||
ifcopenshell.api.pset.edit_pset(
|
||||
self.file, pset=pset, properties={"MyCustom": {"NominalValue": 30.0, "Unit": custom_unit}}
|
||||
)
|
||||
prop = pset.HasProperties[0]
|
||||
assert prop.Unit == custom_unit
|
||||
|
||||
ifcopenshell.api.pset.edit_pset(
|
||||
self.file, pset=pset, properties={"MyCustom": {"NominalValue": 40.0, "Unit": None}}
|
||||
)
|
||||
assert prop.Unit is None
|
||||
assert prop.NominalValue.wrappedValue == 40.0
|
||||
|
||||
def test_a_bare_value_does_not_disturb_an_existing_units_override(self):
|
||||
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
custom_unit = self.file.createIfcSIUnit(UnitType="PRESSUREUNIT", Prefix="GIGA", Name="PASCAL")
|
||||
pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="Foo_Bar")
|
||||
ifcopenshell.api.pset.edit_pset(
|
||||
self.file, pset=pset, properties={"MyCustom": {"NominalValue": 30.0, "Unit": custom_unit}}
|
||||
)
|
||||
prop = pset.HasProperties[0]
|
||||
assert prop.Unit == custom_unit
|
||||
|
||||
ifcopenshell.api.pset.edit_pset(self.file, pset=pset, properties={"MyCustom": 42.0})
|
||||
assert prop.Unit == custom_unit
|
||||
assert prop.NominalValue.wrappedValue == 42.0
|
||||
|
||||
def test_editing_properties_of_non_rooted_elements(self):
|
||||
element = self.file.createIfcMaterial()
|
||||
pset = ifcopenshell.api.pset.add_pset(self.file, product=element, name="Foo_Bar")
|
||||
|
||||
Reference in New Issue
Block a user