Skip to content

Commit c4a2144

Browse files
authored
Merge pull request #329 from buildingSMART/ivs99-ifc105-resource-entities-etc
IVS-99 IFC105 resource entities ...
2 parents 397dc9f + 9b17b80 commit c4a2144

9 files changed

+290
-13
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@IFC
2+
@version1
3+
@E00030
4+
@implementer-agreement
5+
Feature: IFC105 - Resource entities need to be referenced by rooted entity
6+
7+
The rule verifies that resource entities are directly or indirectly related to at least one rooted entity instance by means of forward or inverse attributes.
8+
Resource entities are the schema classes that do not inherit from IfcRoot, typically defined in the resource layer of the schema (e.g Geometry Resource).
9+
10+
Scenario: Resource entities need to be referenced by rooted entity
11+
12+
Given a traversal over the full model originating from subtypes of IfcRoot
13+
Given an entity instance
14+
Given its entity type is not 'IfcRoot'
15+
Then it must be referenced by an entity instance inheriting from IfcRoot directly or indirectly

features/steps/givens/attributes.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import ast
2+
import functools
23
import operator
34

45
import ifcopenshell
@@ -147,6 +148,34 @@ def step_impl(context, file_or_model, field, values):
147148
context.applicable = getattr(context, 'applicable', True) and applicable
148149

149150

151+
@gherkin_ifc.step('a traversal over the full model originating from subtypes of {entity}')
152+
def step_impl(context, entity):
153+
WHITELISTED_INVERSES = {'StyledByItem', 'HasCoordinateOperation'}
154+
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(context.model.schema_identifier)
155+
@functools.cache
156+
def names(entity_type):
157+
decl = schema.declaration_by_name(entity_type)
158+
if isinstance(decl, ifcopenshell.ifcopenshell_wrapper.entity):
159+
non_derived_forward_attributes = map(operator.itemgetter(1), filter(lambda t: not t[0], zip(decl.derived(), decl.all_attributes())))
160+
whitelisted_inverse_attributes = filter(lambda attr: attr.name() in WHITELISTED_INVERSES, decl.all_inverse_attributes())
161+
return {a.name() for a in [*non_derived_forward_attributes, *whitelisted_inverse_attributes]}
162+
else:
163+
return set()
164+
165+
visited = set()
166+
def visit(inst, path=None):
167+
if inst in visited:
168+
return
169+
visited.add(inst)
170+
for attr in names(inst.is_a()):
171+
for ref in filter(lambda inst: isinstance(inst, ifcopenshell.entity_instance), misc.iflatten(getattr(inst, attr))):
172+
visit(ref, (path or ()) + (inst, attr,))
173+
174+
for inst in context.model.by_type(entity):
175+
visit(inst)
176+
177+
context.visited_instances = visited
178+
150179
@gherkin_ifc.step('Its attribute {attribute}')
151180
def step_impl(context, inst, attribute, tail="single"):
152181
yield ValidationOutcome(instance_id=getattr(inst, attribute, None), severity=OutcomeSeverity.PASSED)

features/steps/givens/entities.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@
2020
def step_impl(context, entity_opt_stmt, insts=False):
2121
within_model = (insts == 'instances') # True for given statement containing {insts}
2222

23-
entity2 = pyparsing.Word(pyparsing.alphas)('entity')
24-
sub_stmts = ['with subtypes', 'without subtypes', pyparsing.LineEnd()]
25-
incl_sub_stmt = functools.reduce(operator.or_, [misc.rtrn_pyparse_obj(i) for i in sub_stmts])('include_subtypes')
26-
grammar = entity2 + incl_sub_stmt
27-
parse = grammar.parseString(entity_opt_stmt)
28-
entity = parse['entity']
29-
include_subtypes = misc.do_try(lambda: not 'without' in parse['include_subtypes'], True)
30-
31-
instances = context.model.by_type(entity, include_subtypes) or []
23+
if entity_opt_stmt == "entity instance":
24+
instances = list(context.model)
25+
else:
26+
entity2 = pyparsing.Word(pyparsing.alphas)('entity')
27+
sub_stmts = ['with subtypes', 'without subtypes', pyparsing.LineEnd()]
28+
incl_sub_stmt = functools.reduce(operator.or_, [misc.rtrn_pyparse_obj(i) for i in sub_stmts])('include_subtypes')
29+
grammar = entity2 + incl_sub_stmt
30+
parse = grammar.parseString(entity_opt_stmt)
31+
entity = parse['entity']
32+
include_subtypes = misc.do_try(lambda: not 'without' in parse['include_subtypes'], True)
33+
instances = context.model.by_type(entity, include_subtypes) or []
3234

3335
context.within_model = getattr(context, 'within_model', True) and within_model
3436
if instances:

features/steps/thens/relations.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,13 @@ def schema_has_declaration_name(s):
388388
# @tfk not sure about this one, but for now empty values on a property are probably
389389
# not a universal error. This is more IDS territory.
390390
# if not values:
391-
# yield ValidationOutcome(inst=inst, expected= {"oneOf": accepted_data_type['instance']}, observed = {'value':None}, severity=OutcomeSeverity.ERROR)
391+
# yield ValidationOutcome(inst=inst, expected= {"oneOf": accepted_data_type['instance']}, observed = {'value':None}, severity=OutcomeSeverity.ERROR)
392+
393+
@gherkin_ifc.step('it must be referenced by an entity instance inheriting from IfcRoot directly or indirectly')
394+
def step_impl(context, inst):
395+
# context.visited_instances is set in the gherkin statement:
396+
# 'Given a traversal over the full model originating from subtypes of IfcRoot'
397+
assert hasattr(context, 'visited_instances')
398+
399+
if inst not in context.visited_instances:
400+
yield ValidationOutcome(inst=inst, severity=OutcomeSeverity.ERROR)

features/steps/utils/misc.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ def recursive_flatten(lst):
3131
return flattened_list
3232

3333

34+
def iflatten(any):
35+
if isinstance(any, (tuple, list)):
36+
for v in any:
37+
yield from iflatten(v)
38+
else:
39+
yield any
40+
41+
3442
def do_try(fn, default=None):
3543
try:
3644
return fn()

features/steps/validation_handling.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,9 @@ class SubtypeHandling(Enum):
6666

6767
def generate_error_message(context, errors):
6868
"""
69-
Function to trigger the behave error mechanism so that the JSON output is generated correctly.
70-
Miscellaneous errors also are also printed to the console this way.
69+
Function to trigger the behave error mechanism by raising an exception so that errors are printed to the console.
7170
"""
72-
assert not errors, "Behave errors occured:\n{}".format([str(error) for error in errors])
71+
assert not errors, "Errors occured:" + ''.join(f'\n - {error}' for error in errors)
7372

7473

7574
"""
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
ISO-10303-21;
2+
HEADER;
3+
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
4+
FILE_NAME('','2022-11-08T16:54:40',(''),(''),'IfcOpenShell-v0.7.0-fa6bbf2d','IfcOpenShell-v0.7.0-fa6bbf2d','');
5+
FILE_SCHEMA(('IFC2X3'));
6+
ENDSEC;
7+
DATA;
8+
#1=IFCPERSON($,$,'',$,$,$,$,$);
9+
#2=IFCORGANIZATION($,'',$,$,$);
10+
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
11+
#4=IFCAPPLICATION(#2,'v0.7.0-fa6bbf2d','IfcOpenShell-v0.7.0-fa6bbf2d','');
12+
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,1667926480);
13+
#6=IFCDIRECTION((1.,0.,0.));
14+
#7=IFCDIRECTION((0.,0.,1.));
15+
#8=IFCCARTESIANPOINT((0.,0.,0.));
16+
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
17+
#10=IFCDIRECTION((0.,1.,0.));
18+
#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10);
19+
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
20+
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
21+
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
22+
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
23+
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
24+
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
25+
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
26+
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
27+
#20=IFCPROJECT('3KwPrT3OP4Gg7qpalgQO1_',#5,'',$,$,$,$,(#11),#19);
28+
#21=IFCCARTESIANPOINT((0.,0.,0.));
29+
#22=IFCDIRECTION((0.,0.,1.));
30+
#23=IFCDIRECTION((1.,0.,0.));
31+
#24=IFCAXIS2PLACEMENT3D(#21,#22,#23);
32+
#25=IFCLOCALPLACEMENT($,#24);
33+
#26=IFCSITE('098$knNuOHxPTbB6t11Jwi',#5,'Site',$,$,#25,$,$,.ELEMENT.,$,$,$,$,$);
34+
#27=IFCCARTESIANPOINT((0.,0.,0.));
35+
#28=IFCDIRECTION((0.,0.,1.));
36+
#29=IFCDIRECTION((1.,0.,0.));
37+
#30=IFCAXIS2PLACEMENT3D(#27,#28,#29);
38+
#31=IFCLOCALPLACEMENT(#25,#30);
39+
#32=IFCBUILDING('098$koNuOHxPGoB6t11Jwi',#5,'Building',$,$,#31,$,$,.ELEMENT.,$,$,$);
40+
#33=IFCCARTESIANPOINT((0.,0.,0.));
41+
#34=IFCDIRECTION((0.,0.,1.));
42+
#35=IFCDIRECTION((1.,0.,0.));
43+
#36=IFCAXIS2PLACEMENT3D(#33,#34,#35);
44+
#37=IFCLOCALPLACEMENT(#31,#36);
45+
#38=IFCBUILDINGSTOREY('098$kpNuOHxQvuB6t11Jwi',#5,'Storey',$,$,#37,$,$,.ELEMENT.,0.);
46+
#39=IFCRELAGGREGATES('098$kqNuOHxRbKB6t11Jwi',#5,'Building Container',$,#32,(#38));
47+
#40=IFCRELAGGREGATES('098$krNuOHxQdqB6t11Jwi',#5,'Site Container',$,#26,(#32));
48+
#41=IFCRELAGGREGATES('098$ksNuOHxO9OB6t11Jwi',#5,'Project Container',$,#20,(#26));
49+
#42=IFCCARTESIANPOINT((0.,0.,0.));
50+
#43=IFCDIRECTION((0.,0.,1.));
51+
#44=IFCDIRECTION((1.,0.,0.));
52+
#45=IFCAXIS2PLACEMENT3D(#42,#43,#44);
53+
#47=IFCCARTESIANPOINT((0.,0.,0.));
54+
#48=IFCCARTESIANPOINT((5.,0.,0.));
55+
#49=IFCPOLYLINE((#47,#48));
56+
#50=IFCCARTESIANPOINT((0.,0.,0.));
57+
#51=IFCDIRECTION((0.,0.,1.));
58+
#52=IFCDIRECTION((1.,0.,0.));
59+
#53=IFCAXIS2PLACEMENT3D(#50,#51,#52);
60+
#54=IFCCARTESIANPOINT((0.,-0.1));
61+
#55=IFCCARTESIANPOINT((5.,-0.1));
62+
#56=IFCCARTESIANPOINT((10.,0.1));
63+
#57=IFCCARTESIANPOINT((0.,0.1));
64+
#58=IFCCARTESIANPOINT((0.,-0.1));
65+
#59=IFCPOLYLINE((#54,#55,#56,#57,#58));
66+
#60=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#59);
67+
#61=IFCDIRECTION((0.,0.,1.));
68+
#62=IFCEXTRUDEDAREASOLID(#60,#53,#61,3.);
69+
#63=IFCSHAPEREPRESENTATION(#11,'Body','SweptSolid',(#62));
70+
#64=IFCREPRESENTATIONMAP(#53,#63);
71+
ENDSEC;
72+
END-ISO-10303-21;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
ISO-10303-21;
2+
HEADER;
3+
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
4+
FILE_NAME('','2022-11-08T16:54:40',(''),(''),'IfcOpenShell-v0.7.0-fa6bbf2d','IfcOpenShell-v0.7.0-fa6bbf2d','');
5+
FILE_SCHEMA(('IFC2X3'));
6+
ENDSEC;
7+
DATA;
8+
#1=IFCPERSON($,$,'',$,$,$,$,$);
9+
#2=IFCORGANIZATION($,'',$,$,$);
10+
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
11+
#4=IFCAPPLICATION(#2,'v0.7.0-fa6bbf2d','IfcOpenShell-v0.7.0-fa6bbf2d','');
12+
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,1667926480);
13+
#6=IFCDIRECTION((1.,0.,0.));
14+
#7=IFCDIRECTION((0.,0.,1.));
15+
#8=IFCCARTESIANPOINT((0.,0.,0.));
16+
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
17+
#10=IFCDIRECTION((0.,1.,0.));
18+
#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10);
19+
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
20+
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
21+
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
22+
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
23+
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
24+
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
25+
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
26+
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
27+
#20=IFCPROJECT('3KwPrT3OP4Gg7qpalgQO1_',#5,'',$,$,$,$,(#11),#19);
28+
#21=IFCCARTESIANPOINT((0.,0.,0.));
29+
#22=IFCDIRECTION((0.,0.,1.));
30+
#23=IFCDIRECTION((1.,0.,0.));
31+
#24=IFCAXIS2PLACEMENT3D(#21,#22,#23);
32+
#25=IFCLOCALPLACEMENT($,#24);
33+
#26=IFCSITE('098$knNuOHxPTbB6t11Jwi',#5,'Site',$,$,#25,$,$,.ELEMENT.,$,$,$,$,$);
34+
#27=IFCCARTESIANPOINT((0.,0.,0.));
35+
#28=IFCDIRECTION((0.,0.,1.));
36+
#29=IFCDIRECTION((1.,0.,0.));
37+
#30=IFCAXIS2PLACEMENT3D(#27,#28,#29);
38+
#31=IFCLOCALPLACEMENT(#25,#30);
39+
#32=IFCBUILDING('098$koNuOHxPGoB6t11Jwi',#5,'Building',$,$,#31,$,$,.ELEMENT.,$,$,$);
40+
#33=IFCCARTESIANPOINT((0.,0.,0.));
41+
#34=IFCDIRECTION((0.,0.,1.));
42+
#35=IFCDIRECTION((1.,0.,0.));
43+
#36=IFCAXIS2PLACEMENT3D(#33,#34,#35);
44+
#37=IFCLOCALPLACEMENT(#31,#36);
45+
#38=IFCBUILDINGSTOREY('098$kpNuOHxQvuB6t11Jwi',#5,'Storey',$,$,#37,$,$,.ELEMENT.,0.);
46+
#39=IFCRELAGGREGATES('098$kqNuOHxRbKB6t11Jwi',#5,'Building Container',$,#32,(#38));
47+
#40=IFCRELAGGREGATES('098$krNuOHxQdqB6t11Jwi',#5,'Site Container',$,#26,(#32));
48+
#41=IFCRELAGGREGATES('098$ksNuOHxO9OB6t11Jwi',#5,'Project Container',$,#20,(#26));
49+
#4100=IFCRELAGGREGATES('098$ksNuOHxO9OB6t11Jwj',#5,'Storey Container',$,#38,(#65));
50+
#42=IFCCARTESIANPOINT((0.,0.,0.));
51+
#43=IFCDIRECTION((0.,0.,1.));
52+
#44=IFCDIRECTION((1.,0.,0.));
53+
#45=IFCAXIS2PLACEMENT3D(#42,#43,#44);
54+
#46=IFCLOCALPLACEMENT(#37,#45);
55+
#50=IFCCARTESIANPOINT((0.,0.,0.));
56+
#51=IFCDIRECTION((0.,0.,1.));
57+
#52=IFCDIRECTION((1.,0.,0.));
58+
#53=IFCAXIS2PLACEMENT3D(#50,#51,#52);
59+
#54=IFCCARTESIANPOINT((0.,-0.1));
60+
#55=IFCCARTESIANPOINT((5.,-0.1));
61+
#56=IFCCARTESIANPOINT((10.,0.1));
62+
#57=IFCCARTESIANPOINT((0.,0.1));
63+
#58=IFCCARTESIANPOINT((0.,-0.1));
64+
#59=IFCPOLYLINE((#54,#55,#56,#57,#58));
65+
#60=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#59);
66+
#61=IFCDIRECTION((0.,0.,1.));
67+
#62=IFCEXTRUDEDAREASOLID(#60,#53,#61,3.);
68+
#63=IFCSHAPEREPRESENTATION(#11,'Body','SweptSolid',(#62));
69+
#64=IFCPRODUCTDEFINITIONSHAPE($,$,(#63));
70+
#65=IFCSPACE('098$ktNuOHxOUOB6t11Jwi',#5,'space','An awesome space',$,#46,#64,$,.ELEMENT.,.INTERNAL.,$);
71+
ENDSEC;
72+
END-ISO-10303-21;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
ISO-10303-21;
2+
HEADER;
3+
4+
FILE_DESCRIPTION(
5+
/* description */ ('GeoReference'),
6+
/* implementation level */ '2;1');
7+
FILE_NAME(
8+
/* name */ 'pass-ifc105-with_referencing.ifc',
9+
/* time_stamp */ '2017-07-10T15:03:00',
10+
/* author */ ('redacted'),
11+
/* organization */ ('redacted'),
12+
/* preprocessor_version */ 'redacted',
13+
/* originating_system */ '',
14+
/* authorisation */ 'none');
15+
16+
FILE_SCHEMA (('IFC4X3_ADD2'));
17+
ENDSEC;
18+
DATA;
19+
/* Geographic reference*/
20+
#1= IFCPROJECTEDCRS('EPSG:31467','DHDN / 3-Degree Gauss-Krueger Zone 3','ETRS89',$,'Gaus-Krueger','3',#3);
21+
#2= IFCMAPCONVERSION(#100011,#1,3458715.92,5439966.65,113.7,0.270600445976,0.962691746426,$);
22+
#3= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
23+
24+
25+
/* BuildingElementProxy */
26+
#149= IFCBUILDINGELEMENTPROXY('0rBru4syGxGOZb$M8kVJuS',#100005,'Geographic Position',$,$,#121,#5037,$,$);
27+
#121= IFCLOCALPLACEMENT(#5044,#243);
28+
#243= IFCAXIS2PLACEMENT3D(#173,#217,#218);
29+
#173= IFCCARTESIANPOINT((0.,0.,0.));
30+
#217= IFCDIRECTION((0.,0.,1.));
31+
#218= IFCDIRECTION((1.,0.,0.));
32+
#5037= IFCPRODUCTDEFINITIONSHAPE('',$,(#5038));
33+
#5038= IFCSHAPEREPRESENTATION(#100011,'Body','Tessellation',(#5000));
34+
/* Tesselated geometry */
35+
#5000= IFCTRIANGULATEDFACESET(#5001,$,.T.,((1,3,2),(1,4,3),(1,5,4),(1,2,5),/*(2,3,4),(4,5,2),*/(2,3,6),(3,7,6),(3,4,7),(4,8,7),(4,5,8),(5,9,8),(5,2,9),(2,6,9),(6,7,8),(6,8,9)),$);
36+
#5001= IFCCARTESIANPOINTLIST3D(((0.0,0.0,0.0),(-500.0,-500.0,2000.0),(500.0,-500.0,2000.0),(500.0,500.0,2000.0),(-500.0,500.0,2000.0),(-500.0,-500.0,4000.0),(500.0,-500.0,4000.0),(500.0,500.0,4000.0),(-500.0,500.0,4000.0)),$);
37+
/* BuildingStorey */
38+
#5043= IFCBUILDINGSTOREY('3_fv_WeK63IPclwapZa9MD',#100005,'Storey 1',$,$,#5044,$,$,.ELEMENT.,0.);
39+
#5044= IFCLOCALPLACEMENT(#100025,#100040);
40+
#5045= IFCRELCONTAINEDINSPATIALSTRUCTURE('2lLFgu3KhSGw4jMC3$Ak50',#100005,'Storey 1',$,(#149),#5043);
41+
#5046= IFCRELAGGREGATES('3INy2PAPGPJ8Dpwhrq610o',#100005,'All stories',$,#100023,(#5043));
42+
/* Person, Org, App, Project */
43+
44+
#100001= IFCPERSON($,'redacted',$,$,$,$,$,$);
45+
#100002= IFCORGANIZATION($,'redacted',$,$,$);
46+
#100003= IFCPERSONANDORGANIZATION(#100001,#100002,$);
47+
#100004= IFCAPPLICATION(#100002,'redacted','redacted','redacted');
48+
#100005= IFCOWNERHISTORY(#100003,#100004,$,.NOTDEFINED.,$,$,$,1122650864);
49+
#100010= IFCPROJECT('01JwSt5ycUHvKFlMZUleKS',#100005,'Notch',$,$,$,$,(#100011),#100060);
50+
#100011= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.0E-5,#100040,$);
51+
/* Site */
52+
#100020= IFCSITE('1BPCQAtTW7GhKrUF$Sytrr',#100005,'Site',$,$,#100022,$,$,.ELEMENT.,(49,5,43,983700),(8,26,1,247300),113.7,$,$);
53+
#100021= IFCRELAGGREGATES('2vOmTZNmbvJAJRbSGMMNrC',#100005,$,$,#100010,(#100020));
54+
#100022= IFCLOCALPLACEMENT($,#100040);
55+
/* Building */
56+
#100023= IFCBUILDING('0cVTYHAI3nGeTXA2X4Gxyo',#100005,'Building',$,$,#100025,$,$,.ELEMENT.,$,$,$);
57+
#100024= IFCRELAGGREGATES('1F_GRhxz1GJgGgcJgzjvKX',#100005,$,$,#100020,(#100023));
58+
#100025= IFCLOCALPLACEMENT(#100022,#100040);
59+
/* Placement */
60+
#100040= IFCAXIS2PLACEMENT3D(#100041,#100044,#100042);
61+
#100041= IFCCARTESIANPOINT((0.,0.,0.));
62+
#100042= IFCDIRECTION((1.,0.,0.));
63+
#100044= IFCDIRECTION((0.,0.,1.));
64+
/* Units */
65+
#100060= IFCUNITASSIGNMENT((#100061,#100062,#100063,#100064));
66+
#100061= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
67+
#100062= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
68+
#100063= IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
69+
#100064= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
70+
ENDSEC;
71+
END-ISO-10303-21;

0 commit comments

Comments
 (0)