@ifc-lite/mcp 0.18.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend-query.d.ts +2 -1
- package/dist/backend-query.d.ts.map +1 -1
- package/dist/backend-query.js +14 -35
- package/dist/backend-query.js.map +1 -1
- package/dist/context.d.ts +8 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/effective-entity-membership.d.ts +8 -0
- package/dist/effective-entity-membership.d.ts.map +1 -0
- package/dist/effective-entity-membership.js +23 -0
- package/dist/effective-entity-membership.js.map +1 -0
- package/dist/headless-backend-store-stubs.d.ts +12 -0
- package/dist/headless-backend-store-stubs.d.ts.map +1 -0
- package/dist/headless-backend-store-stubs.js +9 -0
- package/dist/headless-backend-store-stubs.js.map +1 -0
- package/dist/headless-backend-structural-store.d.ts +21 -0
- package/dist/headless-backend-structural-store.d.ts.map +1 -0
- package/dist/headless-backend-structural-store.js +20 -0
- package/dist/headless-backend-structural-store.js.map +1 -0
- package/dist/headless-backend.d.ts +2 -1
- package/dist/headless-backend.d.ts.map +1 -1
- package/dist/headless-backend.js +7 -9
- package/dist/headless-backend.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +4 -0
- package/dist/loader.js.map +1 -1
- package/dist/overlay.d.ts +13 -6
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +42 -24
- package/dist/overlay.js.map +1 -1
- package/dist/protocol/types.d.ts +0 -1
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/schema-tables.d.ts.map +1 -1
- package/dist/schema-tables.js +4 -2
- package/dist/schema-tables.js.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/spatial-tree.d.ts.map +1 -1
- package/dist/spatial-tree.js +3 -9
- package/dist/spatial-tree.js.map +1 -1
- package/dist/tools/check-rules.d.ts +3 -0
- package/dist/tools/check-rules.d.ts.map +1 -0
- package/dist/tools/check-rules.js +75 -0
- package/dist/tools/check-rules.js.map +1 -0
- package/dist/tools/diff-authored-keys.d.ts +4 -2
- package/dist/tools/diff-authored-keys.d.ts.map +1 -1
- package/dist/tools/diff-authored-keys.js +39 -17
- package/dist/tools/diff-authored-keys.js.map +1 -1
- package/dist/tools/diff-content.js +2 -2
- package/dist/tools/diff-content.js.map +1 -1
- package/dist/tools/diff-entity-scope.d.ts +53 -0
- package/dist/tools/diff-entity-scope.d.ts.map +1 -0
- package/dist/tools/diff-entity-scope.js +94 -0
- package/dist/tools/diff-entity-scope.js.map +1 -0
- package/dist/tools/diff-fingerprints.d.ts +1 -1
- package/dist/tools/diff-fingerprints.d.ts.map +1 -1
- package/dist/tools/diff-fingerprints.js +63 -117
- package/dist/tools/diff-fingerprints.js.map +1 -1
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/diff.js +7 -8
- package/dist/tools/diff.js.map +1 -1
- package/dist/tools/entity-target-schema.d.ts +16 -0
- package/dist/tools/entity-target-schema.d.ts.map +1 -0
- package/dist/tools/entity-target-schema.js +32 -0
- package/dist/tools/entity-target-schema.js.map +1 -0
- package/dist/tools/flow.d.ts +3 -0
- package/dist/tools/flow.d.ts.map +1 -0
- package/dist/tools/flow.js +239 -0
- package/dist/tools/flow.js.map +1 -0
- package/dist/tools/ids-accessor.d.ts +9 -1
- package/dist/tools/ids-accessor.d.ts.map +1 -1
- package/dist/tools/ids-accessor.js +9 -2
- package/dist/tools/ids-accessor.js.map +1 -1
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mutate.d.ts.map +1 -1
- package/dist/tools/mutate.js +15 -46
- package/dist/tools/mutate.js.map +1 -1
- package/dist/tools/structural.d.ts +11 -0
- package/dist/tools/structural.d.ts.map +1 -0
- package/dist/tools/structural.js +23 -0
- package/dist/tools/structural.js.map +1 -0
- package/dist/tools/util.d.ts.map +1 -1
- package/dist/tools/util.js +15 -18
- package/dist/tools/util.js.map +1 -1
- package/dist/tools/validation.d.ts.map +1 -1
- package/dist/tools/validation.js +40 -41
- package/dist/tools/validation.js.map +1 -1
- package/dist/tools/viewer.d.ts.map +1 -1
- package/dist/tools/viewer.js +10 -29
- package/dist/tools/viewer.js.map +1 -1
- package/dist/validate.d.ts +22 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +45 -10
- package/dist/validate.js.map +1 -1
- package/dist/viewer-manager.d.ts.map +1 -1
- package/dist/viewer-manager.js +1 -0
- package/dist/viewer-manager.js.map +1 -1
- package/package.json +23 -19
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* for size.
|
|
10
10
|
*/
|
|
11
11
|
import { EntityExtractor, authoredKeyValue, extractRootAttributesFromEntity, getAttributeNamesAcrossSchemas, parseAuthoredKeySpec, } from '@ifc-lite/parser';
|
|
12
|
+
import { stepText } from '../overlay.js';
|
|
12
13
|
/** Prefix on a fingerprint key taken from an authored property rather than a GlobalId. */
|
|
13
14
|
export const AUTHORED_KEY_PREFIX = 'prop:';
|
|
14
15
|
/**
|
|
@@ -19,7 +20,7 @@ export const AUTHORED_KEY_PREFIX = 'prop:';
|
|
|
19
20
|
export function fallbackPairDuplicateAuthoredKeys(sides, duplicates) {
|
|
20
21
|
if (duplicates.size === 0)
|
|
21
22
|
return;
|
|
22
|
-
for (const { fingerprints, store } of sides) {
|
|
23
|
+
for (const { fingerprints, store, overlay } of sides) {
|
|
23
24
|
const extractor = new EntityExtractor(store.source);
|
|
24
25
|
for (const fingerprint of fingerprints) {
|
|
25
26
|
if (!fingerprint.key.startsWith(AUTHORED_KEY_PREFIX))
|
|
@@ -27,11 +28,22 @@ export function fallbackPairDuplicateAuthoredKeys(sides, duplicates) {
|
|
|
27
28
|
const value = fingerprint.key.slice(AUTHORED_KEY_PREFIX.length);
|
|
28
29
|
if (!duplicates.has(value))
|
|
29
30
|
continue;
|
|
31
|
+
const named = overlay?.attributes(fingerprint.ref);
|
|
32
|
+
const positional = overlay?.positionalAttributes?.(fingerprint.ref);
|
|
33
|
+
const editedGlobalId = named?.has('GlobalId') ? named.get('GlobalId')
|
|
34
|
+
: positional?.has(0) ? stepText(positional.get(0)) ?? '' : undefined;
|
|
35
|
+
const createdGlobalId = overlay?.createdEntity(fingerprint.ref)?.globalId;
|
|
30
36
|
const tableGlobalId = store.entities.getGlobalId(fingerprint.ref);
|
|
37
|
+
// @raw-entity-enumeration-ok collision fallback uses this point source record only after checking effective and created GlobalIds
|
|
31
38
|
const ref = store.entityIndex.byId.get(fingerprint.ref);
|
|
32
39
|
const entity = ref ? extractor.extractEntity(ref) : undefined;
|
|
33
40
|
const sourceGlobalId = entity ? extractRootAttributesFromEntity(entity).globalId : undefined;
|
|
34
|
-
|
|
41
|
+
// An explicit empty edit clears GlobalId. Falling back to the source
|
|
42
|
+
// here would resurrect an identity the session no longer has; the
|
|
43
|
+
// fingerprint builder omits that source entity before this repair pass.
|
|
44
|
+
const globalId = editedGlobalId !== undefined ? editedGlobalId
|
|
45
|
+
: createdGlobalId !== undefined ? createdGlobalId
|
|
46
|
+
: (tableGlobalId || sourceGlobalId);
|
|
35
47
|
if (!globalId) {
|
|
36
48
|
throw new Error(`Cannot restore GlobalId for authored-key collision on #${fingerprint.ref}`);
|
|
37
49
|
}
|
|
@@ -46,7 +58,7 @@ export function fallbackPairDuplicateAuthoredKeys(sides, duplicates) {
|
|
|
46
58
|
* owners: a deleted twin no longer contests the key. A created entity has no
|
|
47
59
|
* store row to read and keeps its GlobalId.
|
|
48
60
|
*/
|
|
49
|
-
export function authoredKeyResolver(store, overlay, options, extractor,
|
|
61
|
+
export function authoredKeyResolver(store, overlay, options, extractor, entities) {
|
|
50
62
|
const keySpec = options.keyProperty ? parseAuthoredKeySpec(options.keyProperty) : undefined;
|
|
51
63
|
if (!keySpec)
|
|
52
64
|
return (_expressId, globalId) => globalId;
|
|
@@ -55,6 +67,17 @@ export function authoredKeyResolver(store, overlay, options, extractor, isDepend
|
|
|
55
67
|
const edited = overlay?.attributes(expressId).get('Tag');
|
|
56
68
|
if (edited !== undefined)
|
|
57
69
|
return edited.trim().length > 0 ? edited.trim() : undefined;
|
|
70
|
+
const created = overlay?.createdEntity(expressId);
|
|
71
|
+
// @raw-entity-enumeration-ok Tag slot discovery needs the source class for this one entity when no queued retype or creation supplies it
|
|
72
|
+
const effectiveType = overlay?.effectiveType?.(expressId)
|
|
73
|
+
?? created?.ifcType ?? store.entityIndex.byId.get(expressId)?.type;
|
|
74
|
+
const tagIndex = effectiveType ? getAttributeNamesAcrossSchemas(effectiveType).indexOf('Tag') : -1;
|
|
75
|
+
const positional = overlay?.positionalAttributes?.(expressId);
|
|
76
|
+
if (tagIndex >= 0 && positional?.has(tagIndex))
|
|
77
|
+
return stepText(positional.get(tagIndex));
|
|
78
|
+
if (created) {
|
|
79
|
+
return tagIndex < 0 ? undefined : stepText(created.attributes[tagIndex]);
|
|
80
|
+
}
|
|
58
81
|
}
|
|
59
82
|
else if (overlay) {
|
|
60
83
|
const set = overlay.propertySets(expressId).find((pset) => pset.name === keySpec.pset);
|
|
@@ -72,21 +95,19 @@ export function authoredKeyResolver(store, overlay, options, extractor, isDepend
|
|
|
72
95
|
// A first pass so a value two entities share can be refused for both,
|
|
73
96
|
// instead of the diff's first-wins index quietly keeping one.
|
|
74
97
|
const owners = new Map();
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
for (const { expressId } of entities) {
|
|
100
|
+
if (seen.has(expressId))
|
|
77
101
|
continue;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
else
|
|
88
|
-
owners.set(value, [expressId]);
|
|
89
|
-
}
|
|
102
|
+
seen.add(expressId);
|
|
103
|
+
const value = authoredKeyOf(expressId);
|
|
104
|
+
if (value === undefined)
|
|
105
|
+
continue;
|
|
106
|
+
const list = owners.get(value);
|
|
107
|
+
if (list)
|
|
108
|
+
list.push(expressId);
|
|
109
|
+
else
|
|
110
|
+
owners.set(value, [expressId]);
|
|
90
111
|
}
|
|
91
112
|
for (const [value, ids] of owners) {
|
|
92
113
|
if (ids.length > 1)
|
|
@@ -126,6 +147,7 @@ export function attributeAcrossSchemas(store, expressId, ifcType, attributeName)
|
|
|
126
147
|
const index = getAttributeNamesAcrossSchemas(ifcType).indexOf(attributeName);
|
|
127
148
|
if (index < 0)
|
|
128
149
|
return undefined;
|
|
150
|
+
// @raw-entity-enumeration-ok this point source slot is the base value; buildDataInput applies pending named and positional Tag edits
|
|
129
151
|
const ref = store.entityIndex.byId.get(expressId);
|
|
130
152
|
if (!ref)
|
|
131
153
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-authored-keys.js","sourceRoot":"","sources":["../../src/tools/diff-authored-keys.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;GAMG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,+BAA+B,EAC/B,8BAA8B,EAC9B,oBAAoB,GAErB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"diff-authored-keys.js","sourceRoot":"","sources":["../../src/tools/diff-authored-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,8 +68,8 @@ export function contentDiff(left, right, overlays, maxMatches, maxGroupMembers,
|
|
|
68
68
|
const baseFingerprints = buildModelFingerprints(left.store, overlays.left, adapter);
|
|
69
69
|
const headFingerprints = buildModelFingerprints(right.store, overlays.right, adapter);
|
|
70
70
|
fallbackPairDuplicateAuthoredKeys([
|
|
71
|
-
{ fingerprints: baseFingerprints, store: left.store },
|
|
72
|
-
{ fingerprints: headFingerprints, store: right.store },
|
|
71
|
+
{ fingerprints: baseFingerprints, store: left.store, overlay: overlays.left },
|
|
72
|
+
{ fingerprints: headFingerprints, store: right.store, overlay: overlays.right },
|
|
73
73
|
], duplicateAuthoredKeys);
|
|
74
74
|
const diff = diffModels(baseFingerprints, headFingerprints, {
|
|
75
75
|
scope: 'data',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-content.js","sourceRoot":"","sources":["../../src/tools/diff-content.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAA4C,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAAgB,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,iCAAiC,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAuB,MAAM,eAAe,CAAC;AAG3E;oEACoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C;;;;GAIG;AACH,MAAM,gBAAgB,GAAuB;IAC3C,WAAW;IACX,YAAY;IACZ,cAAc;IACd,OAAO;IACP,UAAU;IACV,aAAa;IACb,SAAS;CACV,CAAC;AAEF;wDACwD;AACxD,MAAM,UAAU,WAAW,CACzB,IAAiB,EACjB,KAAkB,EAClB,QAAuE,EACvE,UAAkB,EAClB,eAAuB,EACvB,WAAoB,EACpB,UAAoB,EACpB,UAAoB;IAEpB,6EAA6E;IAC7E,yEAAyE;IACzE,sDAAsD;IACtD,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1D,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpF,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtF,iCAAiC,CAC/B;QACE,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;
|
|
1
|
+
{"version":3,"file":"diff-content.js","sourceRoot":"","sources":["../../src/tools/diff-content.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Membership and type scope for MCP model diff (#5249). */
|
|
2
|
+
import { type EffectiveEntity } from '@ifc-lite/data';
|
|
3
|
+
import { type IfcDataStore } from '@ifc-lite/parser';
|
|
4
|
+
import type { PendingOverlay } from '../overlay.js';
|
|
5
|
+
/** How an uppercase STEP type participates in the comparison. `name` is the
|
|
6
|
+
* registry's PascalCase spelling, used instead of the `EntityTable`'s
|
|
7
|
+
* `'Unknown'` for entities the table never took in. */
|
|
8
|
+
interface TypeRole {
|
|
9
|
+
role: 'independent' | 'dependent' | 'unknown';
|
|
10
|
+
name: string;
|
|
11
|
+
/** Whether the class is an `IfcTypeObject` — the gate on hashing `Tag`
|
|
12
|
+
* (issue #2021). A class no bundled schema declares is `false` rather than
|
|
13
|
+
* guessed; the fingerprint then carries no `Tag`, which is the same answer
|
|
14
|
+
* as a type object that has none. */
|
|
15
|
+
typeObject: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Classify one STEP type against the three `IfcRoot` branches.
|
|
19
|
+
*
|
|
20
|
+
* The chain has to come from **every bundled schema**, not from the parser's
|
|
21
|
+
* IFC4 codegen pin. `getInheritanceChainForEntity` answers an empty chain for
|
|
22
|
+
* any class the pin does not carry, and that is not a rare corner: IFC2X3 alone
|
|
23
|
+
* puts 23 `IfcObjectDefinition` classes there (`IfcMove`, `IfcOrderAction`,
|
|
24
|
+
* `IfcScheduleTimeControl`, `IfcSpaceProgram`, `IfcServiceLife`, …) and IFC4X3
|
|
25
|
+
* another 77. Judging those as `unknown` dropped the ones the `EntityTable`
|
|
26
|
+
* does not hold — real objects with real GlobalIds — and let through the
|
|
27
|
+
* IFC2X3-only *resource* classes it does hold under a `…STYLE` name, keyed on
|
|
28
|
+
* the Name in slot 0. Both are wrong answers about an IFC2X3 file, which is
|
|
29
|
+
* still most of what is in the wild.
|
|
30
|
+
*
|
|
31
|
+
* `unknown` is still not `dependent`: a vendor extension no schema declares has
|
|
32
|
+
* no chain to judge, so it keeps exactly the reach the `EntityTable` already
|
|
33
|
+
* gave it — which for a `…TYPE` class is a genuine GlobalId, since the parser's
|
|
34
|
+
* type-object branch is name-based and takes those in. Guessing that an
|
|
35
|
+
* unrecognised class is an `IfcObject` and reading its source record instead
|
|
36
|
+
* would cost one STEP extraction per row of every unrecognised bucket in the
|
|
37
|
+
* model, on every call, to reach entities almost no file has. The price of that
|
|
38
|
+
* choice is that a vendor `IfcRoot` subtype whose name does not end in `TYPE`
|
|
39
|
+
* stays uncompared.
|
|
40
|
+
*
|
|
41
|
+
* The one name the chain is not needed for is `IFCREL…`: that prefix is the
|
|
42
|
+
* parser's own rule for taking an unrecognised relationship into the table, and
|
|
43
|
+
* a relationship is excluded here whether any schema can confirm it or not.
|
|
44
|
+
* Without this, an unrecognised `IfcRelXxx` would be the single class of entity
|
|
45
|
+
* that got in through the relationship branch the comparison deliberately shuts.
|
|
46
|
+
*/
|
|
47
|
+
export declare function classifyType(typeKey: string): TypeRole;
|
|
48
|
+
/** Limit the canonical walk to potentially comparable classes before it visits
|
|
49
|
+
* geometry buckets. Sparse retype destinations and authored classes are added
|
|
50
|
+
* even when absent from the parsed source index. */
|
|
51
|
+
export declare function comparableEntities(store: IfcDataStore, overlay?: PendingOverlay | null): EffectiveEntity[];
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=diff-entity-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-entity-scope.d.ts","sourceRoot":"","sources":["../../src/tools/diff-entity-scope.ts"],"names":[],"mappings":"AAIA,4DAA4D;AAC5D,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;wDAEwD;AACxD,UAAU,QAAQ;IAChB,IAAI,EAAE,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;;0CAGsC;IACtC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAqBtD;AAED;;oDAEoD;AACpD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,eAAe,EAAE,CA0B1G"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/** Membership and type scope for MCP model diff (#5249). */
|
|
5
|
+
import { iterateEffectiveEntities } from '@ifc-lite/data';
|
|
6
|
+
import { getInheritanceChainAcrossSchemas } from '@ifc-lite/parser';
|
|
7
|
+
/**
|
|
8
|
+
* Classify one STEP type against the three `IfcRoot` branches.
|
|
9
|
+
*
|
|
10
|
+
* The chain has to come from **every bundled schema**, not from the parser's
|
|
11
|
+
* IFC4 codegen pin. `getInheritanceChainForEntity` answers an empty chain for
|
|
12
|
+
* any class the pin does not carry, and that is not a rare corner: IFC2X3 alone
|
|
13
|
+
* puts 23 `IfcObjectDefinition` classes there (`IfcMove`, `IfcOrderAction`,
|
|
14
|
+
* `IfcScheduleTimeControl`, `IfcSpaceProgram`, `IfcServiceLife`, …) and IFC4X3
|
|
15
|
+
* another 77. Judging those as `unknown` dropped the ones the `EntityTable`
|
|
16
|
+
* does not hold — real objects with real GlobalIds — and let through the
|
|
17
|
+
* IFC2X3-only *resource* classes it does hold under a `…STYLE` name, keyed on
|
|
18
|
+
* the Name in slot 0. Both are wrong answers about an IFC2X3 file, which is
|
|
19
|
+
* still most of what is in the wild.
|
|
20
|
+
*
|
|
21
|
+
* `unknown` is still not `dependent`: a vendor extension no schema declares has
|
|
22
|
+
* no chain to judge, so it keeps exactly the reach the `EntityTable` already
|
|
23
|
+
* gave it — which for a `…TYPE` class is a genuine GlobalId, since the parser's
|
|
24
|
+
* type-object branch is name-based and takes those in. Guessing that an
|
|
25
|
+
* unrecognised class is an `IfcObject` and reading its source record instead
|
|
26
|
+
* would cost one STEP extraction per row of every unrecognised bucket in the
|
|
27
|
+
* model, on every call, to reach entities almost no file has. The price of that
|
|
28
|
+
* choice is that a vendor `IfcRoot` subtype whose name does not end in `TYPE`
|
|
29
|
+
* stays uncompared.
|
|
30
|
+
*
|
|
31
|
+
* The one name the chain is not needed for is `IFCREL…`: that prefix is the
|
|
32
|
+
* parser's own rule for taking an unrecognised relationship into the table, and
|
|
33
|
+
* a relationship is excluded here whether any schema can confirm it or not.
|
|
34
|
+
* Without this, an unrecognised `IfcRelXxx` would be the single class of entity
|
|
35
|
+
* that got in through the relationship branch the comparison deliberately shuts.
|
|
36
|
+
*/
|
|
37
|
+
export function classifyType(typeKey) {
|
|
38
|
+
const upper = typeKey.toUpperCase();
|
|
39
|
+
const chain = getInheritanceChainAcrossSchemas(upper);
|
|
40
|
+
if (chain.length === 0) {
|
|
41
|
+
return {
|
|
42
|
+
role: upper.startsWith('IFCREL') ? 'dependent' : 'unknown',
|
|
43
|
+
name: typeKey,
|
|
44
|
+
typeObject: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// The chain holds the class itself plus its supertypes; which end the leaf
|
|
48
|
+
// sits at is the schema source's business — the union walk answers leaf→root
|
|
49
|
+
// and the IFC4 pin it falls back to answers root→leaf — so find it by name.
|
|
50
|
+
const name = chain.find((ancestor) => ancestor.toUpperCase() === upper) ?? typeKey;
|
|
51
|
+
const typeObject = chain.includes('IfcTypeObject');
|
|
52
|
+
if (!chain.includes('IfcRoot'))
|
|
53
|
+
return { role: 'dependent', name, typeObject };
|
|
54
|
+
return {
|
|
55
|
+
role: chain.includes('IfcObjectDefinition') ? 'independent' : 'dependent',
|
|
56
|
+
name,
|
|
57
|
+
typeObject,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Limit the canonical walk to potentially comparable classes before it visits
|
|
61
|
+
* geometry buckets. Sparse retype destinations and authored classes are added
|
|
62
|
+
* even when absent from the parsed source index. */
|
|
63
|
+
export function comparableEntities(store, overlay) {
|
|
64
|
+
const types = new Set();
|
|
65
|
+
// @raw-entity-enumeration-ok the diff chooses candidate source CLASS keys only; iterateEffectiveEntities handles membership below
|
|
66
|
+
for (const type of store.entityIndex.byType.keys()) {
|
|
67
|
+
if (classifyType(type).role !== 'dependent')
|
|
68
|
+
types.add(type);
|
|
69
|
+
}
|
|
70
|
+
const retypes = overlay?.typeMutations?.();
|
|
71
|
+
for (const change of retypes?.values() ?? []) {
|
|
72
|
+
if (classifyType(change.newType).role !== 'dependent')
|
|
73
|
+
types.add(change.newType);
|
|
74
|
+
}
|
|
75
|
+
const created = overlay?.created ?? [];
|
|
76
|
+
for (const entity of created) {
|
|
77
|
+
if (classifyType(entity.ifcType).role !== 'dependent')
|
|
78
|
+
types.add(entity.ifcType);
|
|
79
|
+
}
|
|
80
|
+
if (types.size === 0)
|
|
81
|
+
return [];
|
|
82
|
+
const createdById = new Map(created.map(entity => [entity.expressId, entity]));
|
|
83
|
+
const membership = overlay ? {
|
|
84
|
+
isDeleted: (id) => overlay.deleted.has(id),
|
|
85
|
+
getNewEntities: () => created.map(entity => ({ expressId: entity.expressId, type: entity.ifcType })),
|
|
86
|
+
getNewEntity: (id) => {
|
|
87
|
+
const entity = createdById.get(id);
|
|
88
|
+
return entity ? { type: entity.ifcType } : null;
|
|
89
|
+
},
|
|
90
|
+
getTypeMutations: () => retypes ?? new Map(),
|
|
91
|
+
} : null;
|
|
92
|
+
return [...iterateEffectiveEntities(store, membership, [...types])];
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=diff-entity-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-entity-scope.js","sourceRoot":"","sources":["../../src/tools/diff-entity-scope.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,4DAA4D;AAC5D,OAAO,EAAE,wBAAwB,EAAwB,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gCAAgC,EAAqB,MAAM,kBAAkB,CAAC;AAgBvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,gCAAgC,CAAC,KAAK,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;YAC1D,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,KAAK;SAClB,CAAC;IACJ,CAAC;IACD,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC/E,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW;QACzE,IAAI;QACJ,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;oDAEoD;AACpD,MAAM,UAAU,kBAAkB,CAAC,KAAmB,EAAE,OAA+B;IACrF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,kIAAkI;IAClI,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACnD,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC;IAC3C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7C,IAAI,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,WAAW;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;IACvC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,WAAW;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;QAC3B,SAAS,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,cAAc,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACpG,YAAY,EAAE,CAAC,EAAU,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAClD,CAAC;QACD,gBAAgB,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,IAAI,GAAG,EAA+B;KAC1E,CAAC,CAAC,CAAC,IAAI,CAAC;IACT,OAAO,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -86,7 +86,7 @@ import { type EntityFingerprint } from '@ifc-lite/diff';
|
|
|
86
86
|
import { type IfcDataStore } from '@ifc-lite/parser';
|
|
87
87
|
import { type FingerprintAdapterOptions } from './diff-authored-keys.js';
|
|
88
88
|
export { AUTHORED_KEY_PREFIX, type FingerprintAdapterOptions } from './diff-authored-keys.js';
|
|
89
|
-
import type
|
|
89
|
+
import { type PendingOverlay } from '../overlay.js';
|
|
90
90
|
/** Adapter handle threaded through the diff: the entity's express id. */
|
|
91
91
|
export type DiffRef = number;
|
|
92
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-fingerprints.d.ts","sourceRoot":"","sources":["../../src/tools/diff-fingerprints.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAaL,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAyD,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"diff-fingerprints.d.ts","sourceRoot":"","sources":["../../src/tools/diff-fingerprints.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAaL,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAyD,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGhI,OAAO,EAAE,mBAAmB,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAgC,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAElF,yEAAyE;AACzE,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAM7B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,EAC/B,OAAO,GAAE,yBAA8B,GACtC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAsD9B"}
|
|
@@ -87,63 +87,12 @@
|
|
|
87
87
|
*/
|
|
88
88
|
import { buildComponentFingerprints, buildDataFingerprint, } from '@ifc-lite/diff';
|
|
89
89
|
import { RelationshipType, resolvedTypeName } from '@ifc-lite/data';
|
|
90
|
-
import { EntityExtractor, extractAllEntityAttributes, extractClassificationsOnDemand, extractProjectUnits, extractPropertiesOnDemand, extractQuantitiesOnDemand, extractRootAttributesFromEntity, spatialContainerPath,
|
|
90
|
+
import { EntityExtractor, extractAllEntityAttributes, extractClassificationsOnDemand, extractProjectUnits, extractPropertiesOnDemand, extractQuantitiesOnDemand, extractRootAttributesFromEntity, spatialContainerPath, getAttributeNamesAcrossSchemas, quantitySiScale, roundToScale, scaledPropertyValue, } from '@ifc-lite/parser';
|
|
91
91
|
import { attributeAcrossSchemas, authoredKeyResolver, override } from './diff-authored-keys.js';
|
|
92
92
|
import { classificationLabel } from './diff-classification-label.js';
|
|
93
|
+
import { classifyType, comparableEntities } from './diff-entity-scope.js';
|
|
93
94
|
export { AUTHORED_KEY_PREFIX } from './diff-authored-keys.js';
|
|
94
|
-
|
|
95
|
-
* Classify one STEP type against the three `IfcRoot` branches.
|
|
96
|
-
*
|
|
97
|
-
* The chain has to come from **every bundled schema**, not from the parser's
|
|
98
|
-
* IFC4 codegen pin. `getInheritanceChainForEntity` answers an empty chain for
|
|
99
|
-
* any class the pin does not carry, and that is not a rare corner: IFC2X3 alone
|
|
100
|
-
* puts 23 `IfcObjectDefinition` classes there (`IfcMove`, `IfcOrderAction`,
|
|
101
|
-
* `IfcScheduleTimeControl`, `IfcSpaceProgram`, `IfcServiceLife`, …) and IFC4X3
|
|
102
|
-
* another 77. Judging those as `unknown` dropped the ones the `EntityTable`
|
|
103
|
-
* does not hold — real objects with real GlobalIds — and let through the
|
|
104
|
-
* IFC2X3-only *resource* classes it does hold under a `…STYLE` name, keyed on
|
|
105
|
-
* the Name in slot 0. Both are wrong answers about an IFC2X3 file, which is
|
|
106
|
-
* still most of what is in the wild.
|
|
107
|
-
*
|
|
108
|
-
* `unknown` is still not `dependent`: a vendor extension no schema declares has
|
|
109
|
-
* no chain to judge, so it keeps exactly the reach the `EntityTable` already
|
|
110
|
-
* gave it — which for a `…TYPE` class is a genuine GlobalId, since the parser's
|
|
111
|
-
* type-object branch is name-based and takes those in. Guessing that an
|
|
112
|
-
* unrecognised class is an `IfcObject` and reading its source record instead
|
|
113
|
-
* would cost one STEP extraction per row of every unrecognised bucket in the
|
|
114
|
-
* model, on every call, to reach entities almost no file has. The price of that
|
|
115
|
-
* choice is that a vendor `IfcRoot` subtype whose name does not end in `TYPE`
|
|
116
|
-
* stays uncompared.
|
|
117
|
-
*
|
|
118
|
-
* The one name the chain is not needed for is `IFCREL…`: that prefix is the
|
|
119
|
-
* parser's own rule for taking an unrecognised relationship into the table, and
|
|
120
|
-
* a relationship is excluded here whether any schema can confirm it or not.
|
|
121
|
-
* Without this, an unrecognised `IfcRelXxx` would be the single class of entity
|
|
122
|
-
* that got in through the relationship branch the comparison deliberately shuts.
|
|
123
|
-
*/
|
|
124
|
-
function classifyType(typeKey) {
|
|
125
|
-
const upper = typeKey.toUpperCase();
|
|
126
|
-
const chain = getInheritanceChainAcrossSchemas(upper);
|
|
127
|
-
if (chain.length === 0) {
|
|
128
|
-
return {
|
|
129
|
-
role: upper.startsWith('IFCREL') ? 'dependent' : 'unknown',
|
|
130
|
-
name: typeKey,
|
|
131
|
-
typeObject: false,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
// The chain holds the class itself plus its supertypes; which end the leaf
|
|
135
|
-
// sits at is the schema source's business — the union walk answers leaf→root
|
|
136
|
-
// and the IFC4 pin it falls back to answers root→leaf — so find it by name.
|
|
137
|
-
const name = chain.find((ancestor) => ancestor.toUpperCase() === upper) ?? typeKey;
|
|
138
|
-
const typeObject = chain.includes('IfcTypeObject');
|
|
139
|
-
if (!chain.includes('IfcRoot'))
|
|
140
|
-
return { role: 'dependent', name, typeObject };
|
|
141
|
-
return {
|
|
142
|
-
role: chain.includes('IfcObjectDefinition') ? 'independent' : 'dependent',
|
|
143
|
-
name,
|
|
144
|
-
typeObject,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
95
|
+
import { stepText } from '../overlay.js';
|
|
147
96
|
/**
|
|
148
97
|
* Build one {@link EntityFingerprint} per `IfcObjectDefinition` in a store.
|
|
149
98
|
*
|
|
@@ -166,58 +115,52 @@ export function buildModelFingerprints(store, overlay, options = {}) {
|
|
|
166
115
|
// the (small) set of object types the EntityTable declines to hold.
|
|
167
116
|
const extractor = new EntityExtractor(store.source);
|
|
168
117
|
const units = extractProjectUnits(store.source, store.entityIndex); // for quantitySiScale/scaledPropertyValue
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
118
|
+
const entities = comparableEntities(store, overlay);
|
|
119
|
+
const keyOf = authoredKeyResolver(store, overlay, options, extractor, entities);
|
|
120
|
+
for (const { expressId, type: typeKey, overlayCreated } of entities) {
|
|
121
|
+
if (overlayCreated) {
|
|
122
|
+
const created = overlay?.createdEntity(expressId);
|
|
123
|
+
if (created && overlay) {
|
|
124
|
+
const fingerprint = createdFingerprint(created, overlay, units, keyOf(expressId, created.globalId));
|
|
125
|
+
if (fingerprint)
|
|
126
|
+
fingerprints.push(fingerprint);
|
|
127
|
+
}
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
174
130
|
const type = classifyType(typeKey);
|
|
175
|
-
if (
|
|
131
|
+
if (seen.has(expressId))
|
|
176
132
|
continue;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// plan. Its GlobalId is in the STEP record, so read it there.
|
|
190
|
-
source = readRootAttributes(extractor, store, expressId);
|
|
191
|
-
globalId = source?.globalId ?? '';
|
|
192
|
-
}
|
|
193
|
-
// Still nothing: the entity is not an IfcRoot at all (a placement, a
|
|
194
|
-
// profile, a representation item), so it has no cross-model identity.
|
|
195
|
-
if (!globalId)
|
|
196
|
-
continue;
|
|
197
|
-
const tableType = store.entities.getTypeName(expressId);
|
|
198
|
-
// `getTypeName` answers 'Unknown' for a row the table never took in. The
|
|
199
|
-
// registry's own spelling is the honest answer, and it has to be a real
|
|
200
|
-
// type name: `ifcType` is hashed into the fingerprint and cross-checked
|
|
201
|
-
// on every content match, so 'Unknown' would pair a task with an actor.
|
|
202
|
-
const ifcType = source && (!tableType || tableType === 'Unknown') ? type.name : tableType;
|
|
203
|
-
const input = buildDataInput(store, expressId, ifcType, source, type.typeObject, overlay, units);
|
|
204
|
-
const fingerprint = {
|
|
205
|
-
key: keyOf(expressId, globalId),
|
|
206
|
-
ifcType,
|
|
207
|
-
dataHash: buildDataFingerprint(input),
|
|
208
|
-
components: buildComponentFingerprints(input),
|
|
209
|
-
ref: expressId,
|
|
210
|
-
};
|
|
211
|
-
const container = spatialContainerPath(store, expressId);
|
|
212
|
-
if (container !== undefined)
|
|
213
|
-
fingerprint.container = container;
|
|
214
|
-
fingerprints.push(fingerprint);
|
|
133
|
+
seen.add(expressId);
|
|
134
|
+
const named = overlay?.attributes(expressId);
|
|
135
|
+
const positional = overlay?.positionalAttributes?.(expressId);
|
|
136
|
+
const editedGlobalId = named?.has('GlobalId') ? named.get('GlobalId')
|
|
137
|
+
: positional?.has(0) ? stepText(positional.get(0)) ?? '' : undefined;
|
|
138
|
+
let globalId = editedGlobalId ?? store.entities.getGlobalId(expressId);
|
|
139
|
+
let source;
|
|
140
|
+
if (!globalId && editedGlobalId === undefined && type.role === 'independent') {
|
|
141
|
+
// In the model but not in the table: a schedule task, an actor, a work
|
|
142
|
+
// plan. Its GlobalId is in the STEP record, so read it there.
|
|
143
|
+
source = readRootAttributes(extractor, store, expressId);
|
|
144
|
+
globalId = source?.globalId ?? '';
|
|
215
145
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
146
|
+
// Still nothing: the entity is not an IfcRoot at all (a placement, a
|
|
147
|
+
// profile, a representation item), so it has no cross-model identity.
|
|
148
|
+
if (!globalId)
|
|
149
|
+
continue;
|
|
150
|
+
// The effective class wins over the immutable table's source class.
|
|
151
|
+
const ifcType = type.name;
|
|
152
|
+
const input = buildDataInput(store, expressId, ifcType, source, type.typeObject, overlay, units);
|
|
153
|
+
const fingerprint = {
|
|
154
|
+
key: keyOf(expressId, globalId),
|
|
155
|
+
ifcType,
|
|
156
|
+
dataHash: buildDataFingerprint(input),
|
|
157
|
+
components: buildComponentFingerprints(input),
|
|
158
|
+
ref: expressId,
|
|
159
|
+
};
|
|
160
|
+
const container = spatialContainerPath(store, expressId);
|
|
161
|
+
if (container !== undefined)
|
|
162
|
+
fingerprint.container = container;
|
|
163
|
+
fingerprints.push(fingerprint);
|
|
221
164
|
}
|
|
222
165
|
return fingerprints;
|
|
223
166
|
}
|
|
@@ -240,15 +183,12 @@ export function buildModelFingerprints(store, overlay, options = {}) {
|
|
|
240
183
|
* hashed IfcRoot attributes: `Name` and `Description` have a payload behind them
|
|
241
184
|
* (STEP slots 0/2/3 are fixed across `IfcRoot` subtypes), `ObjectType` has none
|
|
242
185
|
* (slot 4 is `ApplicableOccurrence` on an `IfcTypeObject`) and so exists only as
|
|
243
|
-
* an override
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* were already read through the overlay.
|
|
186
|
+
* an override. `Tag` is read from its class-specific authored slot or override,
|
|
187
|
+
* and hashed only for `IfcTypeObject` (issue #2021). Property sets and
|
|
188
|
+
* quantities are read through the overlay.
|
|
247
189
|
*
|
|
248
|
-
* An authored key
|
|
249
|
-
*
|
|
250
|
-
* GlobalId the caller gave it. A created entity that duplicates a stored
|
|
251
|
-
* entity's authored value therefore reads as added rather than as a collision.
|
|
190
|
+
* An authored key is resolved from its effective attributes or property sets,
|
|
191
|
+
* alongside source entities, so a duplicate is treated as a collision.
|
|
252
192
|
*
|
|
253
193
|
* `predefinedType` and `typeAssignments` are necessarily absent: both are read
|
|
254
194
|
* through the store, which has no row for an entity that exists only in the
|
|
@@ -256,17 +196,19 @@ export function buildModelFingerprints(store, overlay, options = {}) {
|
|
|
256
196
|
* entity that would have matched on those alone therefore reports as added
|
|
257
197
|
* rather than matched, which is the safe direction.
|
|
258
198
|
*/
|
|
259
|
-
function createdFingerprint(entity, overlay, units
|
|
199
|
+
function createdFingerprint(entity, overlay, units, // scales Qto_ quantities and measure-typed Pset properties to base SI
|
|
200
|
+
key) {
|
|
260
201
|
const type = classifyType(entity.ifcType);
|
|
261
202
|
if (type.role === 'dependent')
|
|
262
203
|
return null;
|
|
263
204
|
const edited = overlay.attributes(entity.expressId);
|
|
205
|
+
const tagIndex = getAttributeNamesAcrossSchemas(entity.ifcType).indexOf('Tag');
|
|
264
206
|
const input = {
|
|
265
207
|
ifcType: type.name,
|
|
266
208
|
name: override(edited.get('Name'), entity.name),
|
|
267
209
|
description: override(edited.get('Description'), entity.description),
|
|
268
210
|
objectType: override(edited.get('ObjectType'), undefined),
|
|
269
|
-
tag: type.typeObject ? override(edited.get('Tag'), undefined) : undefined,
|
|
211
|
+
tag: type.typeObject ? override(edited.get('Tag'), tagIndex < 0 ? undefined : stepText(entity.attributes[tagIndex])) : undefined,
|
|
270
212
|
propertySets: overlay.propertySets(entity.expressId).map((set) => ({
|
|
271
213
|
name: set.name,
|
|
272
214
|
properties: set.properties.map((property) => ({ name: property.name, value: scaledPropertyValue(property.value, property.dataType, units) })),
|
|
@@ -281,7 +223,7 @@ function createdFingerprint(entity, overlay, units) {
|
|
|
281
223
|
typeAssignments: [],
|
|
282
224
|
};
|
|
283
225
|
return {
|
|
284
|
-
key
|
|
226
|
+
key,
|
|
285
227
|
ifcType: type.name,
|
|
286
228
|
dataHash: buildDataFingerprint(input),
|
|
287
229
|
components: buildComponentFingerprints(input),
|
|
@@ -291,6 +233,7 @@ function createdFingerprint(entity, overlay, units) {
|
|
|
291
233
|
/** IfcRoot attributes straight from the entity's STEP record, for the rows the
|
|
292
234
|
* columnar `EntityTable` never took in. */
|
|
293
235
|
function readRootAttributes(extractor, store, expressId) {
|
|
236
|
+
// @raw-entity-enumeration-ok one source record supplies missing table GlobalId; caller applies overlay identity and membership
|
|
294
237
|
const ref = store.entityIndex.byId.get(expressId);
|
|
295
238
|
if (!ref)
|
|
296
239
|
return undefined;
|
|
@@ -326,6 +269,11 @@ overlay, units) {
|
|
|
326
269
|
? attributeAcrossSchemas(store, expressId, ifcType, 'Tag')
|
|
327
270
|
: undefined;
|
|
328
271
|
const edited = overlay?.attributes(expressId);
|
|
272
|
+
const tagIndex = isTypeObject ? getAttributeNamesAcrossSchemas(ifcType).indexOf('Tag') : -1;
|
|
273
|
+
const positional = tagIndex >= 0 ? overlay?.positionalAttributes?.(expressId) : undefined;
|
|
274
|
+
const effectiveTag = tagIndex >= 0 && positional?.has(tagIndex)
|
|
275
|
+
? stepText(positional.get(tagIndex))
|
|
276
|
+
: override(edited?.get('Tag'), storedTag != null ? String(storedTag) : undefined);
|
|
329
277
|
const propertySets = (overlay
|
|
330
278
|
? overlay.propertySets(expressId)
|
|
331
279
|
: extractPropertiesOnDemand(store, expressId)).map((set) => ({
|
|
@@ -361,9 +309,7 @@ overlay, units) {
|
|
|
361
309
|
description: override(edited?.get('Description'), store.entities.getDescription(expressId) || source?.description),
|
|
362
310
|
objectType: override(edited?.get('ObjectType'), store.entities.getObjectType(expressId) || source?.objectType),
|
|
363
311
|
predefinedType: predefinedType != null ? String(predefinedType) : undefined,
|
|
364
|
-
tag: isTypeObject
|
|
365
|
-
? override(edited?.get('Tag'), storedTag != null ? String(storedTag) : undefined)
|
|
366
|
-
: undefined,
|
|
312
|
+
tag: isTypeObject ? effectiveTag : undefined,
|
|
367
313
|
propertySets,
|
|
368
314
|
quantitySets,
|
|
369
315
|
typeAssignments,
|