@ifc-lite/export 2.7.1 → 2.8.1
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/attribute-slot-types.d.ts +57 -0
- package/dist/attribute-slot-types.d.ts.map +1 -0
- package/dist/attribute-slot-types.js +236 -0
- package/dist/attribute-slot-types.js.map +1 -0
- package/dist/demesh-writer.d.ts.map +1 -1
- package/dist/demesh-writer.js +8 -4
- package/dist/demesh-writer.js.map +1 -1
- package/dist/effective-index.d.ts +93 -0
- package/dist/effective-index.d.ts.map +1 -0
- package/dist/effective-index.js +218 -0
- package/dist/effective-index.js.map +1 -0
- package/dist/lod0-generator.d.ts.map +1 -1
- package/dist/lod0-generator.js +10 -4
- package/dist/lod0-generator.js.map +1 -1
- package/dist/lod1-generator.d.ts.map +1 -1
- package/dist/lod1-generator.js +24 -10
- package/dist/lod1-generator.js.map +1 -1
- package/dist/reference-collector.d.ts +18 -2
- package/dist/reference-collector.d.ts.map +1 -1
- package/dist/reference-collector.js +57 -22
- package/dist/reference-collector.js.map +1 -1
- package/dist/step-exporter.d.ts +71 -15
- package/dist/step-exporter.d.ts.map +1 -1
- package/dist/step-exporter.js +365 -95
- package/dist/step-exporter.js.map +1 -1
- package/dist/type-owned-psets.d.ts +44 -0
- package/dist/type-owned-psets.d.ts.map +1 -0
- package/dist/type-owned-psets.js +94 -0
- package/dist/type-owned-psets.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-based positional slots on `entityType` whose declared type is an EXPRESS
|
|
3
|
+
* ENUMERATION.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getEnumTypedSlots(entityType: string): ReadonlySet<number>;
|
|
6
|
+
/**
|
|
7
|
+
* Zero-based positional slots on `entityType` whose declared type bottoms out in
|
|
8
|
+
* EXPRESS STRING (`IfcLabel`, `IfcText`, `IfcIdentifier`, …).
|
|
9
|
+
*
|
|
10
|
+
* These are the slots where a value must be QUOTED regardless of what it looks
|
|
11
|
+
* like. Entity-reference and SELECT slots deliberately stay out: a bare `#12`
|
|
12
|
+
* is the correct token there, and it is only in a text slot that emitting one
|
|
13
|
+
* is a corruption.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getStringTypedSlots(entityType: string): ReadonlySet<number>;
|
|
16
|
+
/**
|
|
17
|
+
* Serialize a value destined for an ENUM slot as a STEP enumeration token:
|
|
18
|
+
* `.USERDEFINED.`, never `'USERDEFINED'`. Accepts the bare symbol or the
|
|
19
|
+
* already-dotted form.
|
|
20
|
+
*
|
|
21
|
+
* Two different questions, answered differently:
|
|
22
|
+
*
|
|
23
|
+
* DOMAIN validity — "is `.FOO.` a legal value of IfcWallTypeEnum" — is NOT
|
|
24
|
+
* checked. That is a schema question; the domain check with its `USERDEFINED` +
|
|
25
|
+
* `ObjectType` fallback lives in `retype.ts`, where a carried-over value has to
|
|
26
|
+
* survive a class change. Here the caller named this attribute explicitly, and
|
|
27
|
+
* `.FOO.` is at least a well-formed token in the right lexical category.
|
|
28
|
+
*
|
|
29
|
+
* LEXICAL validity — "is this a token at all" — IS checked, because this
|
|
30
|
+
* function owns the token form and nothing downstream can recover from getting
|
|
31
|
+
* it wrong. `.A,B.` re-parses as TWO arguments and shifts every following slot;
|
|
32
|
+
* `.O'BRIEN.` opens a string literal that swallows the rest of the record. The
|
|
33
|
+
* damage is silent and spans the whole entity, not one attribute.
|
|
34
|
+
*
|
|
35
|
+
* An invalid symbol falls back to a quoted string rather than throwing or
|
|
36
|
+
* dropping. Dropping is the bug class this whole change exists to fix. Throwing
|
|
37
|
+
* would turn one odd attribute value into a failed save of the entire model —
|
|
38
|
+
* strictly worse than one wrongly-typed slot in a file that still parses, still
|
|
39
|
+
* has correct arity, and still shows the user the text they typed. A quoted
|
|
40
|
+
* string is also exactly what this slot got before enum detection existed.
|
|
41
|
+
*/
|
|
42
|
+
export declare function serializeEnumToken(value: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Serialize a value destined for a STRING slot.
|
|
45
|
+
*
|
|
46
|
+
* Always quotes, never infers. `serializeAttributeValue` reads the token being
|
|
47
|
+
* replaced to decide the form, so over a `$` slot it takes a value that merely
|
|
48
|
+
* LOOKS like a token at face value: a `Tag` of `#12` became an entity
|
|
49
|
+
* reference, `.FOO.` an enumeration. In a slot the schema declares as text, the
|
|
50
|
+
* only legal tokens are a quoted string and the null/derived markers, so there
|
|
51
|
+
* is nothing to infer.
|
|
52
|
+
*
|
|
53
|
+
* `''`, `$` and `*` keep their existing meaning as those markers — that is
|
|
54
|
+
* unchanged behaviour, and `''` is already the caller's way to clear a value.
|
|
55
|
+
*/
|
|
56
|
+
export declare function serializeStringSlot(value: string): string;
|
|
57
|
+
//# sourceMappingURL=attribute-slot-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-slot-types.d.ts","sourceRoot":"","sources":["../src/attribute-slot-types.ts"],"names":[],"mappings":"AAuKA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAE3E;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,236 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Schema-aware detection of ENUMERATION- and STRING-typed STEP attribute slots.
|
|
6
|
+
*
|
|
7
|
+
* `serializeAttributeValue` infers a named attribute's STEP form from the token
|
|
8
|
+
* it is replacing. That works while there IS a token to read — a current
|
|
9
|
+
* `.ELEMENT.` says "this slot is an enum", a current `'Wall A'` says "this slot
|
|
10
|
+
* is text and the new value must be quoted" — and fails silently when the slot
|
|
11
|
+
* holds `$`, where there is nothing to read. Two ways it fails:
|
|
12
|
+
*
|
|
13
|
+
* - an enum came out quoted (`'USERDEFINED'`, not `.USERDEFINED.`);
|
|
14
|
+
* - a value that merely LOOKS like a token is emitted as one, so a `Tag` or
|
|
15
|
+
* `Name` of `#12` became an entity reference and `.FOO.` an enumeration.
|
|
16
|
+
* A room or tag literally named `#12` is ordinary on a real project.
|
|
17
|
+
*
|
|
18
|
+
* Both write a schema-invalid record rather than a wrong value, and the second
|
|
19
|
+
* got wider when overlay-created records started padding missing slots with `$`
|
|
20
|
+
* (#2006 review).
|
|
21
|
+
*
|
|
22
|
+
* A slot's declared type is statically known, so resolve it from the schema
|
|
23
|
+
* instead of guessing from the previous value. Indices come from exactly the
|
|
24
|
+
* resolution {@link getAttributeNamesAcrossSchemas} uses — the pinned IFC4
|
|
25
|
+
* registry first, the bundled 2X3+4+4X3 union only when the pin knows the class
|
|
26
|
+
* not at all — so an index from one is always an index into the other.
|
|
27
|
+
* `attribute-slot-types.test.ts` asserts that alignment over every class in the
|
|
28
|
+
* registry rather than trusting it.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately NOT version-parameterized: both sources are version-invariant
|
|
31
|
+
* here (the pin is IFC4, the union merges every bundled schema), so adding a
|
|
32
|
+
* version would suggest a precision this data cannot deliver.
|
|
33
|
+
*
|
|
34
|
+
* The one remaining gap is a leaf-declared, non-PredefinedType enum on a class
|
|
35
|
+
* the pin does not carry. `IfcEntityInfo` records attribute NAMES only —
|
|
36
|
+
* "types/optional flags are out of scope for the auditor (and not exposed by
|
|
37
|
+
* the upstream SchemaInfo data)" — so those types do not exist in this repo to
|
|
38
|
+
* be read, in the generated tables or anywhere else; closing that would take a
|
|
39
|
+
* codegen change to `@ifc-lite/data`. Everything reachable without one is
|
|
40
|
+
* covered: inherited slots via the nearest pinned ancestor, PredefinedType via
|
|
41
|
+
* the declared domain.
|
|
42
|
+
*/
|
|
43
|
+
import { SCHEMA_REGISTRY, getAllAttributesForEntity, getAttributeNamesAcrossSchemas, resolveEntityNameAlias, } from '@ifc-lite/parser';
|
|
44
|
+
import { ENTITIES_IFC2X3, ENTITIES_IFC4, ENTITIES_IFC4X3 } from '@ifc-lite/data';
|
|
45
|
+
import { escapeStepString, resolveExpressBase } from './step-serialization.js';
|
|
46
|
+
/** Union of every bundled schema, later schemas winning — mirrors the fallback
|
|
47
|
+
* inside `getAttributeNamesAcrossSchemas` so the two agree on indices. */
|
|
48
|
+
const UNION_BY_UPPER = (() => {
|
|
49
|
+
const map = new Map();
|
|
50
|
+
for (const list of [ENTITIES_IFC2X3, ENTITIES_IFC4, ENTITIES_IFC4X3]) {
|
|
51
|
+
for (const entity of list)
|
|
52
|
+
map.set(entity.name.toUpperCase(), entity);
|
|
53
|
+
}
|
|
54
|
+
return map;
|
|
55
|
+
})();
|
|
56
|
+
const slotTypeCache = new Map();
|
|
57
|
+
/**
|
|
58
|
+
* Declared attribute types of the nearest ancestor the pinned registry DOES
|
|
59
|
+
* carry, as a name → EXPRESS type map, for a class it does not.
|
|
60
|
+
*
|
|
61
|
+
* The union data set records attribute names but no per-attribute type, so the
|
|
62
|
+
* types of a leaf's INHERITED attributes have to come from an ancestor. Walks
|
|
63
|
+
* the union's `parent` chain because the pin cannot see the intermediate
|
|
64
|
+
* classes either (IfcRoad → IfcFacility → IfcSpatialStructureElement: only the
|
|
65
|
+
* last is pinned).
|
|
66
|
+
*/
|
|
67
|
+
function pinnedAncestorAttributeTypes(info) {
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
let cursor = info.parent
|
|
70
|
+
? UNION_BY_UPPER.get(info.parent.toUpperCase())
|
|
71
|
+
: undefined;
|
|
72
|
+
while (cursor && !seen.has(cursor.name)) {
|
|
73
|
+
seen.add(cursor.name);
|
|
74
|
+
const attributes = getAllAttributesForEntity(cursor.name);
|
|
75
|
+
if (attributes.length > 0) {
|
|
76
|
+
return new Map(attributes.map((a) => [a.name, a.type]));
|
|
77
|
+
}
|
|
78
|
+
cursor = cursor.parent ? UNION_BY_UPPER.get(cursor.parent.toUpperCase()) : undefined;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
/** Classify one slot by its declared EXPRESS type. */
|
|
83
|
+
function classify(declaredType, index, enums, strings) {
|
|
84
|
+
if (SCHEMA_REGISTRY.enums[declaredType]) {
|
|
85
|
+
enums.add(index);
|
|
86
|
+
}
|
|
87
|
+
else if (resolveExpressBase(declaredType) === 'STRING') {
|
|
88
|
+
strings.add(index);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Declared-type classification of `entityType`'s positional slots.
|
|
93
|
+
*
|
|
94
|
+
* Returns empty sets for classes neither source knows (vendor extensions),
|
|
95
|
+
* which leaves those slots on the previous-token inference exactly as before.
|
|
96
|
+
* Empty sets can never MISPLACE a value, so degrading to them is always safe.
|
|
97
|
+
*/
|
|
98
|
+
function getSlotTypes(entityType) {
|
|
99
|
+
// Canonicalize FIRST, and cache on the canonical name: `getAttributeNames-
|
|
100
|
+
// AcrossSchemas` resolves stratum aliases (IFCSOLIDSTRATUM →
|
|
101
|
+
// IfcGeotechnicalStratum) before indexing the union, so a lookup that did not
|
|
102
|
+
// would answer about a different attribute list than the one these indices
|
|
103
|
+
// index into — and every alias of one class would get its own cache entry.
|
|
104
|
+
const canonical = resolveEntityNameAlias(entityType);
|
|
105
|
+
const upper = canonical.toUpperCase();
|
|
106
|
+
const cached = slotTypeCache.get(upper);
|
|
107
|
+
if (cached)
|
|
108
|
+
return cached;
|
|
109
|
+
const enums = new Set();
|
|
110
|
+
const strings = new Set();
|
|
111
|
+
const pinned = getAllAttributesForEntity(canonical);
|
|
112
|
+
if (pinned.length > 0) {
|
|
113
|
+
for (let i = 0; i < pinned.length; i++)
|
|
114
|
+
classify(pinned[i].type, i, enums, strings);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const info = UNION_BY_UPPER.get(upper);
|
|
118
|
+
if (info) {
|
|
119
|
+
// Inherited slots: take the declared type from the nearest pinned
|
|
120
|
+
// ancestor, matched BY NAME against this class's own attribute list.
|
|
121
|
+
//
|
|
122
|
+
// Not by index. The ancestor's list is not always a prefix of the leaf's
|
|
123
|
+
// (measured: 30 of the 169 classes with a pinned ancestor), and reusing
|
|
124
|
+
// its indices would classify the wrong slot — e.g. on
|
|
125
|
+
// IfcStructuralLinearActionVarying index 10 is `ProjectedOrTrue` in the
|
|
126
|
+
// ancestor and `CausedBy` in the leaf, so an edit to a reference slot
|
|
127
|
+
// would be written as `.SOMETHING.`. Name matching places
|
|
128
|
+
// `ProjectedOrTrue` at the leaf's index 11, where it belongs.
|
|
129
|
+
const names = getAttributeNamesAcrossSchemas(canonical);
|
|
130
|
+
const ancestorTypes = pinnedAncestorAttributeTypes(info);
|
|
131
|
+
if (ancestorTypes) {
|
|
132
|
+
for (let i = 0; i < names.length; i++) {
|
|
133
|
+
const declared = ancestorTypes.get(names[i]);
|
|
134
|
+
if (declared)
|
|
135
|
+
classify(declared, i, enums, strings);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Leaf-declared PredefinedType: no ancestor declares it, and its enum
|
|
139
|
+
// type name is not in the union data — but a non-empty domain says the
|
|
140
|
+
// slot is an enumeration, which is all this needs to know.
|
|
141
|
+
if (info.predefinedTypes.length > 0) {
|
|
142
|
+
const index = names.indexOf('PredefinedType');
|
|
143
|
+
if (index >= 0)
|
|
144
|
+
enums.add(index);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const resolved = { enums, strings };
|
|
149
|
+
slotTypeCache.set(upper, resolved);
|
|
150
|
+
return resolved;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Zero-based positional slots on `entityType` whose declared type is an EXPRESS
|
|
154
|
+
* ENUMERATION.
|
|
155
|
+
*/
|
|
156
|
+
export function getEnumTypedSlots(entityType) {
|
|
157
|
+
return getSlotTypes(entityType).enums;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Zero-based positional slots on `entityType` whose declared type bottoms out in
|
|
161
|
+
* EXPRESS STRING (`IfcLabel`, `IfcText`, `IfcIdentifier`, …).
|
|
162
|
+
*
|
|
163
|
+
* These are the slots where a value must be QUOTED regardless of what it looks
|
|
164
|
+
* like. Entity-reference and SELECT slots deliberately stay out: a bare `#12`
|
|
165
|
+
* is the correct token there, and it is only in a text slot that emitting one
|
|
166
|
+
* is a corruption.
|
|
167
|
+
*/
|
|
168
|
+
export function getStringTypedSlots(entityType) {
|
|
169
|
+
return getSlotTypes(entityType).strings;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* ISO 10303-21 enumeration token body: a letter, then letters, digits or
|
|
173
|
+
* underscores. Anything else is not an enumeration token at all.
|
|
174
|
+
*/
|
|
175
|
+
const ENUM_SYMBOL = /^[A-Z][A-Z0-9_]*$/;
|
|
176
|
+
/**
|
|
177
|
+
* Serialize a value destined for an ENUM slot as a STEP enumeration token:
|
|
178
|
+
* `.USERDEFINED.`, never `'USERDEFINED'`. Accepts the bare symbol or the
|
|
179
|
+
* already-dotted form.
|
|
180
|
+
*
|
|
181
|
+
* Two different questions, answered differently:
|
|
182
|
+
*
|
|
183
|
+
* DOMAIN validity — "is `.FOO.` a legal value of IfcWallTypeEnum" — is NOT
|
|
184
|
+
* checked. That is a schema question; the domain check with its `USERDEFINED` +
|
|
185
|
+
* `ObjectType` fallback lives in `retype.ts`, where a carried-over value has to
|
|
186
|
+
* survive a class change. Here the caller named this attribute explicitly, and
|
|
187
|
+
* `.FOO.` is at least a well-formed token in the right lexical category.
|
|
188
|
+
*
|
|
189
|
+
* LEXICAL validity — "is this a token at all" — IS checked, because this
|
|
190
|
+
* function owns the token form and nothing downstream can recover from getting
|
|
191
|
+
* it wrong. `.A,B.` re-parses as TWO arguments and shifts every following slot;
|
|
192
|
+
* `.O'BRIEN.` opens a string literal that swallows the rest of the record. The
|
|
193
|
+
* damage is silent and spans the whole entity, not one attribute.
|
|
194
|
+
*
|
|
195
|
+
* An invalid symbol falls back to a quoted string rather than throwing or
|
|
196
|
+
* dropping. Dropping is the bug class this whole change exists to fix. Throwing
|
|
197
|
+
* would turn one odd attribute value into a failed save of the entire model —
|
|
198
|
+
* strictly worse than one wrongly-typed slot in a file that still parses, still
|
|
199
|
+
* has correct arity, and still shows the user the text they typed. A quoted
|
|
200
|
+
* string is also exactly what this slot got before enum detection existed.
|
|
201
|
+
*/
|
|
202
|
+
export function serializeEnumToken(value) {
|
|
203
|
+
const trimmed = value.trim();
|
|
204
|
+
if (trimmed === '*')
|
|
205
|
+
return '*';
|
|
206
|
+
const symbol = trimmed.replace(/^\./, '').replace(/\.$/, '').trim().toUpperCase();
|
|
207
|
+
if (symbol === '' || symbol === '$')
|
|
208
|
+
return '$';
|
|
209
|
+
if (!ENUM_SYMBOL.test(symbol)) {
|
|
210
|
+
console.warn(`[StepExporter] "${value}" is not a valid STEP enumeration symbol; writing it as a quoted string. `
|
|
211
|
+
+ 'The record stays parseable, but the slot now holds text where the schema declares an enumeration.');
|
|
212
|
+
return serializeStringSlot(trimmed);
|
|
213
|
+
}
|
|
214
|
+
return `.${symbol}.`;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Serialize a value destined for a STRING slot.
|
|
218
|
+
*
|
|
219
|
+
* Always quotes, never infers. `serializeAttributeValue` reads the token being
|
|
220
|
+
* replaced to decide the form, so over a `$` slot it takes a value that merely
|
|
221
|
+
* LOOKS like a token at face value: a `Tag` of `#12` became an entity
|
|
222
|
+
* reference, `.FOO.` an enumeration. In a slot the schema declares as text, the
|
|
223
|
+
* only legal tokens are a quoted string and the null/derived markers, so there
|
|
224
|
+
* is nothing to infer.
|
|
225
|
+
*
|
|
226
|
+
* `''`, `$` and `*` keep their existing meaning as those markers — that is
|
|
227
|
+
* unchanged behaviour, and `''` is already the caller's way to clear a value.
|
|
228
|
+
*/
|
|
229
|
+
export function serializeStringSlot(value) {
|
|
230
|
+
const trimmed = value.trim();
|
|
231
|
+
if (value === '' || trimmed === '$' || trimmed === '*') {
|
|
232
|
+
return trimmed === '*' ? '*' : '$';
|
|
233
|
+
}
|
|
234
|
+
return `'${escapeStepString(value)}'`;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=attribute-slot-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-slot-types.js","sourceRoot":"","sources":["../src/attribute-slot-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demesh-writer.d.ts","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"demesh-writer.d.ts","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAmD,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAItG,4EAA4E;AAC5E,KAAK,WAAW,GAAG,OAAO,CAAC;AAE3B;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnF,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1C;AAED,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,yEAAyE;IACzE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,wEAAwE;IACxE,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,yBAAyB,EAAE,EACrC,OAAO,GAAE,8BAAmC,GAC3C,iBAAiB,CA4JnB"}
|
package/dist/demesh-writer.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* callers upconvert IFC2X3 stores before applying (`convert --schema IFC4`
|
|
24
24
|
* path).
|
|
25
25
|
*/
|
|
26
|
-
import { EntityExtractor,
|
|
26
|
+
import { EntityExtractor, getAttributeNamesAcrossSchemas } from '@ifc-lite/parser';
|
|
27
27
|
import { pruneReplacedSubgraphs } from './demesh-prune.js';
|
|
28
28
|
import { stepReal } from './step-serialization.js';
|
|
29
29
|
/**
|
|
@@ -209,10 +209,14 @@ function findBodyContextId(byId, getEntity) {
|
|
|
209
209
|
return modelContext ?? anyContext;
|
|
210
210
|
}
|
|
211
211
|
function findAttrIndex(typeName, attrName) {
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
// Cross-schema union, not just the parser's IFC4-pinned registry —
|
|
213
|
+
// otherwise IFC4X3-only leaves (IfcSignal, IfcPavement, IfcCourse, …)
|
|
214
|
+
// resolve zero attributes and every element of that type is silently
|
|
215
|
+
// skipped as 'no-representation-attribute' (#2032).
|
|
216
|
+
const names = getAttributeNamesAcrossSchemas(typeName);
|
|
217
|
+
if (!names || names.length === 0)
|
|
214
218
|
return null;
|
|
215
|
-
const idx =
|
|
219
|
+
const idx = names.indexOf(attrName);
|
|
216
220
|
return idx >= 0 ? idx : null;
|
|
217
221
|
}
|
|
218
222
|
function valuesAreFinite(values) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demesh-writer.js","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"demesh-writer.js","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The effective model: what the file WILL say, not what it said when parsed.
|
|
3
|
+
*
|
|
4
|
+
* `IfcDataStore` answers for the source buffer. The `MutablePropertyView`
|
|
5
|
+
* overlay knows what the session has since created, retyped and deleted, and
|
|
6
|
+
* never writes back into the store (its buffer and `CompactEntityIndex` are
|
|
7
|
+
* immutable by construction — see `StoreEditor`). So every export pass that
|
|
8
|
+
* asked `dataStore` a question the overlay owns produced a saved file that
|
|
9
|
+
* disagreed with what the user did (#2012):
|
|
10
|
+
*
|
|
11
|
+
* - a `visibleOnly` closure computed from `entityIndex.byId` can never make an
|
|
12
|
+
* overlay-created entity a root, nor walk into one, so a created wall was
|
|
13
|
+
* silently absent from the export;
|
|
14
|
+
* - `endsWith('TYPE')` on the source record's class misses an overlay-created
|
|
15
|
+
* `IfcWallType`, so its psets were emitted as occurrence relations;
|
|
16
|
+
* - and a tombstoned entity still looked alive to the pset/quantity passes.
|
|
17
|
+
*
|
|
18
|
+
* This module is the one place those questions are answered. Every consumer
|
|
19
|
+
* takes the index rather than reaching for `dataStore`, so a new pass cannot
|
|
20
|
+
* reintroduce the defect by forgetting to ask the overlay: there is nothing
|
|
21
|
+
* else to ask.
|
|
22
|
+
*
|
|
23
|
+
* Three distinctions the shape deliberately keeps:
|
|
24
|
+
*
|
|
25
|
+
* - {@link EffectiveEntityIndex.get} answers *as authored or parsed* — the
|
|
26
|
+
* source record's class and byte range, or the creation payload's class.
|
|
27
|
+
* {@link EffectiveEntityIndex.typeOf} answers the *effective* class, with
|
|
28
|
+
* retypes applied and normalised to the UPPERCASE form the store uses.
|
|
29
|
+
* The source-iteration pass needs the former (it hands the original class
|
|
30
|
+
* to `retypeStepLine` as the from-type); every classification needs the
|
|
31
|
+
* latter.
|
|
32
|
+
* - a tombstoned id does not exist: `get` returns undefined, `has` is false,
|
|
33
|
+
* and iteration skips it. `isDeleted` is what distinguishes "deleted" from
|
|
34
|
+
* "never existed" for callers that must tell them apart.
|
|
35
|
+
* - an overlay-created record has no bytes, so its outgoing references are
|
|
36
|
+
* read from its authored attributes by {@link EffectiveEntityIndex.refsOf}
|
|
37
|
+
* instead of scanned out of the source buffer.
|
|
38
|
+
*/
|
|
39
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
40
|
+
import { type IfcAttributeValue, type MutablePropertyView } from '@ifc-lite/mutations';
|
|
41
|
+
import { type CompleteEntityIndex } from './entity-iteration.js';
|
|
42
|
+
/**
|
|
43
|
+
* The complete source index (`byId` + any deferred property atoms) with the
|
|
44
|
+
* overlay folded in. Extends {@link CompleteEntityIndex}, so anything that
|
|
45
|
+
* already takes the source view takes this one.
|
|
46
|
+
*/
|
|
47
|
+
export interface EffectiveEntityIndex extends CompleteEntityIndex {
|
|
48
|
+
/** Effective IFC class, UPPERCASE, retype applied. Undefined when the id does
|
|
49
|
+
* not exist in the effective model (unknown, or tombstoned). */
|
|
50
|
+
typeOf(id: number): string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* The same answer for an id whose record you are already holding — on an
|
|
53
|
+
* iteration path, where the extra `get` is not free.
|
|
54
|
+
*
|
|
55
|
+
* `CompactEntityIndex.get` binary-searches and allocates an `EntityRef` per
|
|
56
|
+
* call, so re-deriving the class from the id while iterating would cost
|
|
57
|
+
* O(E log E) plus one allocation per entity for a string the loop already has.
|
|
58
|
+
*/
|
|
59
|
+
effectiveType(id: number, recordType: string): string;
|
|
60
|
+
/** Created by the overlay this session (no source record). */
|
|
61
|
+
isOverlayCreated(id: number): boolean;
|
|
62
|
+
/** Tombstoned by the overlay this session. True for a source entity the
|
|
63
|
+
* session deleted AND for one it created and then deleted. */
|
|
64
|
+
isDeleted(id: number): boolean;
|
|
65
|
+
/** Outgoing `#id` references of an OVERLAY-created record, or undefined when
|
|
66
|
+
* the id has source bytes to scan instead. */
|
|
67
|
+
refsOf(id: number): readonly number[] | undefined;
|
|
68
|
+
/** Effective UPPERCASE-type → ids index: tombstones removed, retypes moved to
|
|
69
|
+
* their new class, overlay creations added. */
|
|
70
|
+
readonly byType: Map<string, number[]>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Build the effective view over a store plus its overlay.
|
|
74
|
+
*
|
|
75
|
+
* Passing no view, or `applyMutations: false`, returns the source view
|
|
76
|
+
* unchanged — the same object `getCompleteEntityIndex` would hand back, with no
|
|
77
|
+
* per-entity wrapper and no extra allocation on the common export path. An
|
|
78
|
+
* overlay that has queued nothing structural (no creates, no deletes, no
|
|
79
|
+
* retypes) takes the same fast path: attribute and property edits do not change
|
|
80
|
+
* which entities exist or what class they are.
|
|
81
|
+
*/
|
|
82
|
+
export declare function getEffectiveEntityIndex(dataStore: IfcDataStore, mutationView: MutablePropertyView | null | undefined, applyMutations: boolean): EffectiveEntityIndex;
|
|
83
|
+
/**
|
|
84
|
+
* Every express id an AUTHORED attribute value references, recursing into lists.
|
|
85
|
+
*
|
|
86
|
+
* `'#42'` is the documented `StoreEditor.addEntity` form for a reference; a
|
|
87
|
+
* value that merely contains one ('detail #999') is text, and a bare number is a
|
|
88
|
+
* measure, not an id. That is the same distinction the byte scanner makes for
|
|
89
|
+
* source records, and the reason this cannot be shared with the source path:
|
|
90
|
+
* there a reference IS a number, because the parser already resolved it.
|
|
91
|
+
*/
|
|
92
|
+
export declare function authoredEntityRefs(value: IfcAttributeValue | string | undefined): number[];
|
|
93
|
+
//# sourceMappingURL=effective-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-index.d.ts","sourceRoot":"","sources":["../src/effective-index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D;qEACiE;IACjE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACtD,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC;mEAC+D;IAC/D,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B;mDAC+C;IAC/C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD;oDACgD;IAChD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EACpD,cAAc,EAAE,OAAO,GACtB,oBAAoB,CAiBtB;AA2KD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAQ1F"}
|