From 724003b89192e2415c9a8d8881c20e82f93e0131 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Mon, 3 Aug 2026 20:19:28 +0300 Subject: [PATCH 1/2] Docs: PartOf accepts predefinedType, note the rules --- Documentation/UserManual/partof-facet.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/UserManual/partof-facet.md b/Documentation/UserManual/partof-facet.md index 9930c89..a6ed0c4 100644 --- a/Documentation/UserManual/partof-facet.md +++ b/Documentation/UserManual/partof-facet.md @@ -20,6 +20,9 @@ When the `relation` parameter is not specified, then all 6 are to be considered | ------------ | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Entity** | ✔️ | An entity facet | Any valid IDS `entityType`, nested in the XML (e.g. "IFCSYSTEM"). The IFC class of the larger object matches the required entity. Expressed in UPPERCASE. | | **Relation** | ❌ | string | One relationship chosen from the 6 supported types listed above. If omitted any valid IFC relationship structure that directly or indirectly, and transitively (recursively) has to be evaluated, if specified only the given type must be evaluated (recursively). Expressed in UPPERCASE. | + +The nested entity is a full `entityType`, the same complex type the Entity facet uses, so it may also carry a `predefinedType`. The rules for resolving it are exactly those given in the [Entity facet](entity-facet.md#ifc-predefined-types), including the case where `predefinedType` is the literal string `USERDEFINED`, which matches the raw IFC `PredefinedType` attribute rather than the substituted `ObjectType` text. + ## 'Part Of' facet interpretation From 77d754f7e0d86eae129e875ef6bc6ebf800afb96 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Sun, 9 Aug 2026 19:11:27 +0300 Subject: [PATCH 2/2] Add PartOf USERDEFINED test fixtures --- ...defined_type_check_fails_a_user_defined_match.ifc | 12 ++++++++++++ ...defined_type_check_fails_a_user_defined_match.ifc | 12 ++++++++++++ ...defined_type_check_fails_a_user_defined_match.ifc | 12 ++++++++++++ ...redefined_type_may_specify_userdefined_itself.ifc | 12 ++++++++++++ ...redefined_type_may_specify_userdefined_itself.ifc | 12 ++++++++++++ ...redefined_type_may_specify_userdefined_itself.ifc | 12 ++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_container_predefined_type_check_fails_a_user_defined_match.ifc create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_default__no_relation__predefined_type_check_fails_a_user_defined_match.ifc create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_nest_predefined_type_check_fails_a_user_defined_match.ifc create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/pass-a_default__no_relation__predefined_type_may_specify_userdefined_itself.ifc create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/pass-the_container_predefined_type_may_specify_userdefined_itself.ifc create mode 100644 Documentation/ImplementersDocumentation/TestCases/partof/pass-the_nest_predefined_type_may_specify_userdefined_itself.ifc diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_container_predefined_type_check_fails_a_user_defined_match.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_container_predefined_type_check_fails_a_user_defined_match.ifc new file mode 100644 index 0000000..6df29a6 --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_container_predefined_type_check_fails_a_user_defined_match.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCELEMENTASSEMBLY('00nbHCClL84BXcPWQfXRvI',$,$,$,$,$,$,$,$,$); +#2=IFCSPACE('0xwFSABAn0aeKfluBB6QWK',$,$,$,'BURROW',$,$,$,$,.USERDEFINED.,$); +#3=IFCRELCONTAINEDINSPATIALSTRUCTURE('24Mj3buiH5QBBh$_6fgzTC',$,$,$,(#1),#2); +ENDSEC; +END-ISO-10303-21; diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_default__no_relation__predefined_type_check_fails_a_user_defined_match.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_default__no_relation__predefined_type_check_fails_a_user_defined_match.ifc new file mode 100644 index 0000000..ae91316 --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_default__no_relation__predefined_type_check_fails_a_user_defined_match.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCELEMENTASSEMBLY('3Z86Xmm6P6QPnwU3WHKg3Z',$,$,$,$,$,$,$,$,$); +#2=IFCSPACE('2T5DfVGyv2ORJtvHObj4n3',$,$,$,'BURROW',$,$,$,$,.USERDEFINED.,$); +#3=IFCRELCONTAINEDINSPATIALSTRUCTURE('0_eM7ap2LA8gQNHrpk42x7',$,$,$,(#1),#2); +ENDSEC; +END-ISO-10303-21; diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_nest_predefined_type_check_fails_a_user_defined_match.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_nest_predefined_type_check_fails_a_user_defined_match.ifc new file mode 100644 index 0000000..06aad3a --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/fail-a_prohibited_nest_predefined_type_check_fails_a_user_defined_match.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCFURNITURE('1RqA_N2aHESB6WMzZU5OnD',$,$,$,'WATERBOTTLE',$,$,$,.USERDEFINED.); +#2=IFCDISCRETEACCESSORY('1CODJQTNf8fgtBo8jyk$Je',$,$,$,$,$,$,$,$); +#3=IFCRELNESTS('3ZfTsF94L9Yv$EmT_jj0Pw',$,$,$,#1,(#2)); +ENDSEC; +END-ISO-10303-21; diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/pass-a_default__no_relation__predefined_type_may_specify_userdefined_itself.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/pass-a_default__no_relation__predefined_type_may_specify_userdefined_itself.ifc new file mode 100644 index 0000000..ae91316 --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/pass-a_default__no_relation__predefined_type_may_specify_userdefined_itself.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCELEMENTASSEMBLY('3Z86Xmm6P6QPnwU3WHKg3Z',$,$,$,$,$,$,$,$,$); +#2=IFCSPACE('2T5DfVGyv2ORJtvHObj4n3',$,$,$,'BURROW',$,$,$,$,.USERDEFINED.,$); +#3=IFCRELCONTAINEDINSPATIALSTRUCTURE('0_eM7ap2LA8gQNHrpk42x7',$,$,$,(#1),#2); +ENDSEC; +END-ISO-10303-21; diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_container_predefined_type_may_specify_userdefined_itself.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_container_predefined_type_may_specify_userdefined_itself.ifc new file mode 100644 index 0000000..6df29a6 --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_container_predefined_type_may_specify_userdefined_itself.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCELEMENTASSEMBLY('00nbHCClL84BXcPWQfXRvI',$,$,$,$,$,$,$,$,$); +#2=IFCSPACE('0xwFSABAn0aeKfluBB6QWK',$,$,$,'BURROW',$,$,$,$,.USERDEFINED.,$); +#3=IFCRELCONTAINEDINSPATIALSTRUCTURE('24Mj3buiH5QBBh$_6fgzTC',$,$,$,(#1),#2); +ENDSEC; +END-ISO-10303-21; diff --git a/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_nest_predefined_type_may_specify_userdefined_itself.ifc b/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_nest_predefined_type_may_specify_userdefined_itself.ifc new file mode 100644 index 0000000..06aad3a --- /dev/null +++ b/Documentation/ImplementersDocumentation/TestCases/partof/pass-the_nest_predefined_type_may_specify_userdefined_itself.ifc @@ -0,0 +1,12 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2026-08-09T19:08:45',(),(),'IfcOpenShell 0.8.5-1c5b825','IfcOpenShell 0.8.5-1c5b825',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCFURNITURE('1RqA_N2aHESB6WMzZU5OnD',$,$,$,'WATERBOTTLE',$,$,$,.USERDEFINED.); +#2=IFCDISCRETEACCESSORY('1CODJQTNf8fgtBo8jyk$Je',$,$,$,$,$,$,$,$); +#3=IFCRELNESTS('3ZfTsF94L9Yv$EmT_jj0Pw',$,$,$,#1,(#2)); +ENDSEC; +END-ISO-10303-21;