@ifc-lite/create 2.2.1 → 2.5.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.
- package/dist/ifc-creator-math.d.ts +14 -0
- package/dist/ifc-creator-math.d.ts.map +1 -1
- package/dist/ifc-creator-math.js +36 -0
- package/dist/ifc-creator-math.js.map +1 -1
- package/dist/ifc-creator-scheduling.d.ts +27 -0
- package/dist/ifc-creator-scheduling.d.ts.map +1 -0
- package/dist/ifc-creator-scheduling.js +131 -0
- package/dist/ifc-creator-scheduling.js.map +1 -0
- package/dist/ifc-creator.d.ts +23 -6
- package/dist/ifc-creator.d.ts.map +1 -1
- package/dist/ifc-creator.js +39 -59
- package/dist/ifc-creator.js.map +1 -1
- package/dist/in-store/anchor.d.ts +16 -1
- package/dist/in-store/anchor.d.ts.map +1 -1
- package/dist/in-store/anchor.js +20 -0
- package/dist/in-store/anchor.js.map +1 -1
- package/dist/in-store/drawing-markup-geometry.d.ts +46 -0
- package/dist/in-store/drawing-markup-geometry.d.ts.map +1 -0
- package/dist/in-store/drawing-markup-geometry.js +80 -0
- package/dist/in-store/drawing-markup-geometry.js.map +1 -0
- package/dist/in-store/drawing-markup-tags.d.ts +29 -0
- package/dist/in-store/drawing-markup-tags.d.ts.map +1 -0
- package/dist/in-store/drawing-markup-tags.js +31 -0
- package/dist/in-store/drawing-markup-tags.js.map +1 -0
- package/dist/in-store/drawing-markup.d.ts +184 -0
- package/dist/in-store/drawing-markup.d.ts.map +1 -0
- package/dist/in-store/drawing-markup.js +196 -0
- package/dist/in-store/drawing-markup.js.map +1 -0
- package/dist/in-store/extract-walls.d.ts +16 -16
- package/dist/in-store/extract-walls.d.ts.map +1 -1
- package/dist/in-store/extract-walls.js +31 -289
- package/dist/in-store/extract-walls.js.map +1 -1
- package/dist/in-store/length-unit-scale.d.ts +34 -0
- package/dist/in-store/length-unit-scale.d.ts.map +1 -0
- package/dist/in-store/length-unit-scale.js +44 -0
- package/dist/in-store/length-unit-scale.js.map +1 -0
- package/dist/in-store/placement-frame.d.ts +132 -0
- package/dist/in-store/placement-frame.d.ts.map +1 -0
- package/dist/in-store/placement-frame.js +266 -0
- package/dist/in-store/placement-frame.js.map +1 -0
- package/dist/in-store/resolve-anchor.d.ts.map +1 -1
- package/dist/in-store/resolve-anchor.js +7 -14
- package/dist/in-store/resolve-anchor.js.map +1 -1
- package/dist/in-store/resolve-source.d.ts.map +1 -1
- package/dist/in-store/resolve-source.js +3 -10
- package/dist/in-store/resolve-source.js.map +1 -1
- package/dist/in-store/spatial-zone.js +1 -1
- package/dist/in-store/storey-plan-frame.d.ts +69 -0
- package/dist/in-store/storey-plan-frame.d.ts.map +1 -0
- package/dist/in-store/storey-plan-frame.js +157 -0
- package/dist/in-store/storey-plan-frame.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/types-scheduling.d.ts +169 -0
- package/dist/types-scheduling.d.ts.map +1 -0
- package/dist/types-scheduling.js +5 -0
- package/dist/types-scheduling.js.map +1 -0
- package/dist/types.d.ts +1 -96
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,44 @@
|
|
|
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 { extractLengthUnitScale } from '@ifc-lite/parser';
|
|
5
|
+
/**
|
|
6
|
+
* Single validated read of `extractLengthUnitScale`, shared by every caller
|
|
7
|
+
* in this package that turns the result into a coordinate multiplier.
|
|
8
|
+
*
|
|
9
|
+
* `extractLengthUnitScale` itself never throws and never returns a
|
|
10
|
+
* non-positive or non-finite value for its OWN degenerate inputs — a
|
|
11
|
+
* missing `IFCPROJECT`, an unresolved `UnitsInContext`, a garbled prefix —
|
|
12
|
+
* every one of those routes back to its documented 1.0 fallback (see
|
|
13
|
+
* `unit-extractor.ts`, pinned by `resolve-anchor-zero-scale.test.ts` which
|
|
14
|
+
* mocks the export because the real implementation cannot produce a zero).
|
|
15
|
+
* This wrapper is defense in depth against that contract changing, or
|
|
16
|
+
* against a caller-supplied `entityIndex` whose `.get` throws — without it,
|
|
17
|
+
* a caller trusting the return value verbatim would scale every length in
|
|
18
|
+
* the model by 0, a negative number, or `NaN` with no warning.
|
|
19
|
+
*
|
|
20
|
+
* Returns `null` when the value cannot be trusted (thrown error, `NaN`,
|
|
21
|
+
* non-finite, zero, or negative) rather than guessing on the caller's
|
|
22
|
+
* behalf. Two call sites in this package used to duplicate this guard with
|
|
23
|
+
* different strictness (`?? 1` here only excluded `null`/`undefined`,
|
|
24
|
+
* `Number.isFinite(raw) && raw > 0` there) — on a store where the lookup
|
|
25
|
+
* degenerated, one side would have refused while the other scaled by 0 or
|
|
26
|
+
* 1. Centralizing the check means they cannot disagree again; each caller
|
|
27
|
+
* still decides for itself what "unreliable" means for its own output —
|
|
28
|
+
* `?? 1.0` to keep the existing metres-fallback behaviour, or an early
|
|
29
|
+
* return to refuse the operation outright.
|
|
30
|
+
*/
|
|
31
|
+
export function safeLengthUnitScale(source, entityIndex, context, projectId) {
|
|
32
|
+
try {
|
|
33
|
+
const raw = extractLengthUnitScale(source, entityIndex, projectId);
|
|
34
|
+
if (Number.isFinite(raw) && raw > 0)
|
|
35
|
+
return raw;
|
|
36
|
+
console.warn(`${context}: failed to extract length unit scale; extractLengthUnitScale returned ${raw}`);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.warn(`${context}: failed to extract length unit scale`, error);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=length-unit-scale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"length-unit-scale.js","sourceRoot":"","sources":["../../src/in-store/length-unit-scale.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,sBAAsB,EAAuC,MAAM,kBAAkB,CAAC;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAmC,EACnC,WAAuG,EACvG,OAAe,EACf,SAAkB;IAElB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QAChD,OAAO,CAAC,IAAI,CACV,GAAG,OAAO,0EAA0E,GAAG,EAAE,CAC1F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,uCAAuC,EAAE,KAAK,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planar rigid frames read out of an `IfcLocalPlacement` chain, and the algebra
|
|
3
|
+
* for composing, inverting and applying them.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `extract-walls.ts` so the storey frame has ONE implementation.
|
|
6
|
+
* `extract-walls` needs it to express wall axes and existing space footprints
|
|
7
|
+
* storey-locally; `storey-plan-frame.ts` needs the same chain composed all the
|
|
8
|
+
* way to the model's own world frame, so a producer working in that frame can
|
|
9
|
+
* divide the storey out before authoring into a storey-local slot. Two copies
|
|
10
|
+
* of the composition order or of `invertFrame`'s sign convention would put the
|
|
11
|
+
* read side and the write side on coordinates that differ by a rotation, which
|
|
12
|
+
* is exactly the failure the storey-local contract exists to prevent.
|
|
13
|
+
*
|
|
14
|
+
* Every frame here is 2D and in the file's own raw length unit: the Z-up ground
|
|
15
|
+
* plane of the IFC coordinates, unscaled. Callers that speak metres apply the
|
|
16
|
+
* length-unit scale themselves.
|
|
17
|
+
*/
|
|
18
|
+
import { EntityExtractor, type IfcDataStore, type IfcAttributeValue } from '@ifc-lite/parser';
|
|
19
|
+
import type { Vec2 } from './auto-space-detect.js';
|
|
20
|
+
/**
|
|
21
|
+
* Optional overlay reader. If supplied, overlay walls (entities
|
|
22
|
+
* created via `editor.addEntity('IfcWall', ...)` since the model was
|
|
23
|
+
* parsed) are included alongside the source walls.
|
|
24
|
+
*/
|
|
25
|
+
export interface OverlayWallReader {
|
|
26
|
+
/** Iterate every overlay-created entity. */
|
|
27
|
+
getNewEntities(): Iterable<{
|
|
28
|
+
expressId: number;
|
|
29
|
+
type: string;
|
|
30
|
+
attributes: IfcAttributeValue[];
|
|
31
|
+
}>;
|
|
32
|
+
/** Resolve a positional attribute (with mutations applied). */
|
|
33
|
+
getAttribute?(expressId: number, index: number): IfcAttributeValue | undefined;
|
|
34
|
+
}
|
|
35
|
+
export declare const AXIS_EPS = 0.000001;
|
|
36
|
+
export interface PlacementFrame {
|
|
37
|
+
/** Placement origin in storey-local 2D (X, Y). */
|
|
38
|
+
origin: Vec2;
|
|
39
|
+
/** Local X axis (RefDirection) projected onto the ground plane. */
|
|
40
|
+
axisX: Vec2;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Walk IfcLocalPlacement → IfcAxis2Placement3D → CartesianPoint and read the
|
|
44
|
+
* ground-plane origin + RefDirection *of this one placement*, i.e. expressed
|
|
45
|
+
* in its own `PlacementRelTo` parent's frame. Returns null when any link is
|
|
46
|
+
* missing.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readOwnPlacementFrame(store: IfcDataStore, extractor: EntityExtractor, overlay: OverlayWallReader | undefined, placementId: number): PlacementFrame | null;
|
|
49
|
+
/**
|
|
50
|
+
* The storey's OWN placement chain: its `ObjectPlacement` and every ancestor
|
|
51
|
+
* reachable from it via `IfcLocalPlacement.PlacementRelTo`, mapped to the
|
|
52
|
+
* number of hops from the storey's own placement (`0` for that placement
|
|
53
|
+
* itself). Composition stops when it reaches one of these, and the hop count
|
|
54
|
+
* says how much of the storey's own chain still separates the stopping point
|
|
55
|
+
* from the storey frame — see `frameInStoreyFrame`.
|
|
56
|
+
*
|
|
57
|
+
* Returns `null` — NOT an empty map — when the storey has no resolvable
|
|
58
|
+
* placement, which `IfcProduct.ObjectPlacement` being OPTIONAL makes a
|
|
59
|
+
* well-formed possibility. An empty map is not "no storey frame", it is
|
|
60
|
+
* "a storey frame the walk can never reach": the walk would find nothing to
|
|
61
|
+
* stop on and compose every hop up to the world root, labelling world
|
|
62
|
+
* coordinates storey-local. `frameInStoreyFrame` treats `null` as "compose
|
|
63
|
+
* nothing" instead — see there.
|
|
64
|
+
*/
|
|
65
|
+
export declare function storeyPlacementChain(store: IfcDataStore, extractor: EntityExtractor, overlay: OverlayWallReader | undefined, storeyId: number): Map<number, number> | null;
|
|
66
|
+
/**
|
|
67
|
+
* The storey's frame expressed in the frame of the chain entry `hops` steps
|
|
68
|
+
* above its own placement: compose the storey's first `hops` placements, the
|
|
69
|
+
* innermost one first. `hops === 0` is the storey's own placement, whose frame
|
|
70
|
+
* relative to itself is the identity.
|
|
71
|
+
*
|
|
72
|
+
* Returns `null` when any of those placements has no readable frame — the
|
|
73
|
+
* caller must then leave the element where it is rather than move it by a
|
|
74
|
+
* partial chain.
|
|
75
|
+
*/
|
|
76
|
+
export declare function storeyFrameAboveBy(store: IfcDataStore, extractor: EntityExtractor, overlay: OverlayWallReader | undefined, storeyChain: ReadonlyMap<number, number>, hops: number): PlacementFrame | null;
|
|
77
|
+
/**
|
|
78
|
+
* The inverse of a planar rigid frame: `invertFrame(f)` maps a point expressed
|
|
79
|
+
* in `f`'s parent frame back into `f`'s own frame, so
|
|
80
|
+
* `composeFrames(invertFrame(f), g)` re-expresses `g` — a sibling of `f` in
|
|
81
|
+
* that parent frame — relative to `f`.
|
|
82
|
+
*
|
|
83
|
+
* With `axisX = (c, s)` the frame applies `p ↦ R·p + origin`, `R = [[c,−s],
|
|
84
|
+
* [s,c]]`. The inverse applies `p ↦ Rᵀ·(p − origin)`, and `Rᵀ` is the rotation
|
|
85
|
+
* whose `axisX` is `(c, −s)`, which is why only the Y component flips.
|
|
86
|
+
*/
|
|
87
|
+
export declare function invertFrame(frame: PlacementFrame): PlacementFrame;
|
|
88
|
+
/**
|
|
89
|
+
* Compose `inner` (expressed in `outer`'s frame) with `outer`, giving the
|
|
90
|
+
* frame of `inner` expressed in whatever frame `outer` is expressed in.
|
|
91
|
+
*/
|
|
92
|
+
export declare function composeFrames(outer: PlacementFrame, inner: PlacementFrame): PlacementFrame;
|
|
93
|
+
/**
|
|
94
|
+
* Frame of `placementId` expressed in the STOREY's frame: this placement's
|
|
95
|
+
* own frame composed with every intermediate `IfcLocalPlacement.
|
|
96
|
+
* PlacementRelTo` hop, stopping *before* the storey's own placement.
|
|
97
|
+
*
|
|
98
|
+
* An element's `ObjectPlacement` is not always one hop from its storey. The
|
|
99
|
+
* IFC-standard grouping pattern — an `IfcElementAssembly` for a curtain
|
|
100
|
+
* wall, precast panel run or railing system, all of them in
|
|
101
|
+
* `DEFAULT_DIVIDER_TYPES` — inserts an intermediate `IfcLocalPlacement`
|
|
102
|
+
* between the member and the storey. Reading only the member's own
|
|
103
|
+
* `RelativePlacement` silently drops that hop's translation and rotation, so
|
|
104
|
+
* the member is extracted at the wrong position relative to walls placed
|
|
105
|
+
* directly under the storey: corners that should meet come out disconnected
|
|
106
|
+
* and the enclosed room is never detected.
|
|
107
|
+
*
|
|
108
|
+
* Composition deliberately STOPS at the storey rather than continuing to the
|
|
109
|
+
* root. Storey-local is the frame the write side uses: `generateSpacesFromWalls`
|
|
110
|
+
* hands these segments to `addSpaceToStore`, which authors the new `IfcSpace`
|
|
111
|
+
* with `anchor.storeyPlacementId` as its `PlacementRelTo` (see `space.ts` and
|
|
112
|
+
* `resolve-anchor.ts`). Composing to the root would bake the storey's own
|
|
113
|
+
* offset into the coordinates and the storey placement would then apply it a
|
|
114
|
+
* second time, putting the space a whole site-offset away from its room.
|
|
115
|
+
*
|
|
116
|
+
* A `null` `storeyChain` (storey with no `ObjectPlacement`) means there is no
|
|
117
|
+
* storey frame to compose towards, so no hop is composed at all.
|
|
118
|
+
*/
|
|
119
|
+
export declare function frameInStoreyFrame(store: IfcDataStore, extractor: EntityExtractor, overlay: OverlayWallReader | undefined, placementId: number, storeyChain: ReadonlyMap<number, number> | null): PlacementFrame | null;
|
|
120
|
+
/**
|
|
121
|
+
* Apply a placement frame to a storey-local 2D point. The point's X is
|
|
122
|
+
* along the wall's local axis; Y is perpendicular (perpendicular to
|
|
123
|
+
* the wall direction in the ground plane).
|
|
124
|
+
*/
|
|
125
|
+
export declare function applyFrame(frame: PlacementFrame, local: Vec2): Vec2;
|
|
126
|
+
export declare function readEntity(store: IfcDataStore, extractor: EntityExtractor, overlay: OverlayWallReader | undefined, expressId: number): {
|
|
127
|
+
type?: string;
|
|
128
|
+
attributes: IfcAttributeValue[];
|
|
129
|
+
} | null;
|
|
130
|
+
export declare function numericAttr(v: IfcAttributeValue | undefined): number | null;
|
|
131
|
+
export declare function readVec3(v: IfcAttributeValue | undefined): [number, number, number] | null;
|
|
132
|
+
//# sourceMappingURL=placement-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement-frame.d.ts","sourceRoot":"","sources":["../../src/in-store/placement-frame.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,cAAc,IAAI,QAAQ,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC,CAAC;IACjG,+DAA+D;IAC/D,YAAY,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;CAChF;AAED,eAAO,MAAM,QAAQ,WAAO,CAAC;AAE7B,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,MAAM,EAAE,IAAI,CAAC;IACb,mEAAmE;IACnE,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,WAAW,EAAE,MAAM,GAClB,cAAc,GAAG,IAAI,CA2BvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAa5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,IAAI,EAAE,MAAM,GACX,cAAc,GAAG,IAAI,CAWvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAKjE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,CAY1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAC9C,cAAc,GAAG,IAAI,CA6CvB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAUnE;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAAG,IAAI,CAc3D;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAW3E;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,iBAAiB,GAAG,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAO1F"}
|
|
@@ -0,0 +1,266 @@
|
|
|
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
|
+
export const AXIS_EPS = 1e-6;
|
|
5
|
+
/**
|
|
6
|
+
* Walk IfcLocalPlacement → IfcAxis2Placement3D → CartesianPoint and read the
|
|
7
|
+
* ground-plane origin + RefDirection *of this one placement*, i.e. expressed
|
|
8
|
+
* in its own `PlacementRelTo` parent's frame. Returns null when any link is
|
|
9
|
+
* missing.
|
|
10
|
+
*/
|
|
11
|
+
export function readOwnPlacementFrame(store, extractor, overlay, placementId) {
|
|
12
|
+
const placement = readEntity(store, extractor, overlay, placementId);
|
|
13
|
+
if (!placement)
|
|
14
|
+
return null;
|
|
15
|
+
const axisPlacementId = numericAttr(placement.attributes[1]);
|
|
16
|
+
if (axisPlacementId === null)
|
|
17
|
+
return null;
|
|
18
|
+
const axisPlacement = readEntity(store, extractor, overlay, axisPlacementId);
|
|
19
|
+
if (!axisPlacement)
|
|
20
|
+
return null;
|
|
21
|
+
const locationId = numericAttr(axisPlacement.attributes[0]);
|
|
22
|
+
const refDirId = numericAttr(axisPlacement.attributes[2]);
|
|
23
|
+
if (locationId === null)
|
|
24
|
+
return null;
|
|
25
|
+
const locationEnt = readEntity(store, extractor, overlay, locationId);
|
|
26
|
+
if (!locationEnt)
|
|
27
|
+
return null;
|
|
28
|
+
const origin = readVec3(locationEnt.attributes[0]);
|
|
29
|
+
if (!origin)
|
|
30
|
+
return null;
|
|
31
|
+
let axisX = [1, 0];
|
|
32
|
+
if (refDirId !== null) {
|
|
33
|
+
const refDir = readEntity(store, extractor, overlay, refDirId);
|
|
34
|
+
if (refDir) {
|
|
35
|
+
const dir = readVec3(refDir.attributes[0]);
|
|
36
|
+
if (dir) {
|
|
37
|
+
const len = Math.hypot(dir[0], dir[1]);
|
|
38
|
+
if (len > AXIS_EPS)
|
|
39
|
+
axisX = [dir[0] / len, dir[1] / len];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { origin: [origin[0], origin[1]], axisX };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The storey's OWN placement chain: its `ObjectPlacement` and every ancestor
|
|
47
|
+
* reachable from it via `IfcLocalPlacement.PlacementRelTo`, mapped to the
|
|
48
|
+
* number of hops from the storey's own placement (`0` for that placement
|
|
49
|
+
* itself). Composition stops when it reaches one of these, and the hop count
|
|
50
|
+
* says how much of the storey's own chain still separates the stopping point
|
|
51
|
+
* from the storey frame — see `frameInStoreyFrame`.
|
|
52
|
+
*
|
|
53
|
+
* Returns `null` — NOT an empty map — when the storey has no resolvable
|
|
54
|
+
* placement, which `IfcProduct.ObjectPlacement` being OPTIONAL makes a
|
|
55
|
+
* well-formed possibility. An empty map is not "no storey frame", it is
|
|
56
|
+
* "a storey frame the walk can never reach": the walk would find nothing to
|
|
57
|
+
* stop on and compose every hop up to the world root, labelling world
|
|
58
|
+
* coordinates storey-local. `frameInStoreyFrame` treats `null` as "compose
|
|
59
|
+
* nothing" instead — see there.
|
|
60
|
+
*/
|
|
61
|
+
export function storeyPlacementChain(store, extractor, overlay, storeyId) {
|
|
62
|
+
const chain = new Map();
|
|
63
|
+
const storey = readEntity(store, extractor, overlay, storeyId);
|
|
64
|
+
if (!storey)
|
|
65
|
+
return null;
|
|
66
|
+
let id = numericAttr(storey.attributes[5]); // ObjectPlacement
|
|
67
|
+
if (id === null)
|
|
68
|
+
return null;
|
|
69
|
+
while (id !== null && !chain.has(id)) {
|
|
70
|
+
chain.set(id, chain.size);
|
|
71
|
+
const placement = readEntity(store, extractor, overlay, id);
|
|
72
|
+
if (!placement)
|
|
73
|
+
break;
|
|
74
|
+
id = numericAttr(placement.attributes[0]); // PlacementRelTo
|
|
75
|
+
}
|
|
76
|
+
return chain;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The storey's frame expressed in the frame of the chain entry `hops` steps
|
|
80
|
+
* above its own placement: compose the storey's first `hops` placements, the
|
|
81
|
+
* innermost one first. `hops === 0` is the storey's own placement, whose frame
|
|
82
|
+
* relative to itself is the identity.
|
|
83
|
+
*
|
|
84
|
+
* Returns `null` when any of those placements has no readable frame — the
|
|
85
|
+
* caller must then leave the element where it is rather than move it by a
|
|
86
|
+
* partial chain.
|
|
87
|
+
*/
|
|
88
|
+
export function storeyFrameAboveBy(store, extractor, overlay, storeyChain, hops) {
|
|
89
|
+
let frame = { origin: [0, 0], axisX: [1, 0] };
|
|
90
|
+
let composed = 0;
|
|
91
|
+
for (const id of storeyChain.keys()) {
|
|
92
|
+
if (composed >= hops)
|
|
93
|
+
break;
|
|
94
|
+
const own = readOwnPlacementFrame(store, extractor, overlay, id);
|
|
95
|
+
if (!own)
|
|
96
|
+
return null;
|
|
97
|
+
frame = composeFrames(own, frame);
|
|
98
|
+
composed += 1;
|
|
99
|
+
}
|
|
100
|
+
return composed === hops ? frame : null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The inverse of a planar rigid frame: `invertFrame(f)` maps a point expressed
|
|
104
|
+
* in `f`'s parent frame back into `f`'s own frame, so
|
|
105
|
+
* `composeFrames(invertFrame(f), g)` re-expresses `g` — a sibling of `f` in
|
|
106
|
+
* that parent frame — relative to `f`.
|
|
107
|
+
*
|
|
108
|
+
* With `axisX = (c, s)` the frame applies `p ↦ R·p + origin`, `R = [[c,−s],
|
|
109
|
+
* [s,c]]`. The inverse applies `p ↦ Rᵀ·(p − origin)`, and `Rᵀ` is the rotation
|
|
110
|
+
* whose `axisX` is `(c, −s)`, which is why only the Y component flips.
|
|
111
|
+
*/
|
|
112
|
+
export function invertFrame(frame) {
|
|
113
|
+
const c = frame.axisX[0];
|
|
114
|
+
const s = frame.axisX[1];
|
|
115
|
+
const [ox, oy] = frame.origin;
|
|
116
|
+
return { origin: [-(c * ox + s * oy), -(-s * ox + c * oy)], axisX: [c, -s] };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compose `inner` (expressed in `outer`'s frame) with `outer`, giving the
|
|
120
|
+
* frame of `inner` expressed in whatever frame `outer` is expressed in.
|
|
121
|
+
*/
|
|
122
|
+
export function composeFrames(outer, inner) {
|
|
123
|
+
const ax = outer.axisX[0];
|
|
124
|
+
const ay = outer.axisX[1];
|
|
125
|
+
// Perpendicular = rotate axisX 90° CCW around +Z — same convention as
|
|
126
|
+
// `applyFrame`, which this must agree with exactly.
|
|
127
|
+
const px = -ay;
|
|
128
|
+
const py = ax;
|
|
129
|
+
return {
|
|
130
|
+
origin: applyFrame(outer, inner.origin),
|
|
131
|
+
// Directions rotate but do not translate.
|
|
132
|
+
axisX: [ax * inner.axisX[0] + px * inner.axisX[1], ay * inner.axisX[0] + py * inner.axisX[1]],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Frame of `placementId` expressed in the STOREY's frame: this placement's
|
|
137
|
+
* own frame composed with every intermediate `IfcLocalPlacement.
|
|
138
|
+
* PlacementRelTo` hop, stopping *before* the storey's own placement.
|
|
139
|
+
*
|
|
140
|
+
* An element's `ObjectPlacement` is not always one hop from its storey. The
|
|
141
|
+
* IFC-standard grouping pattern — an `IfcElementAssembly` for a curtain
|
|
142
|
+
* wall, precast panel run or railing system, all of them in
|
|
143
|
+
* `DEFAULT_DIVIDER_TYPES` — inserts an intermediate `IfcLocalPlacement`
|
|
144
|
+
* between the member and the storey. Reading only the member's own
|
|
145
|
+
* `RelativePlacement` silently drops that hop's translation and rotation, so
|
|
146
|
+
* the member is extracted at the wrong position relative to walls placed
|
|
147
|
+
* directly under the storey: corners that should meet come out disconnected
|
|
148
|
+
* and the enclosed room is never detected.
|
|
149
|
+
*
|
|
150
|
+
* Composition deliberately STOPS at the storey rather than continuing to the
|
|
151
|
+
* root. Storey-local is the frame the write side uses: `generateSpacesFromWalls`
|
|
152
|
+
* hands these segments to `addSpaceToStore`, which authors the new `IfcSpace`
|
|
153
|
+
* with `anchor.storeyPlacementId` as its `PlacementRelTo` (see `space.ts` and
|
|
154
|
+
* `resolve-anchor.ts`). Composing to the root would bake the storey's own
|
|
155
|
+
* offset into the coordinates and the storey placement would then apply it a
|
|
156
|
+
* second time, putting the space a whole site-offset away from its room.
|
|
157
|
+
*
|
|
158
|
+
* A `null` `storeyChain` (storey with no `ObjectPlacement`) means there is no
|
|
159
|
+
* storey frame to compose towards, so no hop is composed at all.
|
|
160
|
+
*/
|
|
161
|
+
export function frameInStoreyFrame(store, extractor, overlay, placementId, storeyChain) {
|
|
162
|
+
let frame = readOwnPlacementFrame(store, extractor, overlay, placementId);
|
|
163
|
+
if (!frame)
|
|
164
|
+
return null;
|
|
165
|
+
// No storey placement at all (`ObjectPlacement` is OPTIONAL): there is no
|
|
166
|
+
// storey frame to compose towards and nothing for the walk to stop on, so
|
|
167
|
+
// walking parents would run to the world root and return world coordinates
|
|
168
|
+
// where every caller expects storey-local ones. Compose nothing — the
|
|
169
|
+
// element's own frame, which is what this returned before the chain walk
|
|
170
|
+
// existed — and leave the element where its own placement puts it rather
|
|
171
|
+
// than silently moving it by the site and building offsets.
|
|
172
|
+
if (!storeyChain)
|
|
173
|
+
return frame;
|
|
174
|
+
// Visited-set termination: exact for cyclic/self-referential
|
|
175
|
+
// `PlacementRelTo` in malformed IFC, and needs no arbitrary depth bound.
|
|
176
|
+
const visited = new Set([placementId]);
|
|
177
|
+
let currentId = placementId;
|
|
178
|
+
for (;;) {
|
|
179
|
+
const placement = readEntity(store, extractor, overlay, currentId);
|
|
180
|
+
const relToId = placement ? numericAttr(placement.attributes[0]) : null;
|
|
181
|
+
// The walk joins the storey's own chain (or runs out of parents at the
|
|
182
|
+
// root, where the storey's chain also ends). `frame` is now expressed in
|
|
183
|
+
// that shared ancestor's frame, and the storey sits `hops` placements
|
|
184
|
+
// below it — `hops === 0` when the ancestor IS the storey's placement,
|
|
185
|
+
// the common shape, where the frame is already storey-local.
|
|
186
|
+
if (relToId === null || storeyChain.has(relToId)) {
|
|
187
|
+
const hops = relToId === null ? storeyChain.size : storeyChain.get(relToId);
|
|
188
|
+
if (hops === 0)
|
|
189
|
+
return frame;
|
|
190
|
+
// #3003: the wall joined the chain ABOVE the storey, so the storey's own
|
|
191
|
+
// hops are in `frame` and every caller reads the result as storey-local.
|
|
192
|
+
// Divide them out — the INVERSE of the storey's frame in the shared
|
|
193
|
+
// ancestor, applied to the wall's frame in that same ancestor. Applying
|
|
194
|
+
// the storey frame itself instead would double the offset rather than
|
|
195
|
+
// remove it, so the two directions land on different coordinates and the
|
|
196
|
+
// #3003 fixture pins which one this is.
|
|
197
|
+
const storeyFrame = storeyFrameAboveBy(store, extractor, overlay, storeyChain, hops);
|
|
198
|
+
return storeyFrame ? composeFrames(invertFrame(storeyFrame), frame) : frame;
|
|
199
|
+
}
|
|
200
|
+
// A cycle in a malformed `PlacementRelTo`: nothing above is trustworthy,
|
|
201
|
+
// so stop with what has been composed so far.
|
|
202
|
+
if (visited.has(relToId))
|
|
203
|
+
return frame;
|
|
204
|
+
const parent = readOwnPlacementFrame(store, extractor, overlay, relToId);
|
|
205
|
+
if (!parent)
|
|
206
|
+
return frame;
|
|
207
|
+
frame = composeFrames(parent, frame);
|
|
208
|
+
visited.add(relToId);
|
|
209
|
+
currentId = relToId;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Apply a placement frame to a storey-local 2D point. The point's X is
|
|
214
|
+
* along the wall's local axis; Y is perpendicular (perpendicular to
|
|
215
|
+
* the wall direction in the ground plane).
|
|
216
|
+
*/
|
|
217
|
+
export function applyFrame(frame, local) {
|
|
218
|
+
const ax = frame.axisX[0];
|
|
219
|
+
const ay = frame.axisX[1];
|
|
220
|
+
// Perpendicular = rotate axisX 90° CCW around +Z.
|
|
221
|
+
const px = -ay;
|
|
222
|
+
const py = ax;
|
|
223
|
+
return [
|
|
224
|
+
frame.origin[0] + ax * local[0] + px * local[1],
|
|
225
|
+
frame.origin[1] + ay * local[0] + py * local[1],
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
export function readEntity(store, extractor, overlay, expressId) {
|
|
229
|
+
const ref = store.entityIndex.byId.get(expressId);
|
|
230
|
+
if (ref && ref.byteLength > 0 && ref.byteOffset >= 0) {
|
|
231
|
+
return extractor.extractEntity(ref);
|
|
232
|
+
}
|
|
233
|
+
// Overlay-only entity: fall back to the overlay reader.
|
|
234
|
+
if (overlay) {
|
|
235
|
+
for (const ent of overlay.getNewEntities()) {
|
|
236
|
+
if (ent.expressId === expressId) {
|
|
237
|
+
return { type: ent.type, attributes: ent.attributes };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
export function numericAttr(v) {
|
|
244
|
+
if (typeof v === 'number')
|
|
245
|
+
return v;
|
|
246
|
+
if (typeof v === 'string') {
|
|
247
|
+
if (v.startsWith('#')) {
|
|
248
|
+
const n = Number(v.slice(1));
|
|
249
|
+
return Number.isFinite(n) ? n : null;
|
|
250
|
+
}
|
|
251
|
+
const n = Number(v);
|
|
252
|
+
return Number.isFinite(n) ? n : null;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
export function readVec3(v) {
|
|
257
|
+
if (!Array.isArray(v) || v.length < 2)
|
|
258
|
+
return null;
|
|
259
|
+
const x = numericAttr(v[0]);
|
|
260
|
+
const y = numericAttr(v[1]);
|
|
261
|
+
const z = v.length >= 3 ? numericAttr(v[2]) : 0;
|
|
262
|
+
if (x === null || y === null || z === null)
|
|
263
|
+
return null;
|
|
264
|
+
return [x, y, z];
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=placement-frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement-frame.js","sourceRoot":"","sources":["../../src/in-store/placement-frame.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAuC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAS7B;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAmB,EACnB,SAA0B,EAC1B,OAAsC,EACtC,WAAmB;IAEnB,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACrE,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,IAAI,eAAe,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7E,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACtE,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,IAAI,KAAK,GAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/D,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,IAAI,GAAG,GAAG,QAAQ;oBAAE,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAmB,EACnB,SAA0B,EAC1B,OAAsC,EACtC,QAAgB;IAEhB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACrC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS;YAAE,MAAM;QACtB,EAAE,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,SAA0B,EAC1B,OAAsC,EACtC,WAAwC,EACxC,IAAY;IAEZ,IAAI,KAAK,GAAmB,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC9D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,EAAE,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACpC,IAAI,QAAQ,IAAI,IAAI;YAAE,MAAM;QAC5B,MAAM,GAAG,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,QAAQ,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,KAAqB;IAC/C,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB,EAAE,KAAqB;IACxE,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IACf,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,OAAO;QACL,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC;QACvC,0CAA0C;QAC1C,KAAK,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC9F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,SAA0B,EAC1B,OAAsC,EACtC,WAAmB,EACnB,WAA+C;IAE/C,IAAI,KAAK,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC1E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,0EAA0E;IAC1E,0EAA0E;IAC1E,2EAA2E;IAC3E,sEAAsE;IACtE,yEAAyE;IACzE,yEAAyE;IACzE,4DAA4D;IAC5D,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,6DAA6D;IAC7D,yEAAyE;IACzE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/C,IAAI,SAAS,GAAG,WAAW,CAAC;IAC5B,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACxE,uEAAuE;QACvE,yEAAyE;QACzE,sEAAsE;QACtE,uEAAuE;QACvE,6DAA6D;QAC7D,IAAI,OAAO,KAAK,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAY,CAAC;YACxF,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7B,yEAAyE;YACzE,yEAAyE;YACzE,oEAAoE;YACpE,wEAAwE;YACxE,sEAAsE;YACtE,yEAAyE;YACzE,wCAAwC;YACxC,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACrF,OAAO,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9E,CAAC;QACD,yEAAyE;QACzE,8CAA8C;QAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACvC,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,SAAS,GAAG,OAAO,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAqB,EAAE,KAAW;IAC3D,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,kDAAkD;IAClD,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IACf,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;QAC/C,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,KAAmB,EACnB,SAA0B,EAC1B,OAAsC,EACtC,SAAiB;IAEjB,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;QACrD,OAAO,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,wDAAwD;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3C,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAgC;IAC1D,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvC,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAgC;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-anchor.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-anchor.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"resolve-anchor.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-anchor.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,aAAa,CAAC;AAGtE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,GAAG,aAAa,CA+ChG"}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* 3D IfcGeometricRepresentationContext), and the target storey's
|
|
10
10
|
* IfcLocalPlacement.
|
|
11
11
|
*/
|
|
12
|
-
import { EntityExtractor,
|
|
12
|
+
import { EntityExtractor, getAttributeNames } from '@ifc-lite/parser';
|
|
13
|
+
import { safeLengthUnitScale } from './length-unit-scale.js';
|
|
13
14
|
export function resolveSpatialAnchor(store, storeyExpressId) {
|
|
14
15
|
// OwnerHistory is OPTIONAL from IFC4 onward — minimal files (including
|
|
15
16
|
// ifc-lite's own exports) legitimately omit it. Builders emit `$` then.
|
|
@@ -41,19 +42,11 @@ export function resolveSpatialAnchor(store, storeyExpressId) {
|
|
|
41
42
|
// exports). Resolve the length-unit scale here so builders can emit
|
|
42
43
|
// coordinates in the file's native unit — mirrors the read-side
|
|
43
44
|
// conversion in extract-walls.ts.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
lengthUnitScale = s;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
// Keep the metre fallback, but don't hide the failure — a wrong scale
|
|
54
|
-
// emits silently mis-sized geometry.
|
|
55
|
-
console.warn('resolveSpatialAnchor: failed to extract length unit scale; defaulting to metres', error);
|
|
56
|
-
}
|
|
45
|
+
// Keep the metre fallback on a failed lookup, but don't hide it — a wrong
|
|
46
|
+
// scale emits silently mis-sized geometry. `safeLengthUnitScale` warns.
|
|
47
|
+
const lengthUnitScale = store.source.byteLength > 0
|
|
48
|
+
? safeLengthUnitScale(store.source, store.entityIndex, 'resolveSpatialAnchor') ?? 1.0
|
|
49
|
+
: 1.0;
|
|
57
50
|
return { ownerHistoryId, bodyContextId, axisContextId, storeyId: storeyExpressId, storeyPlacementId, schema, lengthUnitScale };
|
|
58
51
|
}
|
|
59
52
|
function findOwnerHistoryId(store) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-anchor.js","sourceRoot":"","sources":["../../src/in-store/resolve-anchor.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"resolve-anchor.js","sourceRoot":"","sources":["../../src/in-store/resolve-anchor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-source.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"resolve-source.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEtE,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,gBAAgB,CAAC;AA0ChF;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,GACtB,gBAAgB,CA0GlB"}
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* Lives in @ifc-lite/create alongside the in-store builders so the
|
|
12
12
|
* backend layer can call it without needing parser internals.
|
|
13
13
|
*/
|
|
14
|
-
import { EntityExtractor
|
|
14
|
+
import { EntityExtractor } from '@ifc-lite/parser';
|
|
15
|
+
import { safeLengthUnitScale } from './length-unit-scale.js';
|
|
15
16
|
/**
|
|
16
17
|
* Rel types whose `RelatedObjects` list is replayed against a
|
|
17
18
|
* duplicate so the export carries the same psets / qsets / material /
|
|
@@ -128,15 +129,7 @@ export function resolveDuplicateSource(store, sourceExpressId) {
|
|
|
128
129
|
// Metres per native unit (0.001 for a millimetre file) — lets the
|
|
129
130
|
// duplicate flow convert its metre offset onto the native-unit
|
|
130
131
|
// sourceLocation. Falls back to 1 (metres) on extraction failure.
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
const s = extractLengthUnitScale(store.source, store.entityIndex);
|
|
134
|
-
if (Number.isFinite(s) && s > 0)
|
|
135
|
-
lengthUnitScale = s;
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
console.warn('resolveDuplicateSource: failed to extract length unit scale; defaulting to metres', error);
|
|
139
|
-
}
|
|
132
|
+
const lengthUnitScale = safeLengthUnitScale(store.source, store.entityIndex, 'resolveDuplicateSource') ?? 1.0;
|
|
140
133
|
return {
|
|
141
134
|
// Canonical PascalCase (e.g. "IfcWall"); falls back to the raw
|
|
142
135
|
// extractor type when the entity table doesn't recognise the id
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-source.js","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"resolve-source.js","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* that is not bounded by physical elements (issue #2508 item 3).
|
|
7
7
|
*
|
|
8
8
|
* A location zone is a construction section or takt area a user drew against
|
|
9
|
-
* the rendered scene. `docs/
|
|
9
|
+
* the rendered scene. `docs/architecture/spatial-zone-emission.md` argues why it must NOT be
|
|
10
10
|
* emitted as an `IfcZone`: that type groups SPACES, its `IsGroupedBy` admits
|
|
11
11
|
* only `IfcSpace` / `IfcSpatialZone` / nested `IfcZone`, and this repo's own
|
|
12
12
|
* reader (`extractGroupMembersOnDemand`) describes an `IfcZone`'s members that
|