mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
unblock voxel schema loading, add test for express
This commit is contained in:
committed by
Thomas Krijnen
parent
53c2ddbb47
commit
ab73550059
@@ -420,7 +420,13 @@ class SchemaClass(codegen.Base):
|
||||
|
||||
if isinstance(type, nodes.AggregationType):
|
||||
aggr_type = type.aggregate_type
|
||||
make_bound = lambda b: -1 if b == "?" else int(b)
|
||||
def make_bound(b):
|
||||
# `?` and non-literal bounds (attribute references, arithmetic expressions) collapse to -1.
|
||||
#
|
||||
try:
|
||||
return int(b)
|
||||
except (TypeError, ValueError):
|
||||
return -1
|
||||
bound1, bound2 = map(make_bound, (type.bounds.lower, type.bounds.upper))
|
||||
decl_type = get_declared_type(type.type, emitted_names)
|
||||
return x.aggregation_type(aggr_type, bound1, bound2, decl_type)
|
||||
@@ -547,7 +553,14 @@ class SchemaClass(codegen.Base):
|
||||
inv_attrs = []
|
||||
for attr in type.inverse:
|
||||
if attr.bounds:
|
||||
make_bound = lambda b: -1 if b == "?" else int(b)
|
||||
def make_bound(b):
|
||||
# `?` and non-literal bounds (attribute references, arithmetic
|
||||
# expressions) collapse to -1 (unbounded) — the C++ runtime has
|
||||
# no third state for "dynamic cardinality".
|
||||
try:
|
||||
return int(b)
|
||||
except (TypeError, ValueError):
|
||||
return -1
|
||||
bound1, bound2 = map(make_bound, (attr.bounds.lower, attr.bounds.upper))
|
||||
else:
|
||||
bound1, bound2 = -1, -1
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import ifcopenshell.express
|
||||
|
||||
sys.path.insert(0, os.path.dirname(ifcopenshell.express.__file__))
|
||||
|
||||
|
||||
def _parse(schema_text):
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".exp", delete=False) as f:
|
||||
f.write(schema_text)
|
||||
path = f.name
|
||||
try:
|
||||
return ifcopenshell.express.parse(path)
|
||||
finally:
|
||||
os.unlink(path)
|
||||
cache = path + ".cache.dat"
|
||||
if os.path.exists(cache):
|
||||
os.unlink(cache)
|
||||
|
||||
|
||||
class TestAggregateBounds(unittest.TestCase):
|
||||
def test_literal_bounds_preserved(self):
|
||||
"""After loading [1;3] -> (1, 3)?"""
|
||||
s = _parse(
|
||||
"SCHEMA t; ENTITY E; v : ARRAY [1:3] OF REAL; END_ENTITY; END_SCHEMA;"
|
||||
)
|
||||
agg = (
|
||||
next(d for d in s.schema.declarations() if d.name() == "E")
|
||||
.attributes()[0]
|
||||
.type_of_attribute()
|
||||
.as_aggregation_type()
|
||||
)
|
||||
self.assertEqual((agg.bound1(), agg.bound2()), (1, 3))
|
||||
s.disown()
|
||||
|
||||
def test_unbounded_marker(self):
|
||||
""" [0:?] -> (0, -1)?"""
|
||||
s = _parse(
|
||||
"SCHEMA t; ENTITY E; v : LIST [0:?] OF REAL; END_ENTITY; END_SCHEMA;"
|
||||
)
|
||||
agg = (
|
||||
next(d for d in s.schema.declarations() if d.name() == "E")
|
||||
.attributes()[0]
|
||||
.type_of_attribute()
|
||||
.as_aggregation_type()
|
||||
)
|
||||
# import pdb; pdb.set_trace()
|
||||
self.assertEqual((agg.bound1(), agg.bound2()), (0, -1))
|
||||
s.disown()
|
||||
|
||||
def test_voxel_grid_with_dynamic_bound_loads(self):
|
||||
"""
|
||||
Array that is an expression : [1:dim_x*dim_y*dim_z]
|
||||
Parsing must not crash, Bbund must be (1, -1)
|
||||
"""
|
||||
s = _parse(
|
||||
"""
|
||||
SCHEMA t;
|
||||
TYPE IfcBoolean = BOOLEAN; END_TYPE;
|
||||
|
||||
ENTITY IfcVoxelHolder;
|
||||
NumberOfVoxelsX : INTEGER;
|
||||
NumberOfVoxelsY : INTEGER;
|
||||
NumberOfVoxelsZ : INTEGER;
|
||||
Voxels : ARRAY [1:NumberOfVoxelsX*NumberOfVoxelsY*NumberOfVoxelsZ] OF IfcBoolean;
|
||||
END_ENTITY;
|
||||
END_SCHEMA;
|
||||
"""
|
||||
)
|
||||
holder = next(d for d in s.schema.declarations() if d.name() == "IfcVoxelHolder")
|
||||
voxels = holder.attributes()[-1].type_of_attribute().as_aggregation_type()
|
||||
self.assertEqual((voxels.bound1(), voxels.bound2()), (1, -1))
|
||||
s.disown()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user