@ifc-lite/export 2.9.4 → 3.0.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/csv-cell.d.ts +101 -0
- package/dist/csv-cell.d.ts.map +1 -0
- package/dist/csv-cell.js +90 -0
- package/dist/csv-cell.js.map +1 -0
- package/dist/declared-property-type.d.ts +19 -8
- package/dist/declared-property-type.d.ts.map +1 -1
- package/dist/declared-property-type.js +31 -9
- package/dist/declared-property-type.js.map +1 -1
- package/dist/demesh-session.d.ts.map +1 -1
- package/dist/demesh-session.js +2 -1
- package/dist/demesh-session.js.map +1 -1
- package/dist/effective-index.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/lod1-generator.d.ts +0 -2
- package/dist/lod1-generator.d.ts.map +1 -1
- package/dist/lod1-generator.js +1 -1
- package/dist/lod1-generator.js.map +1 -1
- package/dist/merged-exporter.d.ts +19 -0
- package/dist/merged-exporter.d.ts.map +1 -1
- package/dist/merged-exporter.js +23 -41
- package/dist/merged-exporter.js.map +1 -1
- package/dist/parquet-exporter.d.ts +1 -3
- package/dist/parquet-exporter.d.ts.map +1 -1
- package/dist/parquet-exporter.js +1 -0
- package/dist/parquet-exporter.js.map +1 -1
- package/dist/property-value-serialization.d.ts +54 -0
- package/dist/property-value-serialization.d.ts.map +1 -0
- package/dist/property-value-serialization.js +134 -0
- package/dist/property-value-serialization.js.map +1 -0
- package/dist/reference-collector.d.ts +20 -0
- package/dist/reference-collector.d.ts.map +1 -1
- package/dist/reference-collector.js +46 -113
- package/dist/reference-collector.js.map +1 -1
- package/dist/schema-converter.d.ts.map +1 -1
- package/dist/schema-converter.js +46 -96
- package/dist/schema-converter.js.map +1 -1
- package/dist/source-ref-bounds.d.ts +3 -3
- package/dist/source-ref-bounds.js +3 -3
- package/dist/step-attribute-mutations.d.ts +49 -0
- package/dist/step-attribute-mutations.d.ts.map +1 -0
- package/dist/step-attribute-mutations.js +172 -0
- package/dist/step-attribute-mutations.js.map +1 -0
- package/dist/step-attribute-serializers.d.ts +41 -0
- package/dist/step-attribute-serializers.d.ts.map +1 -0
- package/dist/step-attribute-serializers.js +74 -0
- package/dist/step-attribute-serializers.js.map +1 -0
- package/dist/step-collection.d.ts +55 -0
- package/dist/step-collection.d.ts.map +1 -0
- package/dist/step-collection.js +126 -0
- package/dist/step-collection.js.map +1 -0
- package/dist/step-export-contexts.d.ts +61 -0
- package/dist/step-export-contexts.d.ts.map +1 -0
- package/dist/step-export-contexts.js +50 -0
- package/dist/step-export-contexts.js.map +1 -0
- package/dist/step-export-types.d.ts +262 -0
- package/dist/step-export-types.d.ts.map +1 -0
- package/dist/step-export-types.js +22 -0
- package/dist/step-export-types.js.map +1 -0
- package/dist/step-exporter.d.ts +23 -354
- package/dist/step-exporter.d.ts.map +1 -1
- package/dist/step-exporter.js +76 -1260
- package/dist/step-exporter.js.map +1 -1
- package/dist/step-geometry-types.d.ts +3 -0
- package/dist/step-geometry-types.d.ts.map +1 -0
- package/dist/step-geometry-types.js +73 -0
- package/dist/step-geometry-types.js.map +1 -0
- package/dist/step-georeferencing.d.ts +0 -10
- package/dist/step-georeferencing.d.ts.map +1 -1
- package/dist/step-georeferencing.js +46 -94
- package/dist/step-georeferencing.js.map +1 -1
- package/dist/step-header.d.ts +53 -0
- package/dist/step-header.d.ts.map +1 -0
- package/dist/step-header.js +63 -0
- package/dist/step-header.js.map +1 -0
- package/dist/step-map-unit.d.ts +90 -0
- package/dist/step-map-unit.d.ts.map +1 -0
- package/dist/step-map-unit.js +277 -0
- package/dist/step-map-unit.js.map +1 -0
- package/dist/step-omission-predicates.d.ts +51 -0
- package/dist/step-omission-predicates.d.ts.map +1 -0
- package/dist/step-omission-predicates.js +268 -0
- package/dist/step-omission-predicates.js.map +1 -0
- package/dist/step-overlay-attribute-overrides.d.ts +32 -0
- package/dist/step-overlay-attribute-overrides.d.ts.map +1 -0
- package/dist/step-overlay-attribute-overrides.js +83 -0
- package/dist/step-overlay-attribute-overrides.js.map +1 -0
- package/dist/step-overlay-entities.d.ts +64 -0
- package/dist/step-overlay-entities.d.ts.map +1 -0
- package/dist/step-overlay-entities.js +119 -0
- package/dist/step-overlay-entities.js.map +1 -0
- package/dist/step-pass-builder.d.ts +45 -0
- package/dist/step-pass-builder.d.ts.map +1 -0
- package/dist/step-pass-builder.js +249 -0
- package/dist/step-pass-builder.js.map +1 -0
- package/dist/step-property-set-collection.d.ts +24 -0
- package/dist/step-property-set-collection.d.ts.map +1 -0
- package/dist/step-property-set-collection.js +286 -0
- package/dist/step-property-set-collection.js.map +1 -0
- package/dist/step-property-set-generators.d.ts +20 -0
- package/dist/step-property-set-generators.d.ts.map +1 -0
- package/dist/step-property-set-generators.js +98 -0
- package/dist/step-property-set-generators.js.map +1 -0
- package/dist/step-property-set-index.d.ts +25 -0
- package/dist/step-property-set-index.d.ts.map +1 -0
- package/dist/step-property-set-index.js +69 -0
- package/dist/step-property-set-index.js.map +1 -0
- package/dist/step-property-set-readers.d.ts +158 -0
- package/dist/step-property-set-readers.d.ts.map +1 -0
- package/dist/step-property-set-readers.js +251 -0
- package/dist/step-property-set-readers.js.map +1 -0
- package/dist/step-property-sets.d.ts +2 -184
- package/dist/step-property-sets.d.ts.map +1 -1
- package/dist/step-property-sets.js +22 -674
- package/dist/step-property-sets.js.map +1 -1
- package/dist/step-serialization.d.ts +33 -52
- package/dist/step-serialization.d.ts.map +1 -1
- package/dist/step-serialization.js +69 -131
- package/dist/step-serialization.js.map +1 -1
- package/dist/step-source-iteration.d.ts +97 -0
- package/dist/step-source-iteration.d.ts.map +1 -0
- package/dist/step-source-iteration.js +178 -0
- package/dist/step-source-iteration.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
2
|
+
import type { IfcSchemaVersion } from './schema-converter.js';
|
|
3
|
+
import type { SourceLineMutations } from './step-exporter.js';
|
|
4
|
+
/**
|
|
5
|
+
* THE mutation pipeline for a line read out of the source buffer: retype,
|
|
6
|
+
* then named attribute edits, then positional edits.
|
|
7
|
+
*
|
|
8
|
+
* **One implementation, two call sites**, and that is the whole point. Two
|
|
9
|
+
* passes can write the defining line of a source entity — the
|
|
10
|
+
* source-iteration pass, and the type-object `HasPropertySets` rewrite that
|
|
11
|
+
* REPLACES it (`rewrittenEntityIds` makes the source pass skip those ids).
|
|
12
|
+
* The rewrite used to do its own thing (replace slot 5, nothing else), so
|
|
13
|
+
* every other edit to a type object with a type-owned pset edit was dropped
|
|
14
|
+
* in silence: first the renames (#2462 follow-up), and after those were
|
|
15
|
+
* special-cased here, still the retypes and the positional edits. Whatever
|
|
16
|
+
* the source pass applies, the rewrite has to apply too, or the next edit
|
|
17
|
+
* kind added to one site goes missing at the other.
|
|
18
|
+
*
|
|
19
|
+
* The order is load-bearing:
|
|
20
|
+
*
|
|
21
|
+
* - the retype runs FIRST so named attribute edits resolve against the
|
|
22
|
+
* TARGET class's attribute names, and so positional slots are indexed
|
|
23
|
+
* into the retyped argument list;
|
|
24
|
+
* - the `HasPropertySets` replacement (rewrite path only) runs LAST, on
|
|
25
|
+
* the text this returns. Run it first and a positional edit to slot 5 —
|
|
26
|
+
* or a retype's argument-list rebuild — overwrites the resolved pset
|
|
27
|
+
* list with the stale one, which is the same silent drop one slot over.
|
|
28
|
+
*
|
|
29
|
+
* The expressId is unchanged by all of this, so geometry / placement /
|
|
30
|
+
* representation and every IfcRel* reference (keyed by #id) carry over.
|
|
31
|
+
*
|
|
32
|
+
* All three flags report EFFECT, not intent — each is the answer to "did this
|
|
33
|
+
* operation change the line", measured across that operation alone. The count
|
|
34
|
+
* and the ledger are claims about the FILE, so an edit that resolves to the
|
|
35
|
+
* text already there has delivered nothing and must not be reported: retyping
|
|
36
|
+
* an entity to the class it already is, or writing a positional slot the token
|
|
37
|
+
* it already holds, used to count as a modification and reach the ledger as a
|
|
38
|
+
* landed edit, over a byte-identical line. Discarded edits read the same way:
|
|
39
|
+
* `applyAttributeMutations` drops a name its class has no slot for and
|
|
40
|
+
* `retypeStepLine` returns an unparseable line untouched, and neither is a
|
|
41
|
+
* modification of anything.
|
|
42
|
+
*
|
|
43
|
+
* `retyped` / `positional` matter most in a FULL export, which is where the
|
|
44
|
+
* two are nominated (their edits have no earlier nomination site); named
|
|
45
|
+
* attribute edits are nominated by the collection pass and `attributed` only
|
|
46
|
+
* settles their delivery.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applySourceLineMutations(mutationView: MutablePropertyView | null, expressId: number, entityText: string, recordType: string, attributeMutations: Map<string, string> | undefined, sourceSchema: IfcSchemaVersion, overlayActive: boolean, onRejected?: (attrName: string, value: string) => void): SourceLineMutations;
|
|
49
|
+
//# sourceMappingURL=step-attribute-mutations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-attribute-mutations.d.ts","sourceRoot":"","sources":["../src/step-attribute-mutations.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,mBAAmB,GAAG,IAAI,EACxC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACnD,YAAY,EAAE,gBAAgB,EAC9B,aAAa,EAAE,OAAO,EACtB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACrD,mBAAmB,CAmDrB"}
|
|
@@ -0,0 +1,172 @@
|
|
|
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
|
+
* THE source-buffer attribute-mutation pipeline: retype, then named
|
|
6
|
+
* attribute edits, then positional edits, applied to a line read out of the
|
|
7
|
+
* STEP source. Both {@link applySourceLineMutations}'s call sites — the
|
|
8
|
+
* source-iteration pass and the type-object `HasPropertySets` rewrite that
|
|
9
|
+
* REPLACES it — are documented on the function itself.
|
|
10
|
+
*
|
|
11
|
+
* This file used to also hold the overlay-created sibling pipeline and the
|
|
12
|
+
* two per-slot serialize helpers both pipelines share; #3184 split those out
|
|
13
|
+
* along the line this module's own doc already drew — the overlay-created
|
|
14
|
+
* pipeline is now `step-overlay-attribute-overrides.ts`, and the shared
|
|
15
|
+
* serializers are `step-attribute-serializers.ts`.
|
|
16
|
+
*/
|
|
17
|
+
import { splitTopLevelArgs } from './step-argument-parser.js';
|
|
18
|
+
import { getRealTypedSlots } from './attribute-real-slots.js';
|
|
19
|
+
import { retypeStepLine } from './retype.js';
|
|
20
|
+
import { getAttributeNamesAcrossSchemas } from '@ifc-lite/parser';
|
|
21
|
+
import { serializeNamedAttribute, serializePositionalOverride } from './step-attribute-serializers.js';
|
|
22
|
+
/**
|
|
23
|
+
* THE mutation pipeline for a line read out of the source buffer: retype,
|
|
24
|
+
* then named attribute edits, then positional edits.
|
|
25
|
+
*
|
|
26
|
+
* **One implementation, two call sites**, and that is the whole point. Two
|
|
27
|
+
* passes can write the defining line of a source entity — the
|
|
28
|
+
* source-iteration pass, and the type-object `HasPropertySets` rewrite that
|
|
29
|
+
* REPLACES it (`rewrittenEntityIds` makes the source pass skip those ids).
|
|
30
|
+
* The rewrite used to do its own thing (replace slot 5, nothing else), so
|
|
31
|
+
* every other edit to a type object with a type-owned pset edit was dropped
|
|
32
|
+
* in silence: first the renames (#2462 follow-up), and after those were
|
|
33
|
+
* special-cased here, still the retypes and the positional edits. Whatever
|
|
34
|
+
* the source pass applies, the rewrite has to apply too, or the next edit
|
|
35
|
+
* kind added to one site goes missing at the other.
|
|
36
|
+
*
|
|
37
|
+
* The order is load-bearing:
|
|
38
|
+
*
|
|
39
|
+
* - the retype runs FIRST so named attribute edits resolve against the
|
|
40
|
+
* TARGET class's attribute names, and so positional slots are indexed
|
|
41
|
+
* into the retyped argument list;
|
|
42
|
+
* - the `HasPropertySets` replacement (rewrite path only) runs LAST, on
|
|
43
|
+
* the text this returns. Run it first and a positional edit to slot 5 —
|
|
44
|
+
* or a retype's argument-list rebuild — overwrites the resolved pset
|
|
45
|
+
* list with the stale one, which is the same silent drop one slot over.
|
|
46
|
+
*
|
|
47
|
+
* The expressId is unchanged by all of this, so geometry / placement /
|
|
48
|
+
* representation and every IfcRel* reference (keyed by #id) carry over.
|
|
49
|
+
*
|
|
50
|
+
* All three flags report EFFECT, not intent — each is the answer to "did this
|
|
51
|
+
* operation change the line", measured across that operation alone. The count
|
|
52
|
+
* and the ledger are claims about the FILE, so an edit that resolves to the
|
|
53
|
+
* text already there has delivered nothing and must not be reported: retyping
|
|
54
|
+
* an entity to the class it already is, or writing a positional slot the token
|
|
55
|
+
* it already holds, used to count as a modification and reach the ledger as a
|
|
56
|
+
* landed edit, over a byte-identical line. Discarded edits read the same way:
|
|
57
|
+
* `applyAttributeMutations` drops a name its class has no slot for and
|
|
58
|
+
* `retypeStepLine` returns an unparseable line untouched, and neither is a
|
|
59
|
+
* modification of anything.
|
|
60
|
+
*
|
|
61
|
+
* `retyped` / `positional` matter most in a FULL export, which is where the
|
|
62
|
+
* two are nominated (their edits have no earlier nomination site); named
|
|
63
|
+
* attribute edits are nominated by the collection pass and `attributed` only
|
|
64
|
+
* settles their delivery.
|
|
65
|
+
*/
|
|
66
|
+
export function applySourceLineMutations(mutationView, expressId, entityText, recordType, attributeMutations, sourceSchema, overlayActive, onRejected) {
|
|
67
|
+
let text = entityText;
|
|
68
|
+
let workingType = recordType.toUpperCase();
|
|
69
|
+
const typeMutation = overlayActive && typeof mutationView.getEntityTypeMutation === 'function'
|
|
70
|
+
? mutationView.getEntityTypeMutation(expressId)
|
|
71
|
+
: null;
|
|
72
|
+
let retyped = false;
|
|
73
|
+
if (typeMutation) {
|
|
74
|
+
const beforeRetype = text;
|
|
75
|
+
text = retypeStepLine(text, recordType, typeMutation.newType, typeMutation.predefinedType ?? null, sourceSchema);
|
|
76
|
+
retyped = text !== beforeRetype;
|
|
77
|
+
// Set even for a no-op retype: the entity IS the target class from here
|
|
78
|
+
// on, so the named and positional edits below must resolve against it.
|
|
79
|
+
workingType = typeMutation.newType.toUpperCase();
|
|
80
|
+
}
|
|
81
|
+
// `applyAttributeMutations` returns its input UNCHANGED when it wrote
|
|
82
|
+
// nothing — no slot resolved for any of the names, or the line does not
|
|
83
|
+
// parse — so comparing is what tells the ledger whether a named attribute
|
|
84
|
+
// edit was really carried, rather than merely attempted.
|
|
85
|
+
let attributed = false;
|
|
86
|
+
if (attributeMutations && attributeMutations.size > 0) {
|
|
87
|
+
const beforeAttributes = text;
|
|
88
|
+
text = applyAttributeMutations(text, workingType, attributeMutations, sourceSchema, onRejected);
|
|
89
|
+
attributed = text !== beforeAttributes;
|
|
90
|
+
}
|
|
91
|
+
const positionals = overlayActive && typeof mutationView.getPositionalMutationsForEntity === 'function'
|
|
92
|
+
? mutationView.getPositionalMutationsForEntity(expressId)
|
|
93
|
+
: null;
|
|
94
|
+
let positional = false;
|
|
95
|
+
if (positionals && positionals.size > 0) {
|
|
96
|
+
const beforePositionals = text;
|
|
97
|
+
text = applyPositionalMutations(text, positionals, workingType, sourceSchema);
|
|
98
|
+
positional = text !== beforePositionals;
|
|
99
|
+
}
|
|
100
|
+
return { text, attributed, retyped, positional };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Rewrite root IFC attributes directly on the original STEP entity line.
|
|
104
|
+
*/
|
|
105
|
+
function applyAttributeMutations(entityText, entityType, attributeMutations, schemaVersion, onRejected) {
|
|
106
|
+
const openParen = entityText.indexOf('(');
|
|
107
|
+
const closeParen = entityText.lastIndexOf(');');
|
|
108
|
+
if (openParen < 0 || closeParen < openParen) {
|
|
109
|
+
return entityText;
|
|
110
|
+
}
|
|
111
|
+
// Cross-schema, not the IFC4 pin: an IFC4X3-only class (IfcCourse, IfcRoad,
|
|
112
|
+
// IfcBridge, …) resolves no slots under the pin, so every named edit on one
|
|
113
|
+
// was silently discarded here too. Identical for the 755 pinned classes
|
|
114
|
+
// that declare attributes — `attribute-slot-types.test.ts` measures that —
|
|
115
|
+
// so no IFC4 export changes; this only stops dropping edits it used to drop.
|
|
116
|
+
const attrNames = getAttributeNamesAcrossSchemas(entityType);
|
|
117
|
+
if (attrNames.length === 0) {
|
|
118
|
+
return entityText;
|
|
119
|
+
}
|
|
120
|
+
const args = splitTopLevelArgs(entityText.slice(openParen + 1, closeParen));
|
|
121
|
+
// A source line NEVER pads (unlike the overlay-created path): a short
|
|
122
|
+
// argument list here means the file speaks a different schema, and growing
|
|
123
|
+
// a record we did not author would corrupt it.
|
|
124
|
+
let changed = false;
|
|
125
|
+
const realSlots = getRealTypedSlots(entityType, schemaVersion);
|
|
126
|
+
for (const [attrName, value] of attributeMutations) {
|
|
127
|
+
const index = attrNames.indexOf(attrName);
|
|
128
|
+
if (index < 0 || index >= args.length)
|
|
129
|
+
continue;
|
|
130
|
+
// The source path shares every `$`-slot hole with the overlay-created
|
|
131
|
+
// path, because a source record has plenty of `$` slots of its own. Both
|
|
132
|
+
// go through the one helper below.
|
|
133
|
+
const serialized = serializeNamedAttribute(entityType, index, value, args[index], realSlots);
|
|
134
|
+
if (serialized === null) {
|
|
135
|
+
// Slot untouched AND reported. Not counted as a change: claiming a
|
|
136
|
+
// modification we did not make is the failure this avoids.
|
|
137
|
+
onRejected?.(attrName, value);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
args[index] = serialized;
|
|
141
|
+
changed = true;
|
|
142
|
+
}
|
|
143
|
+
if (!changed) {
|
|
144
|
+
return entityText;
|
|
145
|
+
}
|
|
146
|
+
return `${entityText.slice(0, openParen + 1)}${args.join(',')}${entityText.slice(closeParen)}`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Apply positional STEP argument overrides to an entity line.
|
|
150
|
+
* Used for non-IfcRoot edits (e.g. profile dimensions) where attributes
|
|
151
|
+
* have no symbolic names. Indexes that fall outside the existing arg list
|
|
152
|
+
* are silently ignored.
|
|
153
|
+
*/
|
|
154
|
+
function applyPositionalMutations(entityText, positionals, entityType, schemaVersion) {
|
|
155
|
+
const openParen = entityText.indexOf('(');
|
|
156
|
+
const closeParen = entityText.lastIndexOf(');');
|
|
157
|
+
if (openParen < 0 || closeParen < openParen)
|
|
158
|
+
return entityText;
|
|
159
|
+
const args = splitTopLevelArgs(entityText.slice(openParen + 1, closeParen));
|
|
160
|
+
const realSlots = getRealTypedSlots(entityType, schemaVersion);
|
|
161
|
+
let changed = false;
|
|
162
|
+
for (const [index, value] of positionals) {
|
|
163
|
+
if (index < 0 || index >= args.length)
|
|
164
|
+
continue;
|
|
165
|
+
args[index] = serializePositionalOverride(entityType, index, value, args[index], realSlots, schemaVersion);
|
|
166
|
+
changed = true;
|
|
167
|
+
}
|
|
168
|
+
if (!changed)
|
|
169
|
+
return entityText;
|
|
170
|
+
return `${entityText.slice(0, openParen + 1)}${args.join(',')}${entityText.slice(closeParen)}`;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=step-attribute-mutations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-attribute-mutations.js","sourceRoot":"","sources":["../src/step-attribute-mutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two per-slot serialize helpers `step-attribute-mutations.ts`'s
|
|
3
|
+
* source-buffer pipeline and `step-overlay-attribute-overrides.ts`'s
|
|
4
|
+
* overlay-created pipeline both go through — the single point where a named
|
|
5
|
+
* or positional override becomes a STEP token. Split out of
|
|
6
|
+
* `step-attribute-mutations.ts` (#3184).
|
|
7
|
+
*/
|
|
8
|
+
import type { IfcAttributeValue } from '@ifc-lite/parser';
|
|
9
|
+
import type { IfcSchemaVersion } from './schema-converter.js';
|
|
10
|
+
/**
|
|
11
|
+
* Serialize one NAMED attribute override into its slot — the single point
|
|
12
|
+
* both the source-buffer rewrite and the overlay-created rewrite go through.
|
|
13
|
+
*
|
|
14
|
+
* `serializeAttributeValue` decides the STEP form by reading the token being
|
|
15
|
+
* replaced, which is sound only while that token carries type information. A
|
|
16
|
+
* `$` slot carries none, and both paths have plenty: a source record's
|
|
17
|
+
* optional attributes are `$`, and overlay-created records pad missing slots
|
|
18
|
+
* with `$`. So the declared type decides first, and inference is the fallback
|
|
19
|
+
* for slots the schema does not classify (references, SELECTs, numerics),
|
|
20
|
+
* where reading the old token is exactly the right heuristic.
|
|
21
|
+
*
|
|
22
|
+
* Before this REAL check existed, "the declared type decides first" was true
|
|
23
|
+
* for enum/string slots only — a REAL-backed slot (`IfcMapConversion.
|
|
24
|
+
* OrthogonalHeight`, any other `IfcLengthMeasure`/`IfcReal`-typed attribute)
|
|
25
|
+
* fell straight to `serializeAttributeValue`'s token inference, which quotes
|
|
26
|
+
* anything it cannot recognize as numeric. A schema-legal `$` placeholder
|
|
27
|
+
* carries no digits to recognize, so setting such a field for the first time
|
|
28
|
+
* wrote `'12345'` in a slot ISO 10303-21 requires to be an unquoted REAL —
|
|
29
|
+
* silently invalid output (#2724, LTplus-AG/ifc-lite#2475).
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeNamedAttribute(entityType: string, index: number, value: string, currentToken: string, realSlots: ReadonlySet<number>): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Serialize one positional override, composing the schema-aware passes:
|
|
34
|
+
* explicit `{ real }`/`{ typed }` marker → SELECT auto-qualification
|
|
35
|
+
* (`IFCBOOLEAN(.T.)`) → REAL forcing. For REAL forcing the current source
|
|
36
|
+
* token is a secondary signal: replacing a value that was already a REAL
|
|
37
|
+
* (`0.4`, `1.5E-7`) keeps it REAL even for entities the XSD index doesn't
|
|
38
|
+
* cover, so a whole-number edit can't silently downgrade the slot.
|
|
39
|
+
*/
|
|
40
|
+
export declare function serializePositionalOverride(entityType: string, index: number, value: IfcAttributeValue, currentToken: string, realSlots: ReadonlySet<number>, schemaVersion: IfcSchemaVersion): string;
|
|
41
|
+
//# sourceMappingURL=step-attribute-serializers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-attribute-serializers.d.ts","sourceRoot":"","sources":["../src/step-attribute-serializers.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAU1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,GAAG,IAAI,CAuBf;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,EAC9B,aAAa,EAAE,gBAAgB,GAC9B,MAAM,CAMR"}
|
|
@@ -0,0 +1,74 @@
|
|
|
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
|
+
import { getEnumTypedSlots, getStringTypedSlots, serializeEnumToken, serializeStringSlot } from './attribute-slot-types.js';
|
|
5
|
+
import { isTypedMarker } from './attribute-real-slots.js';
|
|
6
|
+
import { serializeQualifiedSelectSlot } from './select-qualification.js';
|
|
7
|
+
import { toStepReal, serializeAttributeValue, serializeStepValue, tokenIsRealLiteral, } from './step-serialization.js';
|
|
8
|
+
/**
|
|
9
|
+
* Serialize one NAMED attribute override into its slot — the single point
|
|
10
|
+
* both the source-buffer rewrite and the overlay-created rewrite go through.
|
|
11
|
+
*
|
|
12
|
+
* `serializeAttributeValue` decides the STEP form by reading the token being
|
|
13
|
+
* replaced, which is sound only while that token carries type information. A
|
|
14
|
+
* `$` slot carries none, and both paths have plenty: a source record's
|
|
15
|
+
* optional attributes are `$`, and overlay-created records pad missing slots
|
|
16
|
+
* with `$`. So the declared type decides first, and inference is the fallback
|
|
17
|
+
* for slots the schema does not classify (references, SELECTs, numerics),
|
|
18
|
+
* where reading the old token is exactly the right heuristic.
|
|
19
|
+
*
|
|
20
|
+
* Before this REAL check existed, "the declared type decides first" was true
|
|
21
|
+
* for enum/string slots only — a REAL-backed slot (`IfcMapConversion.
|
|
22
|
+
* OrthogonalHeight`, any other `IfcLengthMeasure`/`IfcReal`-typed attribute)
|
|
23
|
+
* fell straight to `serializeAttributeValue`'s token inference, which quotes
|
|
24
|
+
* anything it cannot recognize as numeric. A schema-legal `$` placeholder
|
|
25
|
+
* carries no digits to recognize, so setting such a field for the first time
|
|
26
|
+
* wrote `'12345'` in a slot ISO 10303-21 requires to be an unquoted REAL —
|
|
27
|
+
* silently invalid output (#2724, LTplus-AG/ifc-lite#2475).
|
|
28
|
+
*/
|
|
29
|
+
export function serializeNamedAttribute(entityType, index, value, currentToken, realSlots) {
|
|
30
|
+
if (getEnumTypedSlots(entityType).has(index))
|
|
31
|
+
return serializeEnumToken(value);
|
|
32
|
+
if (getStringTypedSlots(entityType).has(index))
|
|
33
|
+
return serializeStringSlot(value);
|
|
34
|
+
if (realSlots.has(index)) {
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
if (trimmed === '')
|
|
37
|
+
return '$';
|
|
38
|
+
const numberValue = Number(trimmed);
|
|
39
|
+
if (Number.isFinite(numberValue))
|
|
40
|
+
return toStepReal(numberValue);
|
|
41
|
+
// A non-numeric value in a REAL slot used to fall through and be QUOTED,
|
|
42
|
+
// producing the same ISO 10303-21 violation #2725 exists to prevent
|
|
43
|
+
// (#2741). `StoreEditor.setAttribute` takes a string, so any UI text
|
|
44
|
+
// field bound to a georeferencing REAL can deliver one; it does not need
|
|
45
|
+
// a corrupt file.
|
|
46
|
+
//
|
|
47
|
+
// `null` means "leave the slot as the file had it". Simply returning
|
|
48
|
+
// `currentToken` here would stop the invalid output but SILENTLY DISCARD
|
|
49
|
+
// the edit - the exporter would then claim a modification it did not
|
|
50
|
+
// carry, which is the exact misreport #2723/#2724/#2726 were written to
|
|
51
|
+
// pin. The caller turns this into a warning, so a dropped edit is visible
|
|
52
|
+
// rather than inferred from absence.
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return serializeAttributeValue(value, currentToken);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Serialize one positional override, composing the schema-aware passes:
|
|
59
|
+
* explicit `{ real }`/`{ typed }` marker → SELECT auto-qualification
|
|
60
|
+
* (`IFCBOOLEAN(.T.)`) → REAL forcing. For REAL forcing the current source
|
|
61
|
+
* token is a secondary signal: replacing a value that was already a REAL
|
|
62
|
+
* (`0.4`, `1.5E-7`) keeps it REAL even for entities the XSD index doesn't
|
|
63
|
+
* cover, so a whole-number edit can't silently downgrade the slot.
|
|
64
|
+
*/
|
|
65
|
+
export function serializePositionalOverride(entityType, index, value, currentToken, realSlots, schemaVersion) {
|
|
66
|
+
if (isTypedMarker(value))
|
|
67
|
+
return serializeStepValue(value);
|
|
68
|
+
const qualified = serializeQualifiedSelectSlot(entityType, index, value);
|
|
69
|
+
if (qualified !== null)
|
|
70
|
+
return qualified;
|
|
71
|
+
const forceReal = realSlots.has(index) || tokenIsRealLiteral(currentToken);
|
|
72
|
+
return serializeStepValue(value, forceReal);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=step-attribute-serializers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-attribute-serializers.js","sourceRoot":"","sources":["../src/step-attribute-serializers.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAW/D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC5H,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,KAAa,EACb,KAAa,EACb,YAAoB,EACpB,SAA8B;IAE9B,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC/E,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAClF,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,GAAG,CAAC;QAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;QACjE,yEAAyE;QACzE,oEAAoE;QACpE,qEAAqE;QACrE,yEAAyE;QACzE,kBAAkB;QAClB,EAAE;QACF,qEAAqE;QACrE,yEAAyE;QACzE,qEAAqE;QACrE,wEAAwE;QACxE,0EAA0E;QAC1E,qCAAqC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,uBAAuB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CACzC,UAAkB,EAClB,KAAa,EACb,KAAwB,EACxB,YAAoB,EACpB,SAA8B,EAC9B,aAA+B;IAE/B,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,4BAA4B,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACzE,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC3E,OAAO,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The collection phase of `StepExporter.export()` (#2475, the collection
|
|
3
|
+
* block): builds the visible-only closure (`pass.allowedEntityIds` /
|
|
4
|
+
* `hiddenProductIds`), groups the overlay's mutation history by entity and
|
|
5
|
+
* kind, and applies the georeferencing edits. Nothing here WRITES a STEP
|
|
6
|
+
* line — every write happens in a later phase (`step-source-iteration.ts`,
|
|
7
|
+
* `step-property-sets.ts`, `step-georeferencing.ts`'s own new-entity lines,
|
|
8
|
+
* `step-overlay-entities.ts`) that reads what this phase left on `pass`.
|
|
9
|
+
*
|
|
10
|
+
* `PropertyMutationGroups` (`step-property-set-collection.ts`) already names the
|
|
11
|
+
* boundary this module sits behind: "the mutation groupings `export()`
|
|
12
|
+
* builds before the collection phase runs." This is that builder, plus the
|
|
13
|
+
* two collection calls (`buildRelDefinesByPropertiesIndex` /
|
|
14
|
+
* `collectPropertyAndQuantitySetMutations`) it was already handing them to.
|
|
15
|
+
*
|
|
16
|
+
* `hasAnyUnreadableSourceRef` and the `mayNameOmittedRefs` /
|
|
17
|
+
* `isOmittedFromOutput` predicates it feeds do NOT live here: they read
|
|
18
|
+
* `pass.effective` and this phase's OUTPUT (`allowedEntityIds`,
|
|
19
|
+
* `overlayActive`), but nothing in THIS module reads them back, so moving them
|
|
20
|
+
* here would not shrink a dependency, only relocate it. That argument was
|
|
21
|
+
* always about this module specifically. They live in
|
|
22
|
+
* `step-omission-predicates.ts`, called from `export()` immediately after this
|
|
23
|
+
* phase returns (#2475).
|
|
24
|
+
*/
|
|
25
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
26
|
+
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
27
|
+
import { type PropertySetContext } from './step-property-set-readers.js';
|
|
28
|
+
import { type GeorefContext } from './step-georeferencing.js';
|
|
29
|
+
import type { ExportPass, StepExportOptions } from './step-exporter.js';
|
|
30
|
+
/**
|
|
31
|
+
* The exporter state this phase cannot read off the pass.
|
|
32
|
+
*
|
|
33
|
+
* `propertySetContext` and `georefContext` are thunks, not values, matching
|
|
34
|
+
* every other call site of theirs in `export()`: this phase calls
|
|
35
|
+
* `propertySetContext()` twice (once for `buildRelDefinesByPropertiesIndex`,
|
|
36
|
+
* once for `collectPropertyAndQuantitySetMutations`) and moving that call
|
|
37
|
+
* out from under the two sites — deriving one value up front instead —
|
|
38
|
+
* would be a behaviour change nothing here asked for.
|
|
39
|
+
*/
|
|
40
|
+
export interface CollectionContext {
|
|
41
|
+
readonly dataStore: IfcDataStore;
|
|
42
|
+
readonly mutationView: MutablePropertyView | null;
|
|
43
|
+
readonly propertySetContext: () => PropertySetContext;
|
|
44
|
+
readonly georefContext: (deltaOnly: boolean) => GeorefContext;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Populate `pass` with everything the overlay's edits and `options` imply,
|
|
48
|
+
* in place. The caller owns three gates and this phase does not re-derive
|
|
49
|
+
* any of them: `applyMutations` (`options.applyMutations !== false`, read
|
|
50
|
+
* once in `export()` — see the "read ONCE" comment there for why a second
|
|
51
|
+
* read would be a bug, not a style choice), `options.visibleOnly`, and
|
|
52
|
+
* `options.georefMutations`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function collectModifications(pass: ExportPass, options: StepExportOptions, applyMutations: boolean, ctx: CollectionContext): void;
|
|
55
|
+
//# sourceMappingURL=step-collection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-collection.d.ts","sourceRoot":"","sources":["../src/step-collection.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAExE;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;IACtD,QAAQ,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,aAAa,CAAC;CAC/D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,OAAO,EACvB,GAAG,EAAE,iBAAiB,GACrB,IAAI,CAsIN"}
|
|
@@ -0,0 +1,126 @@
|
|
|
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
|
+
import { collectReferencedEntityIds, getVisibleEntityIds, collectStyleEntities } from './reference-collector.js';
|
|
5
|
+
import { buildRelDefinesByPropertiesIndex } from './step-property-set-index.js';
|
|
6
|
+
import { collectPropertyAndQuantitySetMutations } from './step-property-set-collection.js';
|
|
7
|
+
import { applyGeoreferencingMutations } from './step-georeferencing.js';
|
|
8
|
+
/**
|
|
9
|
+
* Populate `pass` with everything the overlay's edits and `options` imply,
|
|
10
|
+
* in place. The caller owns three gates and this phase does not re-derive
|
|
11
|
+
* any of them: `applyMutations` (`options.applyMutations !== false`, read
|
|
12
|
+
* once in `export()` — see the "read ONCE" comment there for why a second
|
|
13
|
+
* read would be a bug, not a style choice), `options.visibleOnly`, and
|
|
14
|
+
* `options.georefMutations`.
|
|
15
|
+
*/
|
|
16
|
+
export function collectModifications(pass, options, applyMutations, ctx) {
|
|
17
|
+
if (options.visibleOnly && ctx.dataStore.source) {
|
|
18
|
+
const visible = getVisibleEntityIds(ctx.dataStore, options.hiddenEntityIds ?? new Set(), options.isolatedEntityIds ?? null, pass.effective);
|
|
19
|
+
pass.hiddenProductIds = visible.hiddenProductIds;
|
|
20
|
+
pass.allowedEntityIds = collectReferencedEntityIds(visible.roots, ctx.dataStore.source, pass.effective, visible.hiddenProductIds, pass.isRefExcludedDuringClosureWalk);
|
|
21
|
+
// Second pass: collect IFCSTYLEDITEM entities that reference included
|
|
22
|
+
// geometry. Styled items reference geometry items but nothing references
|
|
23
|
+
// them back, so the forward closure misses them.
|
|
24
|
+
collectStyleEntities(pass.allowedEntityIds, ctx.dataStore.source, { byId: pass.effective, byType: pass.effective.byType });
|
|
25
|
+
}
|
|
26
|
+
// Process mutations if we have a mutation view
|
|
27
|
+
if (ctx.mutationView && applyMutations) {
|
|
28
|
+
const mutationView = ctx.mutationView;
|
|
29
|
+
const mutations = mutationView.getMutations();
|
|
30
|
+
// Attribute values come from the *overlay*, never from the mutation
|
|
31
|
+
// history. The history is append-only and undo writes its reverse edit
|
|
32
|
+
// with `skipHistory: true`, so a superseded UPDATE_ATTRIBUTE record keeps
|
|
33
|
+
// its stale `newValue` forever — replaying it resurrects edits the user
|
|
34
|
+
// undid (#1957). The overlay is what the editor shows, and it is already
|
|
35
|
+
// the source for psets, quantities, positional attributes and retypes
|
|
36
|
+
// below, so attributes were the sole outlier.
|
|
37
|
+
for (const [entityId, attrs] of mutationView.getAttributeMutationsByEntity()) {
|
|
38
|
+
pass.modifiedEntities.add(entityId);
|
|
39
|
+
let target = pass.modifiedAttributes.get(entityId);
|
|
40
|
+
if (!target) {
|
|
41
|
+
target = new Map();
|
|
42
|
+
pass.modifiedAttributes.set(entityId, target);
|
|
43
|
+
}
|
|
44
|
+
for (const [name, value] of attrs)
|
|
45
|
+
target.set(name, value);
|
|
46
|
+
}
|
|
47
|
+
// Group mutations by entity, separating property vs quantity mutations
|
|
48
|
+
const entityPropMutations = new Map();
|
|
49
|
+
const entityQuantMutations = new Map();
|
|
50
|
+
for (const mutation of mutations) {
|
|
51
|
+
// Handled above, off the overlay. Skipped explicitly because an
|
|
52
|
+
// UPDATE_ATTRIBUTE record can also carry a `psetName` (georef fields
|
|
53
|
+
// encode their target entity there) and must not be mistaken for a
|
|
54
|
+
// property-set edit.
|
|
55
|
+
if (mutation.type === 'UPDATE_ATTRIBUTE')
|
|
56
|
+
continue;
|
|
57
|
+
if (!mutation.psetName)
|
|
58
|
+
continue;
|
|
59
|
+
const isQuantity = mutation.type === 'CREATE_QUANTITY' || mutation.type === 'UPDATE_QUANTITY'
|
|
60
|
+
|| mutation.type === 'DELETE_QUANTITY' || mutation.type === 'DELETE_QUANTITY_SET';
|
|
61
|
+
const targetMap = isQuantity ? entityQuantMutations : entityPropMutations;
|
|
62
|
+
if (!targetMap.has(mutation.entityId)) {
|
|
63
|
+
targetMap.set(mutation.entityId, new Set());
|
|
64
|
+
}
|
|
65
|
+
targetMap.get(mutation.entityId).add(mutation.psetName);
|
|
66
|
+
}
|
|
67
|
+
// Build a reverse index of IfcRelDefinesByProperties → (relId, psetId)
|
|
68
|
+
// pairs keyed on each related entity. The two property/quantity loops
|
|
69
|
+
// below previously walked every entity in `entityIndex.byId` per
|
|
70
|
+
// modified entity (O(E·N)); the index keeps the per-entity step
|
|
71
|
+
// O(K) where K is the number of rels referencing that entity.
|
|
72
|
+
const { byEntity: relDefinesByEntity, relatedByRel } = buildRelDefinesByPropertiesIndex(ctx.propertySetContext());
|
|
73
|
+
// A source IfcRelDefinesByProperties whose EVERY related object the
|
|
74
|
+
// session deleted has nothing left to relate, and emitting it leaves a
|
|
75
|
+
// `#id` pointing at a record the export skipped. Dropped only when all of
|
|
76
|
+
// them are gone: a rel that still names a live entity is that entity's
|
|
77
|
+
// only link to its psets, and nothing here rewrites a RelatedObjects list.
|
|
78
|
+
for (const [relId, related] of relatedByRel) {
|
|
79
|
+
if (related.length > 0 && related.every((id) => pass.effective.isDeleted(id))) {
|
|
80
|
+
pass.skipRelationshipIds.add(relId);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
collectPropertyAndQuantitySetMutations(pass, options, { entityPropMutations, entityQuantMutations, relDefinesByEntity }, ctx.propertySetContext());
|
|
84
|
+
for (const [entityId] of pass.modifiedAttributes) {
|
|
85
|
+
// An overlay-CREATED entity carrying attribute edits is emitted once,
|
|
86
|
+
// by the new-entities pass, and already counted in `newEntityCount`.
|
|
87
|
+
// Counting it here too made the header claim two affected entities for
|
|
88
|
+
// one created-then-renamed wall.
|
|
89
|
+
if (pass.isOverlayCreated(entityId))
|
|
90
|
+
continue;
|
|
91
|
+
// A source entity with no bytes never gets its line rewritten (the
|
|
92
|
+
// source-iteration pass skips it), so an attribute edit against it
|
|
93
|
+
// must not inflate the count either.
|
|
94
|
+
if (!pass.hasEmittableHostBytes(entityId))
|
|
95
|
+
continue;
|
|
96
|
+
// Under `deltaOnly` this only NOMINATES the host's ATTRIBUTE edits:
|
|
97
|
+
// nothing writes an in-place attribute edit into a delta except the
|
|
98
|
+
// type-object line rewrite, so the ledger drops it at settle time
|
|
99
|
+
// unless that pass reports having carried it (#2462). That nomination
|
|
100
|
+
// is deliberately made at INTENT: the per-kind warning exists to NAME
|
|
101
|
+
// an edit the delta could not carry, and an undeliverable edit is
|
|
102
|
+
// exactly the one that must still be named.
|
|
103
|
+
//
|
|
104
|
+
// A FULL export has no such warning, so an edit that resolved to
|
|
105
|
+
// nothing has nothing to say and nothing to claim — it waits for the
|
|
106
|
+
// rewrite instead. `setAttribute` to the value already in the slot, and
|
|
107
|
+
// `setAttribute` naming a slot the class does not declare, both leave
|
|
108
|
+
// the line byte-identical and used to count anyway (#2483).
|
|
109
|
+
//
|
|
110
|
+
// Recorded unconditionally. It used to be skipped for a host that also
|
|
111
|
+
// had a pset or qset edit, because the count was per entity and the
|
|
112
|
+
// other loop had already nominated it — which is exactly what let a
|
|
113
|
+
// pset emission mark the rename delivered and suppress its warning. The
|
|
114
|
+
// ledger de-duplicates the COUNT per entity now, so the two edits can
|
|
115
|
+
// and must be nominated separately.
|
|
116
|
+
pass.inPlaceNominees.attribute.add(entityId);
|
|
117
|
+
if (options.deltaOnly === true)
|
|
118
|
+
pass.modifications.nominate(entityId, 'attribute');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Process georeferencing mutations (only when applyMutations is enabled)
|
|
122
|
+
if (applyMutations && options.georefMutations) {
|
|
123
|
+
applyGeoreferencingMutations(pass, options.georefMutations, ctx.georefContext(options.deltaOnly === true));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=step-collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-collection.js","sourceRoot":"","sources":["../src/step-collection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-phase contexts that do NOT allocate express ids.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `StepExporter` for #2475. These two are pure forwarders: they
|
|
5
|
+
* assemble what a phase cannot read off the pass, out of values handed to
|
|
6
|
+
* them, and touch no exporter state of their own.
|
|
7
|
+
*
|
|
8
|
+
* WHY ONLY THESE TWO. `georefContext` and `propertySetContext` stay methods on
|
|
9
|
+
* `StepExporter`, and `collectionContext` stays with them because it forwards
|
|
10
|
+
* to both. Those two are the only places that mint express ids, via
|
|
11
|
+
* `allocateExpressId: () => this.nextExpressId++` — two closures over ONE
|
|
12
|
+
* instance counter. Moving them would mean re-establishing that shared
|
|
13
|
+
* identity through a parameter, and capturing the counter's value instead of
|
|
14
|
+
* its closure gives each builder its own sequence, silently emitting two
|
|
15
|
+
* entities with the same `#N` — well-formed STEP in which every reference
|
|
16
|
+
* still resolves, and two different entities.
|
|
17
|
+
*
|
|
18
|
+
* That failure used to be invisible: `findDanglingRefs` collects defined ids
|
|
19
|
+
* into a `Set`, which absorbs a duplicate rather than reporting it. It is now
|
|
20
|
+
* caught — `step-georeferencing.test.ts`'s "mints distinct ids for generated
|
|
21
|
+
* psets and for created georeferencing" drives both allocating paths in one
|
|
22
|
+
* export and asserts no id is defined twice. Freezing both closures fails that
|
|
23
|
+
* test and only that test.
|
|
24
|
+
*
|
|
25
|
+
* So the reason this module holds two functions rather than five is written
|
|
26
|
+
* down here AND checkable, which is the only reason it is safe to leave the
|
|
27
|
+
* other three where they are.
|
|
28
|
+
*/
|
|
29
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
30
|
+
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
31
|
+
import type { SourceIterationContext } from './step-source-iteration.js';
|
|
32
|
+
import type { OverlayEntitiesContext } from './step-overlay-entities.js';
|
|
33
|
+
import type { PropertySetContext } from './step-property-set-readers.js';
|
|
34
|
+
/**
|
|
35
|
+
* The state `step-source-iteration.ts` cannot read off the pass (#2475 2d).
|
|
36
|
+
*
|
|
37
|
+
* No `allocateExpressId`: that phase never allocates an id, it only rewrites
|
|
38
|
+
* lines that already have one. `applySourceLineMutations` (a free function in
|
|
39
|
+
* `step-attribute-mutations.ts`, closed over `mutationView` here) and
|
|
40
|
+
* `isGeometryEntity` are injected rather than read off the pass because each
|
|
41
|
+
* has readers outside this phase — the mutation pipeline is shared with the
|
|
42
|
+
* type-object `HasPropertySets` rewrite (see `StepExporter`'s
|
|
43
|
+
* `propertySetContext`, which stays a method because it mints express ids) and
|
|
44
|
+
* with the overlay-created-entities block in `export()`; `isGeometryEntity`
|
|
45
|
+
* with the visible-only setup closure and that same block.
|
|
46
|
+
*
|
|
47
|
+
* `propertySetContext` arrives as a THUNK, not a value: the phase calls it
|
|
48
|
+
* per use and the original method rebuilt it per call, which is the behaviour
|
|
49
|
+
* being preserved.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildSourceIterationContext(dataStore: IfcDataStore, mutationView: MutablePropertyView | null, propertySetContext: () => PropertySetContext): SourceIterationContext;
|
|
52
|
+
/**
|
|
53
|
+
* The state `step-overlay-entities.ts` cannot read off the pass (#2475
|
|
54
|
+
* step 2e). `applyOverlayEntityOverrides` is the free function
|
|
55
|
+
* `step-overlay-attribute-overrides.ts` exports; `isGeometryEntity` and
|
|
56
|
+
* `relationshipWithheldWarning` are the same shared readers
|
|
57
|
+
* {@link buildSourceIterationContext} already injects into the other output
|
|
58
|
+
* pass.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildOverlayEntitiesContext(mutationView: MutablePropertyView | null): OverlayEntitiesContext;
|
|
61
|
+
//# sourceMappingURL=step-export-contexts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-export-contexts.d.ts","sourceRoot":"","sources":["../src/step-export-contexts.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAK/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,mBAAmB,GAAG,IAAI,EACxC,kBAAkB,EAAE,MAAM,kBAAkB,GAC3C,sBAAsB,CASxB;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,mBAAmB,GAAG,IAAI,GACvC,sBAAsB,CAOxB"}
|