@ifc-lite/create 1.15.1 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/in-store/_emit-helpers.d.ts +8 -2
- package/dist/in-store/_emit-helpers.d.ts.map +1 -1
- package/dist/in-store/_emit-helpers.js +10 -2
- package/dist/in-store/_emit-helpers.js.map +1 -1
- package/dist/in-store/anchor.d.ts +25 -2
- package/dist/in-store/anchor.d.ts.map +1 -1
- package/dist/in-store/anchor.js +19 -1
- package/dist/in-store/anchor.js.map +1 -1
- package/dist/in-store/auto-space-detect.d.ts.map +1 -1
- package/dist/in-store/auto-space-detect.js +53 -0
- package/dist/in-store/auto-space-detect.js.map +1 -1
- package/dist/in-store/beam.d.ts +1 -1
- package/dist/in-store/beam.d.ts.map +1 -1
- package/dist/in-store/beam.js +13 -2
- package/dist/in-store/beam.js.map +1 -1
- package/dist/in-store/column.d.ts +1 -1
- package/dist/in-store/column.d.ts.map +1 -1
- package/dist/in-store/column.js +17 -2
- package/dist/in-store/column.js.map +1 -1
- package/dist/in-store/door.d.ts +1 -1
- package/dist/in-store/door.d.ts.map +1 -1
- package/dist/in-store/door.js +13 -2
- package/dist/in-store/door.js.map +1 -1
- package/dist/in-store/duplicate.d.ts +7 -0
- package/dist/in-store/duplicate.d.ts.map +1 -1
- package/dist/in-store/duplicate.js +10 -3
- package/dist/in-store/duplicate.js.map +1 -1
- package/dist/in-store/extract-walls.d.ts +28 -1
- package/dist/in-store/extract-walls.d.ts.map +1 -1
- package/dist/in-store/extract-walls.js +350 -8
- package/dist/in-store/extract-walls.js.map +1 -1
- package/dist/in-store/generate-spaces-all.d.ts +72 -0
- package/dist/in-store/generate-spaces-all.d.ts.map +1 -0
- package/dist/in-store/generate-spaces-all.js +84 -0
- package/dist/in-store/generate-spaces-all.js.map +1 -0
- package/dist/in-store/generate-spaces.d.ts +33 -1
- package/dist/in-store/generate-spaces.d.ts.map +1 -1
- package/dist/in-store/generate-spaces.js +258 -3
- package/dist/in-store/generate-spaces.js.map +1 -1
- package/dist/in-store/member.d.ts +1 -1
- package/dist/in-store/member.d.ts.map +1 -1
- package/dist/in-store/member.js +10 -0
- package/dist/in-store/member.js.map +1 -1
- package/dist/in-store/plate.d.ts +1 -1
- package/dist/in-store/plate.d.ts.map +1 -1
- package/dist/in-store/plate.js +27 -9
- package/dist/in-store/plate.js.map +1 -1
- package/dist/in-store/resolve-anchor.d.ts.map +1 -1
- package/dist/in-store/resolve-anchor.js +21 -5
- 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 +14 -1
- package/dist/in-store/resolve-source.js.map +1 -1
- package/dist/in-store/roof.d.ts +1 -1
- package/dist/in-store/roof.d.ts.map +1 -1
- package/dist/in-store/roof.js +27 -9
- package/dist/in-store/roof.js.map +1 -1
- package/dist/in-store/slab.d.ts +1 -1
- package/dist/in-store/slab.d.ts.map +1 -1
- package/dist/in-store/slab.js +30 -11
- package/dist/in-store/slab.js.map +1 -1
- package/dist/in-store/space.d.ts +28 -1
- package/dist/in-store/space.d.ts.map +1 -1
- package/dist/in-store/space.js +91 -8
- package/dist/in-store/space.js.map +1 -1
- package/dist/in-store/wall.d.ts +1 -1
- package/dist/in-store/wall.d.ts.map +1 -1
- package/dist/in-store/wall.js +15 -2
- package/dist/in-store/wall.js.map +1 -1
- package/dist/in-store/window.d.ts +1 -1
- package/dist/in-store/window.d.ts.map +1 -1
- package/dist/in-store/window.js +13 -2
- package/dist/in-store/window.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level orchestrator over {@link generateSpacesFromWalls}: derive
|
|
3
|
+
* `IfcSpace` across one, several, or all storeys in a model, with
|
|
4
|
+
* auto-escalating snap tolerance and storey-aware heights. This is the engine
|
|
5
|
+
* the CLI (`ifc-lite generate-spaces`) and SDK (`bim.spaces.generate`) share.
|
|
6
|
+
*
|
|
7
|
+
* Footprint comes from the storey's walls (+ other dividers); the vertical
|
|
8
|
+
* extent ("from slabs/roofs") is taken from the storey datums — storeys sit at
|
|
9
|
+
* slab levels, so `height: 'auto'` uses floor-to-floor from `storeyElevations`,
|
|
10
|
+
* and the topmost storey (capped by the roof) falls back to `topStoreyHeight`.
|
|
11
|
+
* Geometry-exact slab/roof undersides are a future refinement.
|
|
12
|
+
*/
|
|
13
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
14
|
+
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
15
|
+
import { type GenerateSpacesResult, type BoundaryMode } from './generate-spaces.js';
|
|
16
|
+
import { type OverlayWallReader } from './extract-walls.js';
|
|
17
|
+
export interface GenerateSpacesAllOptions {
|
|
18
|
+
/** Which storeys: `'all'` (default) or specific express ids. */
|
|
19
|
+
storeys?: 'all' | number[];
|
|
20
|
+
/** Corner-closing tolerance (m), or `'auto'` (default) to escalate the ladder. */
|
|
21
|
+
snap?: number | 'auto';
|
|
22
|
+
/** Drop regions below this area (m²). Default 0.5. */
|
|
23
|
+
minArea?: number;
|
|
24
|
+
/** Space height (m), or `'auto'` (default) = floor-to-floor from storey elevations. */
|
|
25
|
+
height?: number | 'auto';
|
|
26
|
+
/** Height for the topmost storey under `'auto'` (no storey above). Default 3. */
|
|
27
|
+
topStoreyHeight?: number;
|
|
28
|
+
/** Name pattern; `{n}` → 1-based index per storey, `{storey}` → storey name. */
|
|
29
|
+
namePattern?: string;
|
|
30
|
+
/** IfcSpacePredefinedType (default INTERNAL). */
|
|
31
|
+
predefinedType?: string;
|
|
32
|
+
/** Extra divider element types (case-insensitive) beyond the defaults. */
|
|
33
|
+
extraDividerTypes?: string[];
|
|
34
|
+
/** Where the space boundary sits relative to its walls. Default 'inner'. */
|
|
35
|
+
boundaryMode?: BoundaryMode;
|
|
36
|
+
/** Detect + report only; emit no IfcSpace. */
|
|
37
|
+
dryRun?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Re-derive even when the model already contains spaces from a prior run.
|
|
40
|
+
* Off by default — the run is skipped so re-processing its own output can't
|
|
41
|
+
* duplicate spaces. `true` bypasses the guard (may duplicate).
|
|
42
|
+
*/
|
|
43
|
+
force?: boolean;
|
|
44
|
+
debug?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface StoreyInfo {
|
|
47
|
+
id: number;
|
|
48
|
+
name: string;
|
|
49
|
+
elevation: number;
|
|
50
|
+
}
|
|
51
|
+
export interface GenerateSpacesStoreyResult extends StoreyInfo {
|
|
52
|
+
/** Height used for this storey's spaces (m). */
|
|
53
|
+
height: number;
|
|
54
|
+
/** Snap tolerance used (m) — the resolved value when `snap: 'auto'`. */
|
|
55
|
+
snapUsed: number;
|
|
56
|
+
result: GenerateSpacesResult;
|
|
57
|
+
}
|
|
58
|
+
export interface GenerateSpacesAllResult {
|
|
59
|
+
storeys: GenerateSpacesStoreyResult[];
|
|
60
|
+
totalDetected: number;
|
|
61
|
+
totalEmitted: number;
|
|
62
|
+
/**
|
|
63
|
+
* Detected rooms skipped because they overlap an existing space (authored or
|
|
64
|
+
* from a prior run) — per-space, so non-overlapping rooms on the same storey
|
|
65
|
+
* are still emitted. Always 0 when `force` is set.
|
|
66
|
+
*/
|
|
67
|
+
skippedExisting: number;
|
|
68
|
+
}
|
|
69
|
+
/** Every IfcBuildingStorey with resolved name + elevation, low → high. */
|
|
70
|
+
export declare function listStoreys(store: IfcDataStore): StoreyInfo[];
|
|
71
|
+
export declare function generateSpaces(editor: StoreEditor, store: IfcDataStore, options?: GenerateSpacesAllOptions, overlay?: OverlayWallReader): GenerateSpacesAllResult;
|
|
72
|
+
//# sourceMappingURL=generate-spaces-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-spaces-all.d.ts","sourceRoot":"","sources":["../../src/in-store/generate-spaces-all.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAmC,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAO7F,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;IAC3B,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,UAAU;IAC5D,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CAS7D;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,wBAA6B,EACtC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,uBAAuB,CAoDzB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
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 { generateSpacesFromWalls, } from './generate-spaces.js';
|
|
5
|
+
import { existingSpaceFootprintsByStorey } from './extract-walls.js';
|
|
6
|
+
/** Snap tolerances tried, in order, when `snap: 'auto'`. First that encloses
|
|
7
|
+
* rooms wins (least over-merging); else the largest is used. */
|
|
8
|
+
const AUTO_SNAP_LADDER = [0.1, 0.25, 0.5];
|
|
9
|
+
const DEFAULT_TOP_HEIGHT = 3;
|
|
10
|
+
/** Every IfcBuildingStorey with resolved name + elevation, low → high. */
|
|
11
|
+
export function listStoreys(store) {
|
|
12
|
+
const elevs = store.spatialHierarchy?.storeyElevations;
|
|
13
|
+
const list = store.getEntitiesByType('IfcBuildingStorey').map((s) => ({
|
|
14
|
+
id: s.expressId,
|
|
15
|
+
name: store.entities.getName(s.expressId) || `Storey #${s.expressId}`,
|
|
16
|
+
elevation: elevs?.get(s.expressId) ?? 0,
|
|
17
|
+
}));
|
|
18
|
+
list.sort((a, b) => a.elevation - b.elevation);
|
|
19
|
+
return list;
|
|
20
|
+
}
|
|
21
|
+
export function generateSpaces(editor, store, options = {}, overlay) {
|
|
22
|
+
const all = listStoreys(store);
|
|
23
|
+
const want = options.storeys;
|
|
24
|
+
const selected = want === undefined || want === 'all'
|
|
25
|
+
? all
|
|
26
|
+
: all.filter((s) => want.includes(s.id));
|
|
27
|
+
// Per-space dedup: skip detected rooms that overlap an existing space, while
|
|
28
|
+
// still emitting non-overlapping rooms on the same storey. `force` opts out.
|
|
29
|
+
const footprintsByStorey = options.force ? new Map() : existingSpaceFootprintsByStorey(store);
|
|
30
|
+
const minArea = options.minArea ?? 0.5;
|
|
31
|
+
const topH = options.topStoreyHeight ?? DEFAULT_TOP_HEIGHT;
|
|
32
|
+
const snapMode = options.snap ?? 'auto';
|
|
33
|
+
const heightMode = options.height ?? 'auto';
|
|
34
|
+
const storeys = [];
|
|
35
|
+
let totalDetected = 0;
|
|
36
|
+
let totalEmitted = 0;
|
|
37
|
+
let skippedExisting = 0;
|
|
38
|
+
for (const st of selected) {
|
|
39
|
+
const height = resolveHeight(heightMode, st, all, topH);
|
|
40
|
+
const snapUsed = resolveSnap(snapMode, editor, store, st.id, minArea, overlay);
|
|
41
|
+
const namePattern = (options.namePattern ?? 'Space {n}').replaceAll('{storey}', st.name);
|
|
42
|
+
const result = generateSpacesFromWalls(editor, store, st.id, {
|
|
43
|
+
snapTolerance: snapUsed,
|
|
44
|
+
minArea,
|
|
45
|
+
height,
|
|
46
|
+
namePattern,
|
|
47
|
+
predefinedType: options.predefinedType,
|
|
48
|
+
extraDividerTypes: options.extraDividerTypes,
|
|
49
|
+
dryRun: options.dryRun,
|
|
50
|
+
boundaryMode: options.boundaryMode,
|
|
51
|
+
debug: options.debug,
|
|
52
|
+
skipFootprints: footprintsByStorey.get(st.id),
|
|
53
|
+
}, overlay);
|
|
54
|
+
totalDetected += result.detected.length;
|
|
55
|
+
totalEmitted += result.emitted.length;
|
|
56
|
+
skippedExisting += result.skippedExisting;
|
|
57
|
+
storeys.push({ ...st, height, snapUsed, result });
|
|
58
|
+
}
|
|
59
|
+
return { storeys, totalDetected, totalEmitted, skippedExisting };
|
|
60
|
+
}
|
|
61
|
+
function resolveHeight(mode, st, all, topH) {
|
|
62
|
+
if (typeof mode === 'number')
|
|
63
|
+
return mode > 0 ? mode : topH;
|
|
64
|
+
const idx = all.findIndex((s) => s.id === st.id);
|
|
65
|
+
const next = idx >= 0 ? all[idx + 1] : undefined;
|
|
66
|
+
const h = next ? next.elevation - st.elevation : topH;
|
|
67
|
+
// Guard against bad/degenerate elevation data.
|
|
68
|
+
return h > 0.1 && h < 50 ? h : topH;
|
|
69
|
+
}
|
|
70
|
+
function resolveSnap(mode, editor, store, storeyId, minArea, overlay) {
|
|
71
|
+
if (typeof mode === 'number')
|
|
72
|
+
return mode;
|
|
73
|
+
// Escalate via dry runs (no emission) and take the first tolerance that
|
|
74
|
+
// encloses any room; else the largest tried.
|
|
75
|
+
let used = AUTO_SNAP_LADDER[0];
|
|
76
|
+
for (const tol of AUTO_SNAP_LADDER) {
|
|
77
|
+
used = tol;
|
|
78
|
+
const dry = generateSpacesFromWalls(editor, store, storeyId, { snapTolerance: tol, minArea, dryRun: true }, overlay);
|
|
79
|
+
if (dry.detected.length > 0)
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
return used;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=generate-spaces-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-spaces-all.js","sourceRoot":"","sources":["../../src/in-store/generate-spaces-all.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,8 +13,14 @@
|
|
|
13
13
|
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
14
14
|
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
15
15
|
import { type OverlayWallReader, type WallSkip } from './extract-walls.js';
|
|
16
|
-
import { type DetectedSpace, type DetectStats } from './auto-space-detect.js';
|
|
16
|
+
import { type DetectedSpace, type DetectStats, type Segment, type Vec2 } from './auto-space-detect.js';
|
|
17
17
|
import { type SpaceBuildResult } from './space.js';
|
|
18
|
+
/**
|
|
19
|
+
* IfcSpace.ObjectType marker stamped on every derived space, so a re-run can
|
|
20
|
+
* recognise its own output and skip it instead of duplicating (idempotency),
|
|
21
|
+
* and so generated spaces are filterable downstream.
|
|
22
|
+
*/
|
|
23
|
+
export declare const GENERATED_SPACE_OBJECTTYPE = "IfcLite:GeneratedSpace";
|
|
18
24
|
export interface GenerateSpacesOptions {
|
|
19
25
|
/** Snap tolerance for wall-end vertex merge in METRES. Default 0.1 m. */
|
|
20
26
|
snapTolerance?: number;
|
|
@@ -48,6 +54,16 @@ export interface GenerateSpacesOptions {
|
|
|
48
54
|
* members, and railings.
|
|
49
55
|
*/
|
|
50
56
|
extraDividerTypes?: string[];
|
|
57
|
+
/**
|
|
58
|
+
* Footprint polygons (same metre frame as the detected rooms) of existing
|
|
59
|
+
* spaces on this storey. A detected room whose centroid falls inside one is
|
|
60
|
+
* an overlap with an already-present space and is skipped — so re-running
|
|
61
|
+
* (or filling a partly-spaced floor) doesn't duplicate spaces. Per-space, not
|
|
62
|
+
* per-storey: non-overlapping rooms are still emitted.
|
|
63
|
+
*/
|
|
64
|
+
skipFootprints?: Vec2[][];
|
|
65
|
+
/** Where the space boundary sits relative to its walls. Default 'inner'. */
|
|
66
|
+
boundaryMode?: BoundaryMode;
|
|
51
67
|
}
|
|
52
68
|
export interface GenerateSpacesResult {
|
|
53
69
|
/** Total walls considered (existing + overlay) on the storey. */
|
|
@@ -66,6 +82,22 @@ export interface GenerateSpacesResult {
|
|
|
66
82
|
result: SpaceBuildResult;
|
|
67
83
|
name: string;
|
|
68
84
|
}>;
|
|
85
|
+
/** Detected rooms skipped because they overlap an existing space. */
|
|
86
|
+
skippedExisting: number;
|
|
69
87
|
}
|
|
70
88
|
export declare function generateSpacesFromWalls(editor: StoreEditor, store: IfcDataStore, storeyExpressId: number, options?: GenerateSpacesOptions, overlay?: OverlayWallReader): GenerateSpacesResult;
|
|
89
|
+
/** How a space boundary relates to its bounding walls. */
|
|
90
|
+
export type BoundaryMode = 'center' | 'inner' | 'outer';
|
|
91
|
+
/**
|
|
92
|
+
* Offset a (centreline) room outline to the chosen wall boundary: `center` =
|
|
93
|
+
* the centreline as-is; `inner` = each edge shifted toward the room by half the
|
|
94
|
+
* wall thickness (net / inner face); `outer` = shifted away by half (gross /
|
|
95
|
+
* outer face). Re-corners by intersecting adjacent offset edges. `segments[k]`
|
|
96
|
+
* has thickness `wallThicknesses[k]`. `otherRooms` (other rooms' centreline
|
|
97
|
+
* outlines) lets `outer` keep shared/internal edges on the centreline so
|
|
98
|
+
* neighbouring rooms meet there instead of overlapping inside the wall.
|
|
99
|
+
* Returns the original outline if the offset degenerates (e.g. an inner inset
|
|
100
|
+
* of a room thinner than its walls). Exact for orthogonal rooms.
|
|
101
|
+
*/
|
|
102
|
+
export declare function offsetRoomFootprint(outline: Vec2[], segments: Segment[], wallThicknesses: ReadonlyArray<number | undefined>, mode?: BoundaryMode, otherRooms?: Vec2[][]): Vec2[];
|
|
71
103
|
//# sourceMappingURL=generate-spaces.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-spaces.d.ts","sourceRoot":"","sources":["../../src/in-store/generate-spaces.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"generate-spaces.d.ts","sourceRoot":"","sources":["../../src/in-store/generate-spaces.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,IAAI,EACV,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAmB,KAAK,gBAAgB,EAA2B,MAAM,YAAY,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;IAC1B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,YAAY,EAAE,QAAQ,EAAE,CAAC;IACzB,sEAAsE;IACtE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,oEAAoE;IACpE,cAAc,EAAE,WAAW,CAAC;IAC5B,4DAA4D;IAC5D,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClF,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,qBAA0B,EACnC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,oBAAoB,CA2GtB;AA2CD,0DAA0D;AAC1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAqBxD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,IAAI,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,eAAe,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,EAClD,IAAI,GAAE,YAAsB,EAC5B,UAAU,GAAE,IAAI,EAAE,EAAO,GACxB,IAAI,EAAE,CA4CR"}
|
|
@@ -5,6 +5,12 @@ import { resolveSpatialAnchor } from './resolve-anchor.js';
|
|
|
5
5
|
import { extractWallSegmentsForStorey, } from './extract-walls.js';
|
|
6
6
|
import { detectEnclosedAreasWithStats, } from './auto-space-detect.js';
|
|
7
7
|
import { addSpaceToStore } from './space.js';
|
|
8
|
+
/**
|
|
9
|
+
* IfcSpace.ObjectType marker stamped on every derived space, so a re-run can
|
|
10
|
+
* recognise its own output and skip it instead of duplicating (idempotency),
|
|
11
|
+
* and so generated spaces are filterable downstream.
|
|
12
|
+
*/
|
|
13
|
+
export const GENERATED_SPACE_OBJECTTYPE = 'IfcLite:GeneratedSpace';
|
|
8
14
|
export function generateSpacesFromWalls(editor, store, storeyExpressId, options = {}, overlay) {
|
|
9
15
|
const height = options.height ?? 3;
|
|
10
16
|
const namePattern = options.namePattern ?? 'Space {n}';
|
|
@@ -37,8 +43,26 @@ export function generateSpacesFromWalls(editor, store, storeyExpressId, options
|
|
|
37
43
|
console.info(`[auto-spaces] storey #${storeyExpressId}: ${detected.length} region(s) from ${extraction.contributingWallIds.length}/${extraction.considered} walls — ` +
|
|
38
44
|
`${detection.stats.vertices}v / ${detection.stats.segmentsAfterSplit}e / ${detection.stats.faces}f ` +
|
|
39
45
|
`(dropped ${detection.stats.outerFacesDropped} outer + ${detection.stats.belowMinAreaDropped} small) [${unitNote}].`);
|
|
46
|
+
// Per-space dedup: drop detected rooms whose centroid lands inside an
|
|
47
|
+
// existing space footprint, so we don't duplicate already-present spaces
|
|
48
|
+
// (non-overlapping rooms on the same storey are still emitted).
|
|
49
|
+
const skipFootprints = options.skipFootprints ?? [];
|
|
50
|
+
const overlapsExisting = (outline) => {
|
|
51
|
+
if (skipFootprints.length === 0)
|
|
52
|
+
return false;
|
|
53
|
+
let cx = 0, cy = 0;
|
|
54
|
+
for (const p of outline) {
|
|
55
|
+
cx += p[0];
|
|
56
|
+
cy += p[1];
|
|
57
|
+
}
|
|
58
|
+
cx /= outline.length;
|
|
59
|
+
cy /= outline.length;
|
|
60
|
+
return skipFootprints.some((fp) => pointInPolygon(cx, cy, fp));
|
|
61
|
+
};
|
|
62
|
+
const rooms = detected.filter((r) => !overlapsExisting(r.outline));
|
|
63
|
+
const skippedExisting = detected.length - rooms.length;
|
|
40
64
|
const emitted = [];
|
|
41
|
-
if (options.dryRun ||
|
|
65
|
+
if (options.dryRun || rooms.length === 0) {
|
|
42
66
|
return {
|
|
43
67
|
wallsConsidered: extraction.considered,
|
|
44
68
|
wallsContributing: extraction.contributingWallIds.length,
|
|
@@ -46,21 +70,31 @@ export function generateSpacesFromWalls(editor, store, storeyExpressId, options
|
|
|
46
70
|
detected,
|
|
47
71
|
detectionStats: detection.stats,
|
|
48
72
|
emitted,
|
|
73
|
+
skippedExisting,
|
|
49
74
|
};
|
|
50
75
|
}
|
|
51
76
|
const anchor = resolveSpatialAnchor(store, storeyExpressId);
|
|
52
77
|
if (!anchor) {
|
|
53
78
|
throw new Error(`generateSpacesFromWalls: no resolvable spatial anchor for storey #${storeyExpressId}`);
|
|
54
79
|
}
|
|
55
|
-
|
|
80
|
+
const allOutlines = rooms.map((r) => r.outline);
|
|
81
|
+
rooms.forEach((region, i) => {
|
|
56
82
|
const name = namePattern.replace('{n}', String(i + 1));
|
|
83
|
+
const others = allOutlines.filter((_, j) => j !== i);
|
|
84
|
+
// Bake the solid at the inner (net) face — IfcSpace should stop at the room
|
|
85
|
+
// side of the walls, not run to their centreline. GrossFloorArea keeps the
|
|
86
|
+
// centreline measure; NetFloorArea falls out of the inset OuterCurve.
|
|
87
|
+
const netOutline = offsetRoomFootprint(region.outline, extraction.segments, extraction.wallThicknesses, options.boundaryMode ?? 'inner', others);
|
|
57
88
|
const result = addSpaceToStore(editor, anchor, {
|
|
58
89
|
Profile: 'polygon',
|
|
59
|
-
OuterCurve:
|
|
90
|
+
OuterCurve: netOutline,
|
|
60
91
|
Height: height,
|
|
61
92
|
Name: name,
|
|
93
|
+
ObjectType: GENERATED_SPACE_OBJECTTYPE,
|
|
62
94
|
LongName: options.longName,
|
|
63
95
|
PredefinedType: options.predefinedType,
|
|
96
|
+
boundaries: buildSpaceBoundaries(region.outline, extraction.segments, extraction.contributingWallIds, others),
|
|
97
|
+
grossFloorArea: region.area,
|
|
64
98
|
});
|
|
65
99
|
emitted.push({ region, result, name });
|
|
66
100
|
});
|
|
@@ -71,6 +105,227 @@ export function generateSpacesFromWalls(editor, store, storeyExpressId, options
|
|
|
71
105
|
detected,
|
|
72
106
|
detectionStats: detection.stats,
|
|
73
107
|
emitted,
|
|
108
|
+
skippedExisting,
|
|
74
109
|
};
|
|
75
110
|
}
|
|
111
|
+
/** Absolute polygon area (shoelace), m². */
|
|
112
|
+
function polygonArea(pts) {
|
|
113
|
+
let acc = 0;
|
|
114
|
+
for (let i = 0; i < pts.length; i++) {
|
|
115
|
+
const p = pts[i];
|
|
116
|
+
const q = pts[(i + 1) % pts.length];
|
|
117
|
+
acc += p[0] * q[1] - q[0] * p[1];
|
|
118
|
+
}
|
|
119
|
+
return Math.abs(acc) / 2;
|
|
120
|
+
}
|
|
121
|
+
/** Intersection of two lines given as point + unit direction; null if parallel. */
|
|
122
|
+
function lineIntersect(p0, d0, p1, d1) {
|
|
123
|
+
const denom = d0[0] * d1[1] - d0[1] * d1[0];
|
|
124
|
+
if (Math.abs(denom) < 1e-9)
|
|
125
|
+
return null;
|
|
126
|
+
const t = ((p1[0] - p0[0]) * d1[1] - (p1[1] - p0[1]) * d1[0]) / denom;
|
|
127
|
+
return [p0[0] + d0[0] * t, p0[1] + d0[1] * t];
|
|
128
|
+
}
|
|
129
|
+
/** Does outline edge a→b run along wall segment `seg` (parallel, on its
|
|
130
|
+
* centreline, overlapping extent)? */
|
|
131
|
+
function edgeRunsAlong(a, b, seg) {
|
|
132
|
+
const PERP_TOL = 0.2, PARALLEL_TOL = 0.03, OVERLAP_MARGIN = 0.3;
|
|
133
|
+
let ex = b[0] - a[0], ey = b[1] - a[1];
|
|
134
|
+
const el = Math.hypot(ex, ey);
|
|
135
|
+
if (el < 1e-6)
|
|
136
|
+
return false;
|
|
137
|
+
ex /= el;
|
|
138
|
+
ey /= el;
|
|
139
|
+
let sx = seg.b[0] - seg.a[0], sy = seg.b[1] - seg.a[1];
|
|
140
|
+
const sl = Math.hypot(sx, sy);
|
|
141
|
+
if (sl < 1e-6)
|
|
142
|
+
return false;
|
|
143
|
+
sx /= sl;
|
|
144
|
+
sy /= sl;
|
|
145
|
+
if (Math.abs(ex * sy - ey * sx) > PARALLEL_TOL)
|
|
146
|
+
return false;
|
|
147
|
+
const mx = (a[0] + b[0]) / 2, my = (a[1] + b[1]) / 2;
|
|
148
|
+
const t = (mx - seg.a[0]) * sx + (my - seg.a[1]) * sy;
|
|
149
|
+
const px = seg.a[0] + sx * t, py = seg.a[1] + sy * t;
|
|
150
|
+
if (Math.hypot(mx - px, my - py) > PERP_TOL)
|
|
151
|
+
return false;
|
|
152
|
+
return t >= -OVERLAP_MARGIN && t <= sl + OVERLAP_MARGIN;
|
|
153
|
+
}
|
|
154
|
+
/** Drop vertices whose two adjacent edges are collinear (e.g. a T-junction
|
|
155
|
+
* point left on a straight wall run). Such a vertex makes its two adjacent
|
|
156
|
+
* offset lines parallel, so they don't intersect — the offset then falls back
|
|
157
|
+
* to the un-offset centreline point and the corner skews. */
|
|
158
|
+
function simplifyCollinear(pts) {
|
|
159
|
+
const n = pts.length;
|
|
160
|
+
if (n < 4)
|
|
161
|
+
return pts;
|
|
162
|
+
const out = [];
|
|
163
|
+
for (let i = 0; i < n; i++) {
|
|
164
|
+
const p = pts[(i - 1 + n) % n], c = pts[i], q = pts[(i + 1) % n];
|
|
165
|
+
let ax = c[0] - p[0], ay = c[1] - p[1];
|
|
166
|
+
let bx = q[0] - c[0], by = q[1] - c[1];
|
|
167
|
+
const al = Math.hypot(ax, ay) || 1, bl = Math.hypot(bx, by) || 1;
|
|
168
|
+
ax /= al;
|
|
169
|
+
ay /= al;
|
|
170
|
+
bx /= bl;
|
|
171
|
+
by /= bl;
|
|
172
|
+
if (Math.abs(ax * by - ay * bx) > 1e-4)
|
|
173
|
+
out.push(c); // keep real corners only
|
|
174
|
+
}
|
|
175
|
+
return out.length >= 3 ? out : pts;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Offset a (centreline) room outline to the chosen wall boundary: `center` =
|
|
179
|
+
* the centreline as-is; `inner` = each edge shifted toward the room by half the
|
|
180
|
+
* wall thickness (net / inner face); `outer` = shifted away by half (gross /
|
|
181
|
+
* outer face). Re-corners by intersecting adjacent offset edges. `segments[k]`
|
|
182
|
+
* has thickness `wallThicknesses[k]`. `otherRooms` (other rooms' centreline
|
|
183
|
+
* outlines) lets `outer` keep shared/internal edges on the centreline so
|
|
184
|
+
* neighbouring rooms meet there instead of overlapping inside the wall.
|
|
185
|
+
* Returns the original outline if the offset degenerates (e.g. an inner inset
|
|
186
|
+
* of a room thinner than its walls). Exact for orthogonal rooms.
|
|
187
|
+
*/
|
|
188
|
+
export function offsetRoomFootprint(outline, segments, wallThicknesses, mode = 'inner', otherRooms = []) {
|
|
189
|
+
if (mode === 'center')
|
|
190
|
+
return outline;
|
|
191
|
+
const simple = simplifyCollinear(outline);
|
|
192
|
+
const n = simple.length;
|
|
193
|
+
if (n < 3)
|
|
194
|
+
return outline;
|
|
195
|
+
const sign = mode === 'inner' ? 1 : -1; // inner → inward, outer → outward
|
|
196
|
+
const lines = [];
|
|
197
|
+
for (let i = 0; i < n; i++) {
|
|
198
|
+
const a = simple[i];
|
|
199
|
+
const b = simple[(i + 1) % n];
|
|
200
|
+
let dx = b[0] - a[0];
|
|
201
|
+
let dy = b[1] - a[1];
|
|
202
|
+
const l = Math.hypot(dx, dy);
|
|
203
|
+
if (l < 1e-6)
|
|
204
|
+
return outline;
|
|
205
|
+
dx /= l;
|
|
206
|
+
dy /= l;
|
|
207
|
+
let half = 0; // half the thickest wall this edge runs along
|
|
208
|
+
for (let k = 0; k < segments.length; k++) {
|
|
209
|
+
const t = wallThicknesses[k];
|
|
210
|
+
if (t !== undefined && t / 2 > half && edgeRunsAlong(a, b, segments[k]))
|
|
211
|
+
half = t / 2;
|
|
212
|
+
}
|
|
213
|
+
let off = sign * half;
|
|
214
|
+
// A shared (internal) edge has another room on its OUTWARD side. Pushing it
|
|
215
|
+
// outward (outer mode) would overlap that room, so pin shared edges to the
|
|
216
|
+
// centreline; only edges facing outside the building actually push out.
|
|
217
|
+
if (mode === 'outer' && half > 0 && otherRooms.length) {
|
|
218
|
+
const mx = (a[0] + b[0]) / 2 + dy * 0.1; // outward = right normal (dy, -dx)
|
|
219
|
+
const my = (a[1] + b[1]) / 2 - dx * 0.1;
|
|
220
|
+
if (otherRooms.some((poly) => pointInPolygon(mx, my, poly)))
|
|
221
|
+
off = 0;
|
|
222
|
+
}
|
|
223
|
+
// Inward normal of a CCW outline is to the left of a→b: (-dy, dx).
|
|
224
|
+
lines.push({ p: [a[0] - dy * off, a[1] + dx * off], d: [dx, dy] });
|
|
225
|
+
}
|
|
226
|
+
const verts = [];
|
|
227
|
+
for (let i = 0; i < n; i++) {
|
|
228
|
+
const prev = lines[(i - 1 + n) % n];
|
|
229
|
+
const cur = lines[i];
|
|
230
|
+
verts.push(lineIntersect(prev.p, prev.d, cur.p, cur.d) ?? simple[i]);
|
|
231
|
+
}
|
|
232
|
+
if (!verts.every((v) => Number.isFinite(v[0]) && Number.isFinite(v[1])))
|
|
233
|
+
return outline;
|
|
234
|
+
const gross = polygonArea(simple);
|
|
235
|
+
const got = polygonArea(verts);
|
|
236
|
+
if (got <= 1e-6)
|
|
237
|
+
return outline;
|
|
238
|
+
if (mode === 'inner' && got > gross + 1e-6)
|
|
239
|
+
return outline; // inset inverted
|
|
240
|
+
return verts;
|
|
241
|
+
}
|
|
242
|
+
/** Ray-cast point-in-polygon test. */
|
|
243
|
+
function pointInPolygon(x, y, poly) {
|
|
244
|
+
let inside = false;
|
|
245
|
+
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
246
|
+
const xi = poly[i][0], yi = poly[i][1];
|
|
247
|
+
const xj = poly[j][0], yj = poly[j][1];
|
|
248
|
+
if ((yi > y) !== (yj > y) && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi)
|
|
249
|
+
inside = !inside;
|
|
250
|
+
}
|
|
251
|
+
return inside;
|
|
252
|
+
}
|
|
253
|
+
/** Wall ids whose centreline an outline edge runs along (parallel, on the
|
|
254
|
+
* line, overlapping extent). `segments[k]` was extracted from `wallIds[k]`. */
|
|
255
|
+
function matchEdgeWalls(a, b, segments, wallIds) {
|
|
256
|
+
const PERP_TOL = 0.2; // m — edge sits on the wall centreline
|
|
257
|
+
const PARALLEL_TOL = 0.03;
|
|
258
|
+
const OVERLAP_MARGIN = 0.3; // m
|
|
259
|
+
const out = [];
|
|
260
|
+
const mx = (a[0] + b[0]) / 2;
|
|
261
|
+
const my = (a[1] + b[1]) / 2;
|
|
262
|
+
let ex = b[0] - a[0];
|
|
263
|
+
let ey = b[1] - a[1];
|
|
264
|
+
const el = Math.hypot(ex, ey);
|
|
265
|
+
if (el < 1e-6)
|
|
266
|
+
return out;
|
|
267
|
+
ex /= el;
|
|
268
|
+
ey /= el;
|
|
269
|
+
for (let k = 0; k < segments.length; k++) {
|
|
270
|
+
const sa = segments[k].a;
|
|
271
|
+
const sb = segments[k].b;
|
|
272
|
+
let sx = sb[0] - sa[0];
|
|
273
|
+
let sy = sb[1] - sa[1];
|
|
274
|
+
const sl = Math.hypot(sx, sy);
|
|
275
|
+
if (sl < 1e-6)
|
|
276
|
+
continue;
|
|
277
|
+
sx /= sl;
|
|
278
|
+
sy /= sl;
|
|
279
|
+
if (Math.abs(ex * sy - ey * sx) > PARALLEL_TOL)
|
|
280
|
+
continue; // not parallel
|
|
281
|
+
const t = (mx - sa[0]) * sx + (my - sa[1]) * sy; // projection onto wall (m)
|
|
282
|
+
const px = sa[0] + sx * t;
|
|
283
|
+
const py = sa[1] + sy * t;
|
|
284
|
+
if (Math.hypot(mx - px, my - py) > PERP_TOL)
|
|
285
|
+
continue; // edge off the wall line
|
|
286
|
+
if (t < -OVERLAP_MARGIN || t > sl + OVERLAP_MARGIN)
|
|
287
|
+
continue; // no extent overlap
|
|
288
|
+
out.push(wallIds[k]);
|
|
289
|
+
}
|
|
290
|
+
return out;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Build the IfcRelSpaceBoundary inputs for one room: map each outline edge to
|
|
294
|
+
* the wall it runs along, classifying the boundary INTERNAL when another room
|
|
295
|
+
* lies on the far side of that edge (a partition) or EXTERNAL when it's the
|
|
296
|
+
* building perimeter. "Far side" is the edge midpoint nudged along its outward
|
|
297
|
+
* normal — robust to neighbours that split the shared run differently than this
|
|
298
|
+
* room does (where exact edge-matching would miss). A wall stays INTERNAL if
|
|
299
|
+
* any of its edges has a room on the far side. One boundary per distinct wall.
|
|
300
|
+
*/
|
|
301
|
+
function buildSpaceBoundaries(outline, segments, wallIds, otherRooms) {
|
|
302
|
+
const NUDGE = 0.1; // m past the shared centreline into the neighbour
|
|
303
|
+
const byWall = new Map();
|
|
304
|
+
const n = outline.length;
|
|
305
|
+
for (let i = 0; i < n; i++) {
|
|
306
|
+
const a = outline[i];
|
|
307
|
+
const b = outline[(i + 1) % n];
|
|
308
|
+
let dx = b[0] - a[0];
|
|
309
|
+
let dy = b[1] - a[1];
|
|
310
|
+
const dl = Math.hypot(dx, dy);
|
|
311
|
+
if (dl < 1e-6)
|
|
312
|
+
continue;
|
|
313
|
+
dx /= dl;
|
|
314
|
+
dy /= dl;
|
|
315
|
+
// Outward normal of a CCW outline is to the right of a→b.
|
|
316
|
+
const mx = (a[0] + b[0]) / 2 + dy * NUDGE;
|
|
317
|
+
const my = (a[1] + b[1]) / 2 - dx * NUDGE;
|
|
318
|
+
const cls = otherRooms.some((poly) => pointInPolygon(mx, my, poly)) ? 'INTERNAL' : 'EXTERNAL';
|
|
319
|
+
for (const wallId of matchEdgeWalls(a, b, segments, wallIds)) {
|
|
320
|
+
if (byWall.get(wallId) === 'INTERNAL')
|
|
321
|
+
continue; // once internal, stays internal
|
|
322
|
+
byWall.set(wallId, cls);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return [...byWall].map(([elementId, internalOrExternal]) => ({
|
|
326
|
+
elementId,
|
|
327
|
+
internalOrExternal,
|
|
328
|
+
physicalOrVirtual: 'PHYSICAL',
|
|
329
|
+
}));
|
|
330
|
+
}
|
|
76
331
|
//# sourceMappingURL=generate-spaces.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-spaces.js","sourceRoot":"","sources":["../../src/in-store/generate-spaces.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generate-spaces.js","sourceRoot":"","sources":["../../src/in-store/generate-spaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* default — IfcBeam carries `.BEAM.`.
|
|
8
8
|
*/
|
|
9
9
|
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
10
|
-
import type
|
|
10
|
+
import { type SpatialAnchor } from './anchor.js';
|
|
11
11
|
export interface MemberInStoreParams {
|
|
12
12
|
Start: [number, number, number];
|
|
13
13
|
End: [number, number, number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../../src/in-store/member.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../../src/in-store/member.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,EAAkC,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjF,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EACX,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAC7D,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAC5D,aAAa,GAAG,YAAY,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAOD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,mBAAmB,GAC1B,iBAAiB,CAoCnB"}
|
package/dist/in-store/member.js
CHANGED
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { vecCross, vecNorm } from '../ifc-creator-math.js';
|
|
5
|
+
import { toNativeLength, toNativePoint3 } from './anchor.js';
|
|
5
6
|
import { emitBodyRepresentation, emitExtrudedSolid, emitLocalPlacement, emitRectangleProfile, emitRelContainedInSpatialStructure, ifcElementHeader, } from './_emit-helpers.js';
|
|
6
7
|
function computeRefDirection(axis) {
|
|
7
8
|
const up = Math.abs(axis[2]) < 0.9 ? [0, 0, 1] : [1, 0, 0];
|
|
8
9
|
return vecNorm(vecCross(up, axis));
|
|
9
10
|
}
|
|
10
11
|
export function addMemberToStore(editor, anchor, params) {
|
|
12
|
+
// Params are metres; convert dimensioned fields to the file's native
|
|
13
|
+
// length unit before emit (see SpatialAnchor.lengthUnitScale).
|
|
14
|
+
params = {
|
|
15
|
+
...params,
|
|
16
|
+
Start: toNativePoint3(anchor, params.Start),
|
|
17
|
+
End: toNativePoint3(anchor, params.End),
|
|
18
|
+
Width: toNativeLength(anchor, params.Width),
|
|
19
|
+
Height: toNativeLength(anchor, params.Height),
|
|
20
|
+
};
|
|
11
21
|
const dx = params.End[0] - params.Start[0];
|
|
12
22
|
const dy = params.End[1] - params.Start[1];
|
|
13
23
|
const dz = params.End[2] - params.Start[2];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member.js","sourceRoot":"","sources":["../../src/in-store/member.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAY/D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"member.js","sourceRoot":"","sources":["../../src/in-store/member.ts"],"names":[],"mappings":"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"}
|
package/dist/in-store/plate.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* default (callers can override).
|
|
6
6
|
*/
|
|
7
7
|
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
8
|
-
import type
|
|
8
|
+
import { type SpatialAnchor } from './anchor.js';
|
|
9
9
|
export type PlateInStoreParams = PlateRectangleParams | PlatePolygonParams;
|
|
10
10
|
export interface PlateRectangleParams {
|
|
11
11
|
Position: [number, number, number];
|