@ifc-lite/export 2.2.0 → 2.4.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.
@@ -0,0 +1,346 @@
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
+ * Unit normalization for merged STEP export (issue #1475).
6
+ *
7
+ * When {@link MergedExporter} runs with `unitReconciliation: 'normalize'`, every
8
+ * non-primary model whose length unit differs from the primary model's has all
9
+ * of its length-valued data rescaled into the primary unit, so the models can be
10
+ * unified into ONE `IfcProject` with ONE `IfcUnitAssignment` (rather than
11
+ * federated as separate, mutually mis-scaled projects).
12
+ *
13
+ * This module is the pure, text-level rescaler. It knows WHICH numeric attributes
14
+ * of a STEP entity carry a length (and which carry an area/volume) by deriving the
15
+ * answer from the generated IFC schema registry (`@ifc-lite/parser`
16
+ * `getAllAttributesForEntity`) — the 0-based index into an entity's `allAttributes`
17
+ * is exactly its 0-based STEP attribute index, and each attribute is typed. This
18
+ * avoids a hand-maintained per-entity table and stays correct as the schema evolves.
19
+ *
20
+ * ## Factors
21
+ * The caller passes three *independent* factors (a length datum × `lengthFactor`,
22
+ * an area datum × `areaFactor`, a volume datum × `volumeFactor`). They are NOT
23
+ * `lengthFactor` powers: IFC declares `AREAUNIT`/`VOLUMEUNIT` independently of
24
+ * `LENGTHUNIT` (e.g. Revit exports millimetre lengths but square-/cubic-metre
25
+ * areas/volumes), so each dimension is converted by the ratio of its own declared
26
+ * unit. See {@link MergedExporter} for how the factors are derived.
27
+ *
28
+ * ## What is rescaled
29
+ * - **Coordinate lists** — every number in a `LIST OF IfcLengthMeasure` attribute
30
+ * (`IfcCartesianPoint.Coordinates`, `IfcCartesianPointList2D/3D.CoordList`). × length.
31
+ * - **Scalar lengths** — any attribute typed `IfcLengthMeasure` /
32
+ * `IfcPositiveLengthMeasure` / `IfcNonNegativeLengthMeasure` (extrusion depths,
33
+ * profile dimensions, radii, wall thicknesses, `IfcVector.Magnitude`, CSG
34
+ * primitive sizes, `IfcBuildingStorey.Elevation`, `IfcSite.RefElevation`,
35
+ * `IfcQuantityLength.LengthValue`, …). × length.
36
+ * - **Areas / volumes** — `IfcQuantityArea.AreaValue` (× area),
37
+ * `IfcQuantityVolume.VolumeValue` (× volume).
38
+ * - **Typed measures in property values** — `IFCLENGTHMEASURE(x)` /
39
+ * `IFCPOSITIVELENGTHMEASURE(x)` / `IFCNONNEGATIVELENGTHMEASURE(x)` (× length),
40
+ * `IFCAREAMEASURE(x)` (× area), `IFCVOLUMEMEASURE(x)` (× volume), wherever they
41
+ * appear outside a quoted string.
42
+ *
43
+ * ## What is NOT rescaled
44
+ * - Unit-definition entities (`IfcSIUnit`, `IfcConversionBasedUnit`,
45
+ * `IfcMeasureWithUnit`, `IfcUnitAssignment`, …): their numbers define units, not
46
+ * data, and must survive verbatim.
47
+ * - Georeferencing (`IfcMapConversion`): its offsets are in the map/CRS unit,
48
+ * independent of the project length unit.
49
+ * - A quantity or property that carries its own explicit unit reference (`Unit`,
50
+ * or `DefiningUnit`/`DefinedUnit` on `IfcPropertyTableValue`): its value is
51
+ * already in that unit, not the global one.
52
+ * - Angles, direction ratios, plain `IfcReal` ratios and counts — never typed as a
53
+ * length/area/volume measure, so they are excluded automatically.
54
+ */
55
+ import { getAllAttributesForEntity } from '@ifc-lite/parser';
56
+ import { splitTopLevelStepArguments } from './step-serialization.js';
57
+ /** IFC defined types whose values are lengths (STEP writes them as bare reals). */
58
+ const LENGTH_MEASURE_TYPES = new Set([
59
+ 'IfcLengthMeasure',
60
+ 'IfcPositiveLengthMeasure',
61
+ 'IfcNonNegativeLengthMeasure',
62
+ ]);
63
+ /**
64
+ * Entity types whose numeric content must NEVER be rescaled: unit definitions
65
+ * (the numbers *are* the unit) and georeferencing (offsets live in the CRS unit).
66
+ * `IFCMAPCONVERSION` is matched by prefix to also catch schema variants.
67
+ */
68
+ const RESCALE_EXCLUDED_TYPES = new Set([
69
+ 'IFCUNITASSIGNMENT', 'IFCSIUNIT', 'IFCCONVERSIONBASEDUNIT', 'IFCCONTEXTDEPENDENTUNIT',
70
+ 'IFCDERIVEDUNIT', 'IFCDERIVEDUNITELEMENT', 'IFCDIMENSIONALEXPONENTS', 'IFCMONETARYUNIT',
71
+ 'IFCMEASUREWITHUNIT',
72
+ ]);
73
+ function isRescaleExcluded(typeUpper) {
74
+ return RESCALE_EXCLUDED_TYPES.has(typeUpper) || typeUpper.startsWith('IFCMAPCONVERSION');
75
+ }
76
+ const EMPTY_PLAN = {
77
+ listIdx: [], scalarIdx: [], areaIdx: [], volumeIdx: [], unitGuardIdx: [], empty: true,
78
+ };
79
+ /** Attribute names that hold a self-describing unit override for a value. */
80
+ const UNIT_GUARD_NAMES = new Set(['Unit', 'DefiningUnit', 'DefinedUnit']);
81
+ const planCache = new Map();
82
+ /**
83
+ * The base measure type of an attribute, and whether it is an aggregate. Handles
84
+ * both the compact `"IfcLengthMeasure[]"` encoding and the rare raw EXPRESS form
85
+ * (`"UNIQUE LIST [1:2] OF IfcLengthMeasure"`) the generated registry sometimes
86
+ * carries — the base is the last `Ifc…` token, and an aggregate is signalled by
87
+ * the flags, a `[]` suffix, or a `LIST`/`SET`/`ARRAY` keyword.
88
+ */
89
+ function attrBaseType(type, flags) {
90
+ const match = type.match(/Ifc[A-Za-z0-9]+/g);
91
+ const base = match ? match[match.length - 1] : type;
92
+ const isList = flags.isList || flags.isArray || flags.isSet
93
+ || /\[\]/.test(type) || /\b(?:LIST|SET|ARRAY|BAG)\b/i.test(type);
94
+ return { base, isList };
95
+ }
96
+ /**
97
+ * Derive (and cache) the length/area/volume attribute plan for an uppercase STEP
98
+ * type name from the generated schema registry. Excluded types (unit definitions,
99
+ * georeferencing) and unknown/abstract types return the empty plan.
100
+ */
101
+ export function getEntityLengthPlan(typeUpper) {
102
+ const cached = planCache.get(typeUpper);
103
+ if (cached !== undefined)
104
+ return cached;
105
+ const plan = buildEntityLengthPlan(typeUpper);
106
+ planCache.set(typeUpper, plan);
107
+ return plan;
108
+ }
109
+ function buildEntityLengthPlan(typeUpper) {
110
+ if (isRescaleExcluded(typeUpper))
111
+ return EMPTY_PLAN;
112
+ const attrs = getAllAttributesForEntity(typeUpper);
113
+ if (!attrs || attrs.length === 0)
114
+ return EMPTY_PLAN;
115
+ const listIdx = [];
116
+ const scalarIdx = [];
117
+ const areaIdx = [];
118
+ const volumeIdx = [];
119
+ const unitGuardIdx = [];
120
+ attrs.forEach((a, i) => {
121
+ const { base, isList } = attrBaseType(a.type, a);
122
+ if (LENGTH_MEASURE_TYPES.has(base)) {
123
+ if (isList)
124
+ listIdx.push(i);
125
+ else
126
+ scalarIdx.push(i);
127
+ }
128
+ else if (base === 'IfcAreaMeasure' && !isList) {
129
+ areaIdx.push(i);
130
+ }
131
+ else if (base === 'IfcVolumeMeasure' && !isList) {
132
+ volumeIdx.push(i);
133
+ }
134
+ // A quantity's Unit is typed IfcNamedUnit; a property's Unit is the IfcUnit
135
+ // SELECT; an IfcPropertyTableValue uses DefiningUnit/DefinedUnit. Any of them,
136
+ // when set, means the value carries its own unit.
137
+ if (UNIT_GUARD_NAMES.has(a.name) && (base === 'IfcNamedUnit' || base === 'IfcUnit')) {
138
+ unitGuardIdx.push(i);
139
+ }
140
+ });
141
+ const empty = listIdx.length === 0 && scalarIdx.length === 0
142
+ && areaIdx.length === 0 && volumeIdx.length === 0 && unitGuardIdx.length === 0;
143
+ return empty ? EMPTY_PLAN : { listIdx, scalarIdx, areaIdx, volumeIdx, unitGuardIdx, empty };
144
+ }
145
+ /**
146
+ * Format a number as a valid ISO-10303-21 STEP REAL, after a unit multiply.
147
+ *
148
+ * Rounds to 12 significant digits first to erase floating-point noise from the
149
+ * multiply (e.g. `0.3048 * 100 = 30.479999999999997` → `30.48`) — 12 digits keeps
150
+ * sub-micron precision at building scale. Always emits a decimal point, and
151
+ * rewrites JavaScript's lowercase exponent (`1.5e-7`) into STEP's uppercase form
152
+ * with a mantissa dot (`1.5E-7`), so small/large magnitudes stay parseable.
153
+ */
154
+ export function toStepRealScaled(v) {
155
+ if (!Number.isFinite(v))
156
+ return '0.';
157
+ if (v === 0)
158
+ return '0.'; // also normalizes -0
159
+ const s = parseFloat(v.toPrecision(12)).toString();
160
+ const e = s.indexOf('e');
161
+ if (e !== -1) {
162
+ let mantissa = s.slice(0, e);
163
+ const exp = s.slice(e + 1);
164
+ if (!mantissa.includes('.'))
165
+ mantissa += '.';
166
+ return `${mantissa}E${exp}`;
167
+ }
168
+ return s.includes('.') ? s : s + '.';
169
+ }
170
+ /**
171
+ * Single token matcher used by {@link scaleNumberLiterals}: a full STEP string
172
+ * (kept verbatim, honouring the `''` escape), a `#`-reference (kept verbatim), or
173
+ * a REAL/INTEGER literal (rescaled). Ordering matters — strings and refs are
174
+ * matched first so their inner digits are never treated as numbers. The number
175
+ * alternative consumes an optional exponent as one token, so `1.E-5` / `-2.5E2`
176
+ * scale the mantissa without touching the exponent digits.
177
+ */
178
+ const NUMBER_TOKEN_RE = /'(?:[^']|'')*'|#\d+|[+-]?(?:\d+\.\d*|\.\d+|\d+)(?:[eE][+-]?\d+)?/g;
179
+ /**
180
+ * Multiply every bare numeric literal in `text` by `factor`, leaving quoted
181
+ * strings and `#`-references untouched. O(n) single pass — safe for the large
182
+ * coordinate lists of tessellated geometry.
183
+ */
184
+ export function scaleNumberLiterals(text, factor) {
185
+ return text.replace(NUMBER_TOKEN_RE, (tok) => {
186
+ const c = tok.charCodeAt(0);
187
+ if (c === 0x27 /* ' */ || c === 0x23 /* # */)
188
+ return tok;
189
+ return toStepRealScaled(parseFloat(tok) * factor);
190
+ });
191
+ }
192
+ /**
193
+ * Scale the typed measures embedded in property/quantity values. Matches
194
+ * `IFC[POSITIVE|NONNEGATIVE]LENGTHMEASURE(x)` (× lengthFactor), `IFCAREAMEASURE(x)`
195
+ * (× areaFactor) and `IFCVOLUMEMEASURE(x)` (× volumeFactor), but never inside a
196
+ * quoted string (the string alternative is matched first and returned verbatim).
197
+ *
198
+ * A single non-word delimiter (`(`, `,`, whitespace, or start-of-input) is
199
+ * captured before the keyword and restored, so a keyword can never be matched as
200
+ * the suffix of a longer identifier — without a lookbehind, which some engines
201
+ * (older Safari) reject at construction time and would break importing this module.
202
+ */
203
+ const TYPED_MEASURE_RE = /('(?:[^']|'')*')|(^|[^A-Za-z0-9_])(IFC(?:POSITIVE|NONNEGATIVE)?LENGTHMEASURE|IFCAREAMEASURE|IFCVOLUMEMEASURE)\(([^)]*)\)/gi;
204
+ export function scaleTypedMeasures(text, lengthFactor, areaFactor, volumeFactor) {
205
+ return text.replace(TYPED_MEASURE_RE, (full, str, delim, keyword, num) => {
206
+ if (str !== undefined)
207
+ return full; // inside a quoted string
208
+ const kw = keyword.toUpperCase();
209
+ const factor = kw === 'IFCAREAMEASURE' ? areaFactor
210
+ : kw === 'IFCVOLUMEMEASURE' ? volumeFactor
211
+ : lengthFactor; // any *LENGTHMEASURE
212
+ return `${delim}${keyword}(${scaleMeasureNumber(num, factor)})`;
213
+ });
214
+ }
215
+ /** Scale the numeric content of one typed-measure token, preserving non-numeric ($) content. */
216
+ function scaleMeasureNumber(num, factor) {
217
+ const trimmed = num.trim();
218
+ const n = Number(trimmed);
219
+ if (trimmed === '' || !Number.isFinite(n))
220
+ return num;
221
+ return toStepRealScaled(n * factor);
222
+ }
223
+ /** Scale a single scalar attribute token by `factor` (skips `$`/`*`/non-bare-number). */
224
+ function scaleScalarArg(arg, factor) {
225
+ const trimmed = arg.trim();
226
+ if (trimmed === '' || trimmed === '$' || trimmed === '*')
227
+ return arg;
228
+ const n = Number(trimmed);
229
+ // Only a bare real is a directly-typed length; a typed token (IFC…MEASURE(…))
230
+ // is left to the measure pass, so it is never scaled twice.
231
+ if (!Number.isFinite(n))
232
+ return arg;
233
+ return toStepRealScaled(n * factor);
234
+ }
235
+ /**
236
+ * Locate the outer STEP argument list of one entity line: the first `(` (nothing
237
+ * is quoted before the type name) and its matching `)`, honouring quoted strings
238
+ * (with the `''` escape) so a literal `)` inside a string never closes early.
239
+ * Returns `null` for a line without arguments.
240
+ */
241
+ function findOuterArgs(line) {
242
+ const open = line.indexOf('(');
243
+ if (open === -1)
244
+ return null;
245
+ let depth = 0;
246
+ let inString = false;
247
+ for (let i = open; i < line.length; i++) {
248
+ const ch = line[i];
249
+ if (inString) {
250
+ if (ch === "'") {
251
+ if (line[i + 1] === "'")
252
+ i++; // escaped quote
253
+ else
254
+ inString = false;
255
+ }
256
+ continue;
257
+ }
258
+ if (ch === "'") {
259
+ inString = true;
260
+ continue;
261
+ }
262
+ if (ch === '(')
263
+ depth++;
264
+ else if (ch === ')') {
265
+ depth--;
266
+ if (depth === 0)
267
+ return { open, close: i };
268
+ }
269
+ }
270
+ return null;
271
+ }
272
+ /**
273
+ * Rescale every length/area/volume-valued datum of one STEP entity line.
274
+ *
275
+ * `typeUpper` is the entity's uppercase STEP type (used for the schema-derived
276
+ * plan). The line is expected to be a single `#id=TYPE(...);` statement. Returns
277
+ * the input unchanged when all factors are `1`, the type is excluded (unit
278
+ * definition / georeferencing), or there is nothing to scale.
279
+ */
280
+ export function rescaleEntityLengths(line, typeUpper, lengthFactor, areaFactor, volumeFactor) {
281
+ if (lengthFactor === 1 && areaFactor === 1 && volumeFactor === 1)
282
+ return line;
283
+ if (!Number.isFinite(lengthFactor) || !Number.isFinite(areaFactor) || !Number.isFinite(volumeFactor))
284
+ return line;
285
+ if (isRescaleExcluded(typeUpper))
286
+ return line;
287
+ const plan = getEntityLengthPlan(typeUpper);
288
+ const hasStructural = plan.listIdx.length > 0 || plan.scalarIdx.length > 0
289
+ || plan.areaIdx.length > 0 || plan.volumeIdx.length > 0;
290
+ // Fast path: nothing structural, no unit override to weigh, and no typed measure.
291
+ if (!hasStructural && plan.unitGuardIdx.length === 0 && !line.includes('MEASURE'))
292
+ return line;
293
+ const bounds = findOuterArgs(line);
294
+ if (!bounds)
295
+ return line;
296
+ let inner = line.slice(bounds.open + 1, bounds.close);
297
+ let skipValues = false;
298
+ if (hasStructural || plan.unitGuardIdx.length > 0) {
299
+ const args = splitTopLevelStepArguments(inner);
300
+ // A live unit-override reference means the value is already in its own unit.
301
+ skipValues = plan.unitGuardIdx.some((idx) => {
302
+ const u = args[idx]?.trim();
303
+ return u !== undefined && u !== '' && u !== '$' && u !== '*';
304
+ });
305
+ if (!skipValues && hasStructural) {
306
+ for (const idx of plan.listIdx) {
307
+ if (args[idx] !== undefined)
308
+ args[idx] = scaleNumberLiterals(args[idx], lengthFactor);
309
+ }
310
+ for (const idx of plan.scalarIdx) {
311
+ if (args[idx] !== undefined)
312
+ args[idx] = scaleScalarArg(args[idx], lengthFactor);
313
+ }
314
+ for (const idx of plan.areaIdx) {
315
+ if (args[idx] !== undefined)
316
+ args[idx] = scaleScalarArg(args[idx], areaFactor);
317
+ }
318
+ for (const idx of plan.volumeIdx) {
319
+ if (args[idx] !== undefined)
320
+ args[idx] = scaleScalarArg(args[idx], volumeFactor);
321
+ }
322
+ inner = args.join(',');
323
+ }
324
+ }
325
+ // Typed measures live in property/quantity value slots (an IfcValue SELECT is
326
+ // written with its explicit type). Skipped when the entity declares its own unit.
327
+ if (!skipValues && inner.includes('MEASURE')) {
328
+ inner = scaleTypedMeasures(inner, lengthFactor, areaFactor, volumeFactor);
329
+ }
330
+ return line.slice(0, bounds.open + 1) + inner + line.slice(bounds.close);
331
+ }
332
+ /**
333
+ * Factor that converts a value expressed in `modelScale` units into `primaryScale`
334
+ * units (both are SI-per-unit for the same dimension). Returns `1` when the units
335
+ * already match or either scale is non-positive/non-finite.
336
+ */
337
+ export function computeNormalizeFactor(modelScale, primaryScale) {
338
+ if (!Number.isFinite(modelScale) || !Number.isFinite(primaryScale))
339
+ return 1;
340
+ if (modelScale <= 0 || primaryScale <= 0)
341
+ return 1;
342
+ if (modelScale === primaryScale)
343
+ return 1;
344
+ return modelScale / primaryScale;
345
+ }
346
+ //# sourceMappingURL=unit-normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-normalize.js","sourceRoot":"","sources":["../src/unit-normalize.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ifc-lite/export",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Export formats for IFC-Lite",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -16,16 +16,16 @@
16
16
  "parquet-wasm": "^0.7.1",
17
17
  "apache-arrow": "^21.1.0",
18
18
  "jszip": "^3.10.0",
19
- "@ifc-lite/geometry": "^2.12.0",
20
- "@ifc-lite/data": "^2.2.0",
21
- "@ifc-lite/encoding": "^1.14.7",
22
- "@ifc-lite/parser": "^3.5.0",
19
+ "@ifc-lite/geometry": "^3.0.0",
20
+ "@ifc-lite/data": "^2.3.0",
21
+ "@ifc-lite/encoding": "^1.14.8",
22
+ "@ifc-lite/parser": "^3.5.2",
23
23
  "@ifc-lite/mutations": "^1.17.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "typescript": "^6.0.3",
27
27
  "vitest": "^4.1.9",
28
- "@ifc-lite/ifcx": "^2.1.5"
28
+ "@ifc-lite/ifcx": "^2.1.6"
29
29
  },
30
30
  "license": "MPL-2.0",
31
31
  "author": "Louis True",