Docs: PartOf accepts predefinedType, which the page never mentions - #450
Docs: PartOf accepts predefinedType, which the page never mentions#450BIMvoice wants to merge 2 commits into
Conversation
|
Following up on the test-suite gap, because it turns out to cost nothing. I said we would be happy to contribute the missing PartOf
basename = f"{result}-" + re.sub("[^0-9a-zA-Z]", "_", name.lower())
ifc.write(os.path.join(outdir, "testcases", self.facet, f"{basename}.ifc"))So the existing suite is generated from IfcTester's own tests, which is exactly why the gap existed: Our fix (IfcOpenShell#9203) adds assertions covering all six PartOf relation branches, both directions each: Regenerating after that merges produces the corresponding Worth noting the Nothing needed from you on this beyond the documentation change in this PR. Flagging it so you know the suite gap closes on its own rather than needing a separate contribution. |
|
Correcting my own comment above, which was wrong. I said the conformance test cases are generated from IfcTester's @andyward pointed this out on #283: the So the offer in that comment does not hold as written. If the PartOf Apologies for the noise. The documentation change in this PR is unaffected. |
|
@BIMvoice, |
|
@CBenghi Done, pushed as
Each pass and fail file in a pair is deliberately identical content, matching how the existing prohibited pairs in that directory share a model. The custom All six verified functionally with the fixed IfcTester: required passes, prohibited fails. And to confirm the fail cases test what they claim, the three prohibited cases were also run against pre-fix IfcTester, where all three falsely pass. That is the silent-satisfaction bug these cases exist to catch. To save you the boilerplate, here is the specification content we used for verification, ready to adapt into the fenced blocks. Container pair: <!-- pass -->
<specification name="The container predefined type may specify USERDEFINED itself" ifcVersion="IFC4">
<applicability maxOccurs="unbounded">
<entity><name><simpleValue>IFCELEMENTASSEMBLY</simpleValue></name></entity>
</applicability>
<requirements>
<partOf relation="IFCRELCONTAINEDINSPATIALSTRUCTURE">
<entity>
<name><simpleValue>IFCSPACE</simpleValue></name>
<predefinedType><simpleValue>USERDEFINED</simpleValue></predefinedType>
</entity>
</partOf>
</requirements>
</specification>
<!-- fail -->
<specification name="A prohibited container predefined type check fails a user-defined match" ifcVersion="IFC4">
<applicability maxOccurs="unbounded">
<entity><name><simpleValue>IFCELEMENTASSEMBLY</simpleValue></name></entity>
</applicability>
<requirements>
<partOf relation="IFCRELCONTAINEDINSPATIALSTRUCTURE" cardinality="prohibited">
<entity>
<name><simpleValue>IFCSPACE</simpleValue></name>
<predefinedType><simpleValue>USERDEFINED</simpleValue></predefinedType>
</entity>
</partOf>
</requirements>
</specification>For the nest variant, applicability targets One thing worth knowing: there was no prior |
partof-facet.md's Parameters table lists two parameters, Entity and Relation. The wordpredefinedTypedoes not appear anywhere on the page.But PartOf's nested entity is a full
entityType. FromSchema/ids.xsd:That is the same complex type the Entity facet uses, so
predefinedTypeis legal inside PartOf and behaves the same way. Meanwhileentity-facet.mddocuments it extensively, including the five-step resolution procedure and worked examples showing thatpredefinedType="USERDEFINED"matches the raw IFC attribute literally rather than the substitutedObjectTypetext. Issue #306 records that this literal match is deliberate and agreed.So the rule is stated once, for one facet, and silently applies to another that never mentions the parameter exists.
Why we noticed
We hit it as a real defect. IfcTester's
PartOfnever handled the literalUSERDEFINEDcase, at six separate sites, while itsEntityfacet did. The consequence was a false pass: anIfcSpacecontaining anIfcWall, checked withPartOf(predefinedType="USERDEFINED", cardinality="prohibited"), reported PASS when the correct verdict is FAIL. A prohibition silently satisfied, so a non-compliant model passes with nothing to prompt anyone to look.Fixed on our side in IfcOpenShell#9203.
A gap in the test suite, which may matter more than the docs
We enumerated all 24 official PartOf test cases. None tests a literal
USERDEFINED. Issue #307 added exactly that case for the Entity facet after #306 agreed the behaviour, but the equivalent was never added for PartOf.So an implementer can pass the whole conformance suite with this bug present, which is what happened to us. Happy to contribute that test case if it would be useful; tell us the naming and placement you would want.
This change
One paragraph under the Parameters table, pointing at the Entity facet's existing rules rather than duplicating them, so there is one source of truth.
Reword freely to fit the manual's voice.