@ifc-lite/export 2.9.3 → 3.0.0

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.
Files changed (90) hide show
  1. package/dist/csv-cell.d.ts +101 -0
  2. package/dist/csv-cell.d.ts.map +1 -0
  3. package/dist/csv-cell.js +90 -0
  4. package/dist/csv-cell.js.map +1 -0
  5. package/dist/demesh-session.d.ts.map +1 -1
  6. package/dist/demesh-session.js +2 -1
  7. package/dist/demesh-session.js.map +1 -1
  8. package/dist/effective-index.js +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +9 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/lod1-generator.d.ts +0 -2
  14. package/dist/lod1-generator.d.ts.map +1 -1
  15. package/dist/lod1-generator.js +1 -1
  16. package/dist/lod1-generator.js.map +1 -1
  17. package/dist/merged-exporter.d.ts +3 -2
  18. package/dist/merged-exporter.d.ts.map +1 -1
  19. package/dist/merged-exporter.js +32 -44
  20. package/dist/merged-exporter.js.map +1 -1
  21. package/dist/parquet-exporter.js +2 -0
  22. package/dist/parquet-exporter.js.map +1 -1
  23. package/dist/reference-collector.d.ts +40 -17
  24. package/dist/reference-collector.d.ts.map +1 -1
  25. package/dist/reference-collector.js +89 -19
  26. package/dist/reference-collector.js.map +1 -1
  27. package/dist/schema-converter.d.ts.map +1 -1
  28. package/dist/schema-converter.js +27 -1
  29. package/dist/schema-converter.js.map +1 -1
  30. package/dist/source-ref-bounds.d.ts +16 -1
  31. package/dist/source-ref-bounds.d.ts.map +1 -1
  32. package/dist/source-ref-bounds.js +85 -0
  33. package/dist/source-ref-bounds.js.map +1 -1
  34. package/dist/step-attribute-mutations.d.ts +91 -0
  35. package/dist/step-attribute-mutations.d.ts.map +1 -0
  36. package/dist/step-attribute-mutations.js +302 -0
  37. package/dist/step-attribute-mutations.js.map +1 -0
  38. package/dist/step-collection.d.ts +55 -0
  39. package/dist/step-collection.d.ts.map +1 -0
  40. package/dist/step-collection.js +125 -0
  41. package/dist/step-collection.js.map +1 -0
  42. package/dist/step-export-contexts.d.ts +63 -0
  43. package/dist/step-export-contexts.d.ts.map +1 -0
  44. package/dist/step-export-contexts.js +51 -0
  45. package/dist/step-export-contexts.js.map +1 -0
  46. package/dist/step-export-types.d.ts +262 -0
  47. package/dist/step-export-types.d.ts.map +1 -0
  48. package/dist/step-export-types.js +22 -0
  49. package/dist/step-export-types.js.map +1 -0
  50. package/dist/step-exporter.d.ts +45 -398
  51. package/dist/step-exporter.d.ts.map +1 -1
  52. package/dist/step-exporter.js +145 -2033
  53. package/dist/step-exporter.js.map +1 -1
  54. package/dist/step-geometry-types.d.ts +19 -0
  55. package/dist/step-geometry-types.d.ts.map +1 -0
  56. package/dist/step-geometry-types.js +57 -0
  57. package/dist/step-geometry-types.js.map +1 -0
  58. package/dist/step-georeferencing.d.ts +58 -0
  59. package/dist/step-georeferencing.d.ts.map +1 -0
  60. package/dist/step-georeferencing.js +339 -0
  61. package/dist/step-georeferencing.js.map +1 -0
  62. package/dist/step-header.d.ts +43 -0
  63. package/dist/step-header.d.ts.map +1 -0
  64. package/dist/step-header.js +70 -0
  65. package/dist/step-header.js.map +1 -0
  66. package/dist/step-omission-predicates.d.ts +51 -0
  67. package/dist/step-omission-predicates.d.ts.map +1 -0
  68. package/dist/step-omission-predicates.js +268 -0
  69. package/dist/step-omission-predicates.js.map +1 -0
  70. package/dist/step-overlay-entities.d.ts +64 -0
  71. package/dist/step-overlay-entities.d.ts.map +1 -0
  72. package/dist/step-overlay-entities.js +119 -0
  73. package/dist/step-overlay-entities.js.map +1 -0
  74. package/dist/step-pass-builder.d.ts +44 -0
  75. package/dist/step-pass-builder.d.ts.map +1 -0
  76. package/dist/step-pass-builder.js +249 -0
  77. package/dist/step-pass-builder.js.map +1 -0
  78. package/dist/step-property-sets.d.ts +198 -0
  79. package/dist/step-property-sets.d.ts.map +1 -0
  80. package/dist/step-property-sets.js +842 -0
  81. package/dist/step-property-sets.js.map +1 -0
  82. package/dist/step-serialization.d.ts +16 -1
  83. package/dist/step-serialization.d.ts.map +1 -1
  84. package/dist/step-serialization.js +50 -3
  85. package/dist/step-serialization.js.map +1 -1
  86. package/dist/step-source-iteration.d.ts +95 -0
  87. package/dist/step-source-iteration.d.ts.map +1 -0
  88. package/dist/step-source-iteration.js +178 -0
  89. package/dist/step-source-iteration.js.map +1 -0
  90. package/package.json +7 -7
@@ -5,116 +5,15 @@
5
5
  * Supports applying property and root attribute mutations before export.
6
6
  */
7
7
  import type { IfcDataStore } from '@ifc-lite/parser';
8
- import { type MapConversion, type ProjectedCRS } from '@ifc-lite/parser';
9
8
  import type { MutablePropertyView } from '@ifc-lite/mutations';
10
- import { type RandomSource } from '@ifc-lite/encoding';
11
9
  /**
12
- * Options for STEP export
10
+ * The export vocabulary lives in `step-export-types.ts` (#2475). Re-exported
11
+ * here, unchanged, so that the package entry point and the seven sibling
12
+ * modules that import `ExportPass` / `SourceLineMutations` from this file
13
+ * carry on doing exactly that -- the split moved declarations, not call sites.
13
14
  */
14
- export interface StepExportOptions {
15
- /** IFC schema version for the output file (any version, will convert if needed) */
16
- schema: 'IFC2X3' | 'IFC4' | 'IFC4X3' | 'IFC5';
17
- /** File description */
18
- description?: string;
19
- /** Author name */
20
- author?: string;
21
- /** Organization name */
22
- organization?: string;
23
- /** Application name (defaults to 'ifc-lite') */
24
- application?: string;
25
- /** Output filename */
26
- filename?: string;
27
- /** Include original geometry entities (default: true) */
28
- includeGeometry?: boolean;
29
- /** Include property sets (default: true) */
30
- includeProperties?: boolean;
31
- /** Include quantity sets (default: true) */
32
- includeQuantities?: boolean;
33
- /** Include relationships (default: true) */
34
- includeRelationships?: boolean;
35
- /** Apply mutations from MutablePropertyView (default: true if provided) */
36
- applyMutations?: boolean;
37
- /** Only export entities with mutations (delta export) */
38
- deltaOnly?: boolean;
39
- /** Only export entities currently visible in the viewer */
40
- visibleOnly?: boolean;
41
- /** Hidden entity IDs (local expressIds) — required when visibleOnly is true */
42
- hiddenEntityIds?: Set<number>;
43
- /** Isolated entity IDs (local expressIds, null = no isolation active) */
44
- isolatedEntityIds?: Set<number> | null;
45
- /** Georeferencing mutations to apply (IfcProjectedCRS / IfcMapConversion edits) */
46
- georefMutations?: {
47
- projectedCRS?: Partial<ProjectedCRS>;
48
- mapConversion?: Partial<MapConversion>;
49
- };
50
- /**
51
- * Seeded randomness for the GlobalIds this exporter SYNTHESIZES:
52
- * the `IfcPropertySet` / `IfcElementQuantity` roots regenerated for
53
- * mutated (or overlay-created) property and quantity sets, their
54
- * `IfcRelDefinesByProperties` links, and any `IFCPROXY` placeholder minted
55
- * by schema conversion. Without it those come from the platform CSPRNG, so
56
- * two exports of the same model differ in exactly those bytes - which
57
- * breaks byte-reproducibility for in-store builds that call
58
- * `addPropertySet` / `addQuantitySet` (the sets themselves live in the
59
- * mutation overlay and only become IFC roots here). Pass the same seeded
60
- * source used for `SpatialAnchor.guidRandom` to close that gap. Default
61
- * (omitted) behaviour is unchanged: random.
62
- */
63
- guidRandom?: RandomSource;
64
- /**
65
- * Pin the STEP header `FILE_NAME` timestamp (STEP format, e.g.
66
- * `20240101T000000`). Omitted = the wall clock, as before. Required for
67
- * genuinely byte-identical exports, since the header otherwise carries the
68
- * export instant.
69
- */
70
- timeStamp?: string;
71
- /** Progress callback for async export */
72
- onProgress?: (progress: StepExportProgress) => void;
73
- }
74
- /**
75
- * Progress information during STEP export
76
- */
77
- export interface StepExportProgress {
78
- /** Current phase of export */
79
- phase: 'preparing' | 'entities' | 'assembling';
80
- /** Progress 0-1 */
81
- percent: number;
82
- /** Number of entities processed so far */
83
- entitiesProcessed: number;
84
- /** Total entities to process */
85
- entitiesTotal: number;
86
- }
87
- /**
88
- * Result of STEP export
89
- */
90
- export interface StepExportResult {
91
- /** STEP file content as bytes (avoids V8 string length limit for large files) */
92
- content: Uint8Array;
93
- /** Statistics about the export */
94
- stats: {
95
- /** Total entities exported */
96
- entityCount: number;
97
- /** New entities created for mutations */
98
- newEntityCount: number;
99
- /** Entities modified by mutations */
100
- modifiedEntityCount: number;
101
- /** File size in bytes */
102
- fileSize: number;
103
- /**
104
- * Non-fatal refusals: things the caller asked for that this export could
105
- * not write. Empty when the export did everything it was asked to do.
106
- *
107
- * A requested `georefMutations.mapConversion` is the one case today: with
108
- * no `IfcGeometricRepresentationContext` to reference as `SourceCRS`, the
109
- * `IfcMapConversion` is skipped (writing it would produce a dangling
110
- * reference) while the `IfcProjectedCRS` is still written — so the output
111
- * is indistinguishable from "no map conversion was requested" unless the
112
- * caller reads this (#2067). Same `string[]` shape as
113
- * `MergeExportResult.stats.warnings`.
114
- */
115
- warnings: string[];
116
- };
117
- }
15
+ export type { StepExportOptions, StepExportProgress, StepExportResult, SourceLineMutations, ExportPass, } from './step-export-types.js';
16
+ import type { StepExportOptions, StepExportResult } from './step-export-types.js';
118
17
  /**
119
18
  * IFC STEP file exporter
120
19
  */
@@ -123,11 +22,16 @@ export declare class StepExporter {
123
22
  private mutationView;
124
23
  private nextExpressId;
125
24
  private entityExtractor;
126
- /** Lazily-resolved fallback `#id` of an IfcOwnerHistory that survives the
127
- * current export closure (or `$` when the file has none). */
128
- private ownerHistoryFallbackRef;
129
- /** Per-host cache of an element's own OwnerHistory ref (`#id` or null). */
130
- private ownerHistoryByEntity;
25
+ /**
26
+ * The owner-history memos the property-set and quantity-set generators read.
27
+ *
28
+ * Owned here and handed to `step-property-sets.ts` BY REFERENCE rather than
29
+ * stored on its context: the reset below is an `export()`-level statement,
30
+ * and the comment there is where "per export, not per exporter" is argued.
31
+ * Moving the storage into a per-export context would make that reset
32
+ * implicit — the same invariant, in a place nothing says it (#2475 step 2b).
33
+ */
34
+ private ownerHistory;
131
35
  /**
132
36
  * "Can this record's line actually be read out of this store's source?"
133
37
  * (`source-ref-bounds.ts`, #2491). Built once — `dataStore` is assigned in
@@ -149,305 +53,48 @@ export declare class StepExporter {
149
53
  * Export only property/quantity changes (lightweight export)
150
54
  */
151
55
  exportPropertiesOnly(options: Omit<StepExportOptions, 'includeGeometry'>): StepExportResult;
152
- /**
153
- * Resolve a STEP reference to an existing IfcOwnerHistory for the
154
- * IfcPropertySet / IfcRelDefinesByProperties / IfcElementQuantity entities we
155
- * generate for `hostEntityId`'s mutations. OwnerHistory is optional in IFC4 but
156
- * MANDATORY in IFC2X3 (IfcRoot.OwnerHistory), so emitting `$` yields an invalid
157
- * IFC2X3 file that strict readers (e.g. BIM Vision) reject.
158
- *
159
- * Prefer the host element's OWN owner history, then any owner history that
160
- * survives this export, then `$` only when none does.
161
- *
162
- * "Survives" is `willBeEmitted`, the same predicate that decides whether the
163
- * host itself may have psets generated for it. A reference is a reference: it
164
- * is no more acceptable to point an emitted `IfcPropertySet` at an owner
165
- * history the session deleted than at a host it deleted. This used to consult
166
- * only the `visibleOnly` closure, so an overlay-created OwnerHistory that was
167
- * later deleted still got referenced — a dangling `#N`, reached through the
168
- * one attribute the generators fill in for themselves.
169
- */
170
- private resolveOwnerHistoryRef;
171
- /**
172
- * The overlay's answer for one positional slot of an overlay-created entity,
173
- * falling back to the creation payload only when the overlay has NOTHING to
174
- * say about that slot.
175
- *
176
- * **Ask `Map.has`, never `??`.** `setPositionalAttribute(id, slot, null)` is
177
- * an explicit "clear this slot", and its value is `null`, so `??` reads the
178
- * overlay's answer as an absence and reinstates the authored one. That is the
179
- * same overlay-versus-buffer confusion this whole change is about, one
180
- * attribute wide: an explicit null IS the overlay's answer, and the overlay is
181
- * the authority. Cleared OwnerHistory came back as the authored reference, and
182
- * a cleared `HasPropertySets` resurrected the list the user had removed.
183
- */
184
- private overlaySlotValue;
185
- /**
186
- * Read an element's own OwnerHistory reference (`#id`), or null when the
187
- * element omits one (`$`) or cannot be parsed. OwnerHistory is the second
188
- * attribute of every IfcRoot subtype, immediately after the GlobalId string.
189
- */
190
- private getOwnerHistoryRefOfEntity;
191
- /**
192
- * Generate STEP entities for property sets
193
- */
194
- private generatePropertySetEntities;
195
- /**
196
- * Generate STEP entities for quantity sets (IfcElementQuantity)
197
- */
198
- private generateQuantitySetEntities;
199
- /**
200
- * THE mutation pipeline for a line read out of the source buffer: retype,
201
- * then named attribute edits, then positional edits.
202
- *
203
- * **One implementation, two call sites**, and that is the whole point. Two
204
- * passes can write the defining line of a source entity — the
205
- * source-iteration pass, and the type-object `HasPropertySets` rewrite that
206
- * REPLACES it (`rewrittenEntityIds` makes the source pass skip those ids).
207
- * The rewrite used to do its own thing (replace slot 5, nothing else), so
208
- * every other edit to a type object with a type-owned pset edit was dropped
209
- * in silence: first the renames (#2462 follow-up), and after those were
210
- * special-cased here, still the retypes and the positional edits. Whatever
211
- * the source pass applies, the rewrite has to apply too, or the next edit
212
- * kind added to one site goes missing at the other.
213
- *
214
- * The order is load-bearing:
215
- *
216
- * - the retype runs FIRST so named attribute edits resolve against the
217
- * TARGET class's attribute names, and so positional slots are indexed
218
- * into the retyped argument list;
219
- * - the `HasPropertySets` replacement (rewrite path only) runs LAST, on
220
- * the text this returns. Run it first and a positional edit to slot 5 —
221
- * or a retype's argument-list rebuild — overwrites the resolved pset
222
- * list with the stale one, which is the same silent drop one slot over.
223
- *
224
- * The expressId is unchanged by all of this, so geometry / placement /
225
- * representation and every IfcRel* reference (keyed by #id) carry over.
226
- *
227
- * All three flags report EFFECT, not intent — each is the answer to "did this
228
- * operation change the line", measured across that operation alone. The count
229
- * and the ledger are claims about the FILE, so an edit that resolves to the
230
- * text already there has delivered nothing and must not be reported: retyping
231
- * an entity to the class it already is, or writing a positional slot the token
232
- * it already holds, used to count as a modification and reach the ledger as a
233
- * landed edit, over a byte-identical line. Discarded edits read the same way:
234
- * `applyAttributeMutations` drops a name its class has no slot for and
235
- * `retypeStepLine` returns an unparseable line untouched, and neither is a
236
- * modification of anything.
237
- *
238
- * `retyped` / `positional` matter most in a FULL export, which is where the
239
- * two are nominated (their edits have no earlier nomination site); named
240
- * attribute edits are nominated by the collection pass and `attributed` only
241
- * settles their delivery.
242
- */
243
- private applySourceLineMutations;
244
- /**
245
- * Rewrite root IFC attributes directly on the original STEP entity line.
246
- */
247
- private applyAttributeMutations;
248
- /**
249
- * Serialize one NAMED attribute override into its slot — the single point
250
- * both the source-buffer rewrite and the overlay-created rewrite go through.
251
- *
252
- * `serializeAttributeValue` decides the STEP form by reading the token being
253
- * replaced, which is sound only while that token carries type information. A
254
- * `$` slot carries none, and both paths have plenty: a source record's
255
- * optional attributes are `$`, and overlay-created records pad missing slots
256
- * with `$`. So the declared type decides first, and inference is the fallback
257
- * for slots the schema does not classify (references, SELECTs, numerics),
258
- * where reading the old token is exactly the right heuristic.
259
- */
260
- private serializeNamedAttribute;
261
- /**
262
- * Apply overlay attribute + positional overrides to an OVERLAY-CREATED
263
- * entity's argument list (#2006).
264
- *
265
- * Distinct from {@link applyAttributeMutations} / {@link applyPositionalMutations},
266
- * which rewrite a line read out of the source buffer. Here the whole line is
267
- * ours: it was serialized moments ago from the creation payload, so the
268
- * argument list is the authoring payload's, not the file's. That difference
269
- * is why this PADS — `entity_create` takes whatever positional list the
270
- * caller passes, so a wall authored with three arguments still has a real
271
- * `Tag` slot at index 7, and dropping the edit because the payload was short
272
- * would be the very data loss this fixes. The source-buffer path must not
273
- * pad: there a short line means a different schema, and growing a record we
274
- * did not author would corrupt it.
275
- *
276
- * Named and positional overrides resolve to a slot index up front and share
277
- * ONE padding rule. Two padding rules on one record is how the next bug
278
- * starts, and the argument for padding — the class is fixed at creation time,
279
- * so a short payload is partial authoring — never depended on which of the
280
- * two APIs queued the edit.
281
- */
282
- private applyOverlayEntityOverrides;
283
- /**
284
- * Apply positional STEP argument overrides to an entity line.
285
- * Used for non-IfcRoot edits (e.g. profile dimensions) where attributes
286
- * have no symbolic names. Indexes that fall outside the existing arg list
287
- * are silently ignored.
288
- */
289
- private applyPositionalMutations;
290
- /**
291
- * Serialize one positional override, composing the schema-aware passes:
292
- * explicit `{ real }`/`{ typed }` marker → SELECT auto-qualification
293
- * (`IFCBOOLEAN(.T.)`) → REAL forcing. For REAL forcing the current source
294
- * token is a secondary signal: replacing a value that was already a REAL
295
- * (`0.4`, `1.5E-7`) keeps it REAL even for entities the XSD index doesn't
296
- * cover, so a whole-number edit can't silently downgrade the slot.
297
- */
298
- private serializePositionalOverride;
299
- private resolveMapUnitReference;
300
- private normalizeMapUnitName;
301
- /**
302
- * `effective` filters the candidates the same way the georef reads above do:
303
- * returning a tombstoned unit id hands the caller a `#id` for a line the
304
- * export never writes. Returning null instead makes `resolveMapUnitReference`
305
- * synthesise a fresh unit, which is the outcome a deleted unit deserves.
306
- */
307
- private findLengthUnitReference;
308
- /**
309
- * Record that a requested IfcMapConversion could not be written. Emitting it
310
- * anyway would leave `SourceCRS` pointing at nothing, so the refusal is the
311
- * correct output — but the file alone cannot express it, which is why it goes
312
- * back to the caller in `stats.warnings` as well as to the console (#2067).
313
- */
314
- private reportMapConversionRefused;
315
- /**
316
- * Record that a requested IfcMapConversion could not be written because
317
- * there is no IfcProjectedCRS to attach it to — a different refusal from
318
- * {@link reportMapConversionRefused}: "no CRS to attach it to" rather than
319
- * "no context to reference" (#2105).
320
- */
321
- private reportMapConversionRefusedNoCrs;
322
- /**
323
- * `effective` again: the id returned here becomes the new IfcMapConversion's
324
- * SourceCRS, so a tombstoned context would leave the created line pointing at
325
- * a record the export skips — a dangling reference and an invalid file.
326
- */
327
- private findPreferredGeometricRepresentationContextId;
328
- /**
329
- * Generate a new IFC GlobalId (22 character base64). `random` is the
330
- * export's optional seeded source (`StepExportOptions.guidRandom`);
331
- * undefined keeps the default random path.
332
- */
333
- private generateGlobalId;
334
56
  /**
335
57
  * Find the maximum EXPRESS ID in the data store
336
58
  */
337
59
  private findMaxExpressId;
338
60
  /**
339
- * Find a unit entity ID by name (simplified - returns null for now)
340
- */
341
- private findUnitId;
342
- /**
343
- * Check if an entity type is a geometry-related type
344
- */
345
- private isGeometryEntity;
346
- /**
347
- * Build a one-shot reverse index of every IfcRelDefinesByProperties in
348
- * the source: for each related entity, list the rels and property/quantity
349
- * sets that reference it. Used by the export pre-pass so the per-entity
350
- * "find owning rels" step is O(K) rather than O(N) per modified entity.
61
+ * The exporter state `step-georeferencing.ts` cannot read off the pass.
351
62
  *
352
- * `relatedByRel` is the same walk read the other way round, so the deleted-host
353
- * sweep costs nothing extra.
63
+ * `allocateExpressId` hands out ids from THIS exporter's `nextExpressId`,
64
+ * which the property-set and quantity-set generators in
65
+ * `step-property-sets.ts` increment at six further sites through the same
66
+ * callback — hoisting the counter onto the pass would change what it
67
+ * computes, not merely where it is named, so both phases get a callback
68
+ * instead (#2475 step 2a).
354
69
  */
355
- private buildRelDefinesByPropertiesIndex;
70
+ private georefContext;
356
71
  /**
357
- * The source STEP text of an entity's line, or `null` when there are no bytes
358
- * to read.
359
- *
360
- * The byte check is on the RANGE, not on `dataStore.source`. `source` is a
361
- * MANDATORY accessor — `EMPTY_SOURCE_BYTES` is how "this model kept no bytes"
362
- * is spelled (server-parsed, synthetic, GLB and point-cloud stores all have
363
- * one) — so the `!this.dataStore.source` guard the five readers below used to
364
- * carry never fired. It was also redundant: a zero-length range decodes to
365
- * `''`, which fails every regex those readers run, so they already answered
366
- * "nothing" for a sourceless store. Scoping the check to the range is what
367
- * makes the guard live without changing a single answer, the same shape and
368
- * for the same reason as `reference-collector.ts` (#2339).
369
- *
370
- * An OVERLAY-created entity never reaches here: every caller resolves its id
371
- * through `dataStore.entityIndex.byId`, which holds source records only
372
- * (`effective-index.ts` synthesises the overlay refs on its own side and
373
- * writes nothing back), so an overlay id is already `undefined` at the
374
- * lookup and is served by the callers' documented "not a source record"
375
- * path. That is why an early return is safe HERE and is NOT safe at the
376
- * visible-only closure in `export` — see the comment there.
377
- *
378
- * ## Why `isReadableSourceRef` and not `byteLength === 0`
72
+ * The state `step-property-sets.ts` cannot read off the pass (#2475 2b/2c).
379
73
  *
380
- * An out-of-range ref does NOT degrade to "no match" here. `decodeUtf8`
381
- * clamps the range it cannot address, and the clamped window is still a
382
- * window over real file bytesso these readers answer from somebody
383
- * ELSE's record. `source-ref-bounds.ts` (#2491) carries the measured
384
- * account of both shapes and of why "a clamped, empty decode already yields
385
- * no match" is false; it is not restated here, because an argument kept in
386
- * two files is an argument that has to stay true in two files.
387
- *
388
- * The consequence specific to THIS site is that the wrong answer is acted
389
- * on. `retainSharedAtoms` un-skips every id `getPropertyIdsInSet` returns,
390
- * so a member list read out of the wrong record un-skips the wrong atoms;
391
- * and the source-iteration pass already refuses to emit a record whose ref
392
- * fails `isReadableSourceRef` (see the `continue` in `export`), so before
393
- * this gate these readers were making decisions on behalf of a container
394
- * that the same export had decided not to write. Gating them on the same
395
- * predicate is what makes the two passes agree.
396
- *
397
- * The degradation is the one the exporter already handles: a record with no
398
- * emittable bytes, generating nothing and named by nothing. It costs one
399
- * answer that used to be right by luck — an overrunning ref on the file's
400
- * LAST record clamps back to exactly that record's text — but that record
401
- * is one the emission pass drops anyway, so keeping the answer only kept
402
- * the disagreement.
403
- */
404
- private entityLineText;
405
- /**
406
- * Get entity IDs related by IfcRelDefinesByProperties (the related objects)
407
- */
408
- private getRelatedEntities;
409
- /**
410
- * Get the property set ID from IfcRelDefinesByProperties
411
- */
412
- private getRelatedPropertySet;
413
- /**
414
- * Get the name of a property set by parsing the entity
415
- */
416
- private getPropertySetName;
417
- /**
418
- * Get the name of an element quantity set by parsing the entity
419
- */
420
- private getElementQuantityName;
421
- /**
422
- * Get IDs of properties in a property set
423
- */
424
- /**
425
- * Un-skip property/quantity atoms that a surviving (non-skipped, and — under
426
- * visible-only export — still-included) IfcPropertySet / IfcElementQuantity
427
- * still references.
74
+ * `allocateExpressId` is the same callback `georefContext` hands out, over
75
+ * the same counter, so the ids the two phases allocate stay in one sequence.
76
+ * `ownerHistory` is passed by referencethe object is this exporter's, and
77
+ * `export()` resets it. `isReadableSourceRef` is the instance predicate, not
78
+ * `pass.isReadableSourceRef`, because two consumers of that module
79
+ * (`buildRelDefinesByPropertiesIndex`, and `retainSharedAtoms` in
80
+ * `step-source-iteration.ts`) run with no pass in hand; both readers are
81
+ * built over the same source.
428
82
  *
429
- * When a property is edited, the modified pset is replaced and its member atoms
430
- * are added to `skipIds` wholesale. Because exporters deduplicate shared
431
- * Pset_*Common atoms (e.g. a single IsExternal / IsLoadBearing value referenced
432
- * by many psets), that wholesale skip can drop an atom another pset still needs.
433
- * This pass restores any such atom: the edited pset still emits its replacement
434
- * with the new value, while the shared atom stays for the psets that keep their
435
- * original value.
83
+ * Rebuilt per call, as `georefContext` is: every call site runs once per
84
+ * export bar `retainSharedAtoms`, which hoists it out of its loop — hence
85
+ * `buildSourceIterationContext` (`step-export-contexts.ts`) takes this as a
86
+ * thunk rather than a value.
436
87
  */
437
- private retainSharedAtoms;
438
- private getPropertyIdsInSet;
88
+ private propertySetContext;
439
89
  /**
440
- * The full HasPropertySets id list of a type object, from whichever authority
441
- * owns the record.
442
- *
443
- * Slot 5 is `HasPropertySets` on every `IfcTypeObject` subtype. For a source
444
- * record the list is parsed out of the file; for an overlay-created type it is
445
- * read off the authored payload, where a reference is the documented `'#42'`
446
- * string form. Reading only the source made every pset on a created
447
- * `IfcWallType` look unowned, which is how it ended up on an occurrence
448
- * relation instead (#2012).
90
+ * The state `step-collection.ts` cannot read off the pass (#2475, the
91
+ * collection block). `propertySetContext` and `georefContext` are handed
92
+ * over as the SAME thunks {@link propertySetContext} and
93
+ * {@link georefContext} already are this phase calls the first twice per
94
+ * export and the second once, and nothing here should change how often
95
+ * either is rebuilt.
449
96
  */
450
- private getTypeOwnedHasPropertySetIds;
97
+ private collectionContext;
451
98
  }
452
99
  /**
453
100
  * Quick export function for simple use cases.
@@ -1 +1 @@
1
- {"version":3,"file":"step-exporter.d.ts","sourceRoot":"","sources":["../src/step-exporter.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAsD,MAAM,kBAAkB,CAAC;AACzG,OAAO,EASL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA2ExE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC9C,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,yDAAyD;IACzD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAEvC,mFAAmF;IACnF,eAAe,CAAC,EAAE;QAChB,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QACrC,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;KACxC,CAAC;IAEF;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,yCAAyC;IACzC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;IAC/C,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gCAAgC;IAChC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iFAAiF;IACjF,OAAO,EAAE,UAAU,CAAC;IACpB,kCAAkC;IAClC,KAAK,EAAE;QACL,8BAA8B;QAC9B,WAAW,EAAE,MAAM,CAAC;QACpB,yCAAyC;QACzC,cAAc,EAAE,MAAM,CAAC;QACvB,qCAAqC;QACrC,mBAAmB,EAAE,MAAM,CAAC;QAC5B,yBAAyB;QACzB,QAAQ,EAAE,MAAM,CAAC;QACjB;;;;;;;;;;;WAWG;QACH,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AA6BD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAyB;IAChD;kEAC8D;IAC9D,OAAO,CAAC,uBAAuB,CAAqB;IACpD,2EAA2E;IAC3E,OAAO,CAAC,oBAAoB,CAAoC;IAChE;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAA2C;gBAE1D,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,mBAAmB;IAYvE;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB;IAovCpD;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqBxE;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,GAAG,gBAAgB;IAQ3F;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAoClC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA+DnC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA+CnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACH,OAAO,CAAC,wBAAwB;IAsDhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA4C/B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,uBAAuB;IAW/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,2BAA2B;IA8DnC;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;;;;;OAOG;IACH,OAAO,CAAC,2BAA2B;IAenC,OAAO,CAAC,uBAAuB;IAgC/B,OAAO,CAAC,oBAAoB;IAQ5B;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IA+C/B;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAKlC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAMvC;;;;OAIG;IACH,OAAO,CAAC,6CAA6C;IA4BrD;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;;;;;;;OAQG;IACH,OAAO,CAAC,gCAAgC;IAwBxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+CG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;OAEG;IACH;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,6BAA6B;CAetC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,YAAY,EACvB,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACnC,MAAM,CAOR"}
1
+ {"version":3,"file":"step-exporter.d.ts","sourceRoot":"","sources":["../src/step-exporter.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,kBAAkB,CAAC;AAEtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAgB/D;;;;;GAKG;AACH,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,GACX,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAc,MAAM,wBAAwB,CAAC;AAU9F;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAyB;IAChD;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAAsE;IAC1F;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAA2C;gBAE1D,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,mBAAmB;IAYvE;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB;IA4IpD;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqBxE;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,GAAG,gBAAgB;IAQ3F;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;CAW1B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,YAAY,EACvB,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACnC,MAAM,CAOR"}