Build a canonical data fingerprint for one entity. Property sets, quantity
sets, their members, and type assignments are all sorted, so collection
ordering never produces a spurious "modified".
Assigned types are identified semantically — by name and IFC class, never
by GlobalId. A GlobalId is only stable while the file is edited in
place; a from-scratch re-export regenerates every IfcRoot's, and
IfcTypeObject is an IfcRoot. Hashing the type's GlobalId therefore
changed the fingerprint of every typed element — walls, doors, windows,
most of a real model — on exactly the re-export where nothing substantive
changed, and matchUnpairedByContent buckets on dataHash, so those
elements could never content-match. Name + class is the part of a type
assignment that survives a re-GUID, and is what the equivalent IfcOpenShell
comparison keys on.
The cost is a real, accepted loss of discrimination: two different type
entities that share a name and a class are now indistinguishable here, so
re-pointing an element from one to the other does not move its dataHash.
That trade is lopsided in favour of the semantic key. The loss needs
duplicate type names within one class, which is a modelling defect and
indistinguishable to a human reader of the model anyway; and it only
surfaces on elements that are otherwise byte-identical in every attribute,
property and quantity. The bug it replaces fired on every typed element of
every re-exported model.
Tag participates, and is supplied for TYPE OBJECTS ONLY — the one place
where it is design content rather than the exporter's element id. See
DataFingerprintInput.tag for both halves of that argument.
Build a canonical data fingerprint for one entity. Property sets, quantity sets, their members, and type assignments are all sorted, so collection ordering never produces a spurious "modified".
Assigned types are identified semantically — by name and IFC class, never by GlobalId. A
GlobalIdis only stable while the file is edited in place; a from-scratch re-export regenerates everyIfcRoot's, andIfcTypeObjectis anIfcRoot. Hashing the type's GlobalId therefore changed the fingerprint of every typed element — walls, doors, windows, most of a real model — on exactly the re-export where nothing substantive changed, andmatchUnpairedByContentbuckets ondataHash, so those elements could never content-match. Name + class is the part of a type assignment that survives a re-GUID, and is what the equivalent IfcOpenShell comparison keys on.The cost is a real, accepted loss of discrimination: two different type entities that share a name and a class are now indistinguishable here, so re-pointing an element from one to the other does not move its
dataHash. That trade is lopsided in favour of the semantic key. The loss needs duplicate type names within one class, which is a modelling defect and indistinguishable to a human reader of the model anyway; and it only surfaces on elements that are otherwise byte-identical in every attribute, property and quantity. The bug it replaces fired on every typed element of every re-exported model.Tagparticipates, and is supplied for TYPE OBJECTS ONLY — the one place where it is design content rather than the exporter's element id. See DataFingerprintInput.tag for both halves of that argument.