@ifc-lite/create 4.0.0 → 5.1.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/README.md +34 -0
- package/dist/in-store/align-boxes.d.ts +38 -0
- package/dist/in-store/align-boxes.d.ts.map +1 -0
- package/dist/in-store/align-boxes.js +97 -0
- package/dist/in-store/align-boxes.js.map +1 -0
- package/dist/in-store/anchor.d.ts.map +1 -1
- package/dist/in-store/anchor.js +13 -2
- package/dist/in-store/anchor.js.map +1 -1
- package/dist/in-store/beam.d.ts.map +1 -1
- package/dist/in-store/beam.js +3 -10
- package/dist/in-store/beam.js.map +1 -1
- package/dist/in-store/copy-array.d.ts +17 -0
- package/dist/in-store/copy-array.d.ts.map +1 -0
- package/dist/in-store/copy-array.js +47 -0
- package/dist/in-store/copy-array.js.map +1 -0
- package/dist/in-store/copy-batch.d.ts +27 -0
- package/dist/in-store/copy-batch.d.ts.map +1 -0
- package/dist/in-store/copy-batch.js +101 -0
- package/dist/in-store/copy-batch.js.map +1 -0
- package/dist/in-store/copy-dependent-walk.d.ts +27 -0
- package/dist/in-store/copy-dependent-walk.d.ts.map +1 -0
- package/dist/in-store/copy-dependent-walk.js +61 -0
- package/dist/in-store/copy-dependent-walk.js.map +1 -0
- package/dist/in-store/copy-frame.d.ts +4 -3
- package/dist/in-store/copy-frame.d.ts.map +1 -1
- package/dist/in-store/copy-frame.js +14 -1
- package/dist/in-store/copy-frame.js.map +1 -1
- package/dist/in-store/copy-product.d.ts +0 -20
- package/dist/in-store/copy-product.d.ts.map +1 -1
- package/dist/in-store/copy-product.js +35 -35
- package/dist/in-store/copy-product.js.map +1 -1
- package/dist/in-store/edit/effective-mutation-view.d.ts +6 -0
- package/dist/in-store/edit/effective-mutation-view.d.ts.map +1 -0
- package/dist/in-store/edit/effective-mutation-view.js +45 -0
- package/dist/in-store/edit/effective-mutation-view.js.map +1 -0
- package/dist/in-store/edit/effective-storey.d.ts +13 -0
- package/dist/in-store/edit/effective-storey.d.ts.map +1 -0
- package/dist/in-store/edit/effective-storey.js +36 -0
- package/dist/in-store/edit/effective-storey.js.map +1 -0
- package/dist/in-store/edit/effective-storeys.d.ts +9 -0
- package/dist/in-store/edit/effective-storeys.d.ts.map +1 -0
- package/dist/in-store/edit/effective-storeys.js +16 -0
- package/dist/in-store/edit/effective-storeys.js.map +1 -0
- package/dist/in-store/edit/hosted-opening-refit.d.ts +29 -0
- package/dist/in-store/edit/hosted-opening-refit.d.ts.map +1 -0
- package/dist/in-store/edit/hosted-opening-refit.js +168 -0
- package/dist/in-store/edit/hosted-opening-refit.js.map +1 -0
- package/dist/in-store/edit/length-unit-scale.d.ts +24 -0
- package/dist/in-store/edit/length-unit-scale.d.ts.map +1 -0
- package/dist/in-store/edit/length-unit-scale.js +37 -0
- package/dist/in-store/edit/length-unit-scale.js.map +1 -0
- package/dist/in-store/edit/linear-element-edit.d.ts +131 -0
- package/dist/in-store/edit/linear-element-edit.d.ts.map +1 -0
- package/dist/in-store/edit/linear-element-edit.js +259 -0
- package/dist/in-store/edit/linear-element-edit.js.map +1 -0
- package/dist/in-store/edit/metadata-clone-effective.d.ts +5 -0
- package/dist/in-store/edit/metadata-clone-effective.d.ts.map +1 -0
- package/dist/in-store/edit/metadata-clone-effective.js +47 -0
- package/dist/in-store/edit/metadata-clone-effective.js.map +1 -0
- package/dist/in-store/edit/metadata-clone.d.ts +40 -0
- package/dist/in-store/edit/metadata-clone.d.ts.map +1 -0
- package/dist/in-store/edit/metadata-clone.js +107 -0
- package/dist/in-store/edit/metadata-clone.js.map +1 -0
- package/dist/in-store/edit/placement-core.d.ts +140 -0
- package/dist/in-store/edit/placement-core.d.ts.map +1 -0
- package/dist/in-store/edit/placement-core.js +317 -0
- package/dist/in-store/edit/placement-core.js.map +1 -0
- package/dist/in-store/edit/polygon-clip.d.ts +58 -0
- package/dist/in-store/edit/polygon-clip.d.ts.map +1 -0
- package/dist/in-store/edit/polygon-clip.js +153 -0
- package/dist/in-store/edit/polygon-clip.js.map +1 -0
- package/dist/in-store/edit/read-profile.d.ts +6 -0
- package/dist/in-store/edit/read-profile.d.ts.map +1 -0
- package/dist/in-store/edit/read-profile.js +95 -0
- package/dist/in-store/edit/read-profile.js.map +1 -0
- package/dist/in-store/edit/slab-edit-frame.d.ts +40 -0
- package/dist/in-store/edit/slab-edit-frame.d.ts.map +1 -0
- package/dist/in-store/edit/slab-edit-frame.js +146 -0
- package/dist/in-store/edit/slab-edit-frame.js.map +1 -0
- package/dist/in-store/edit/slab-edit.d.ts +112 -0
- package/dist/in-store/edit/slab-edit.d.ts.map +1 -0
- package/dist/in-store/edit/slab-edit.js +275 -0
- package/dist/in-store/edit/slab-edit.js.map +1 -0
- package/dist/in-store/edit/slab-opening-carry.d.ts +10 -0
- package/dist/in-store/edit/slab-opening-carry.d.ts.map +1 -0
- package/dist/in-store/edit/slab-opening-carry.js +65 -0
- package/dist/in-store/edit/slab-opening-carry.js.map +1 -0
- package/dist/in-store/edit/split-guid.d.ts +29 -0
- package/dist/in-store/edit/split-guid.d.ts.map +1 -0
- package/dist/in-store/edit/split-guid.js +64 -0
- package/dist/in-store/edit/split-guid.js.map +1 -0
- package/dist/in-store/edit/split-target.d.ts +90 -0
- package/dist/in-store/edit/split-target.d.ts.map +1 -0
- package/dist/in-store/edit/split-target.js +116 -0
- package/dist/in-store/edit/split-target.js.map +1 -0
- package/dist/in-store/edit/target.d.ts +8 -0
- package/dist/in-store/edit/target.d.ts.map +1 -0
- package/dist/in-store/edit/target.js +5 -0
- package/dist/in-store/edit/target.js.map +1 -0
- package/dist/in-store/edit/trim-extend-geometry.d.ts +99 -0
- package/dist/in-store/edit/trim-extend-geometry.d.ts.map +1 -0
- package/dist/in-store/edit/trim-extend-geometry.js +105 -0
- package/dist/in-store/edit/trim-extend-geometry.js.map +1 -0
- package/dist/in-store/edit/wall-axis-edit.d.ts +16 -0
- package/dist/in-store/edit/wall-axis-edit.d.ts.map +1 -0
- package/dist/in-store/edit/wall-axis-edit.js +40 -0
- package/dist/in-store/edit/wall-axis-edit.js.map +1 -0
- package/dist/in-store/edit/wall-edit.d.ts +157 -0
- package/dist/in-store/edit/wall-edit.d.ts.map +1 -0
- package/dist/in-store/edit/wall-edit.js +276 -0
- package/dist/in-store/edit/wall-edit.js.map +1 -0
- package/dist/in-store/edit/wall-hosted-cuts.d.ts +35 -0
- package/dist/in-store/edit/wall-hosted-cuts.d.ts.map +1 -0
- package/dist/in-store/edit/wall-hosted-cuts.js +27 -0
- package/dist/in-store/edit/wall-hosted-cuts.js.map +1 -0
- package/dist/in-store/edit/wall-opening-reassign.d.ts +18 -0
- package/dist/in-store/edit/wall-opening-reassign.d.ts.map +1 -0
- package/dist/in-store/edit/wall-opening-reassign.js +50 -0
- package/dist/in-store/edit/wall-opening-reassign.js.map +1 -0
- package/dist/in-store/element-align.d.ts +13 -0
- package/dist/in-store/element-align.d.ts.map +1 -0
- package/dist/in-store/element-align.js +90 -0
- package/dist/in-store/element-align.js.map +1 -0
- package/dist/in-store/element-replacement.d.ts +26 -0
- package/dist/in-store/element-replacement.d.ts.map +1 -0
- package/dist/in-store/element-replacement.js +68 -0
- package/dist/in-store/element-replacement.js.map +1 -0
- package/dist/in-store/element-size-edit.d.ts +40 -0
- package/dist/in-store/element-size-edit.d.ts.map +1 -0
- package/dist/in-store/element-size-edit.js +103 -0
- package/dist/in-store/element-size-edit.js.map +1 -0
- package/dist/in-store/element-split-axis.d.ts +6 -0
- package/dist/in-store/element-split-axis.d.ts.map +1 -0
- package/dist/in-store/element-split-axis.js +87 -0
- package/dist/in-store/element-split-axis.js.map +1 -0
- package/dist/in-store/element-split-joined.d.ts +13 -0
- package/dist/in-store/element-split-joined.d.ts.map +1 -0
- package/dist/in-store/element-split-joined.js +74 -0
- package/dist/in-store/element-split-joined.js.map +1 -0
- package/dist/in-store/element-split-placement.d.ts +19 -0
- package/dist/in-store/element-split-placement.d.ts.map +1 -0
- package/dist/in-store/element-split-placement.js +48 -0
- package/dist/in-store/element-split-placement.js.map +1 -0
- package/dist/in-store/element-split-slab.d.ts +19 -0
- package/dist/in-store/element-split-slab.d.ts.map +1 -0
- package/dist/in-store/element-split-slab.js +86 -0
- package/dist/in-store/element-split-slab.js.map +1 -0
- package/dist/in-store/element-split.d.ts +49 -0
- package/dist/in-store/element-split.d.ts.map +1 -0
- package/dist/in-store/element-split.js +52 -0
- package/dist/in-store/element-split.js.map +1 -0
- package/dist/in-store/element-transform-edit.d.ts +33 -0
- package/dist/in-store/element-transform-edit.d.ts.map +1 -0
- package/dist/in-store/element-transform-edit.js +97 -0
- package/dist/in-store/element-transform-edit.js.map +1 -0
- package/dist/in-store/element-transform-frames.d.ts +58 -0
- package/dist/in-store/element-transform-frames.d.ts.map +1 -0
- package/dist/in-store/element-transform-frames.js +110 -0
- package/dist/in-store/element-transform-frames.js.map +1 -0
- package/dist/in-store/element-transform-joins.d.ts +4 -0
- package/dist/in-store/element-transform-joins.d.ts.map +1 -0
- package/dist/in-store/element-transform-joins.js +62 -0
- package/dist/in-store/element-transform-joins.js.map +1 -0
- package/dist/in-store/element-transform-plan.d.ts +38 -0
- package/dist/in-store/element-transform-plan.d.ts.map +1 -0
- package/dist/in-store/element-transform-plan.js +115 -0
- package/dist/in-store/element-transform-plan.js.map +1 -0
- package/dist/in-store/element-trim-extend.d.ts +25 -0
- package/dist/in-store/element-trim-extend.d.ts.map +1 -0
- package/dist/in-store/element-trim-extend.js +97 -0
- package/dist/in-store/element-trim-extend.js.map +1 -0
- package/dist/in-store/extract-grids.d.ts +7 -17
- package/dist/in-store/extract-grids.d.ts.map +1 -1
- package/dist/in-store/extract-grids.js +11 -2
- package/dist/in-store/extract-grids.js.map +1 -1
- package/dist/in-store/grid-column.d.ts +23 -0
- package/dist/in-store/grid-column.d.ts.map +1 -0
- package/dist/in-store/grid-column.js +73 -0
- package/dist/in-store/grid-column.js.map +1 -0
- package/dist/in-store/grid-intersection-read.d.ts +10 -0
- package/dist/in-store/grid-intersection-read.d.ts.map +1 -0
- package/dist/in-store/grid-intersection-read.js +45 -0
- package/dist/in-store/grid-intersection-read.js.map +1 -0
- package/dist/in-store/grid.d.ts +7 -1
- package/dist/in-store/grid.d.ts.map +1 -1
- package/dist/in-store/grid.js +12 -2
- package/dist/in-store/grid.js.map +1 -1
- package/dist/in-store/group-evidence.d.ts +49 -0
- package/dist/in-store/group-evidence.d.ts.map +1 -0
- package/dist/in-store/group-evidence.js +111 -0
- package/dist/in-store/group-evidence.js.map +1 -0
- package/dist/in-store/group-graph.d.ts +51 -0
- package/dist/in-store/group-graph.d.ts.map +1 -0
- package/dist/in-store/group-graph.js +213 -0
- package/dist/in-store/group-graph.js.map +1 -0
- package/dist/in-store/group.d.ts +34 -0
- package/dist/in-store/group.d.ts.map +1 -0
- package/dist/in-store/group.js +181 -0
- package/dist/in-store/group.js.map +1 -0
- package/dist/in-store/host-geometry-frame.d.ts +5 -1
- package/dist/in-store/host-geometry-frame.d.ts.map +1 -1
- package/dist/in-store/host-geometry-frame.js +46 -2
- package/dist/in-store/host-geometry-frame.js.map +1 -1
- package/dist/in-store/index.d.ts +7 -0
- package/dist/in-store/index.d.ts.map +1 -1
- package/dist/in-store/index.js +7 -0
- package/dist/in-store/index.js.map +1 -1
- package/dist/in-store/linear-profile-frame.d.ts +10 -0
- package/dist/in-store/linear-profile-frame.d.ts.map +1 -0
- package/dist/in-store/linear-profile-frame.js +17 -0
- package/dist/in-store/linear-profile-frame.js.map +1 -0
- package/dist/in-store/material.d.ts.map +1 -1
- package/dist/in-store/material.js +17 -6
- package/dist/in-store/material.js.map +1 -1
- package/dist/in-store/member.d.ts.map +1 -1
- package/dist/in-store/member.js +3 -7
- package/dist/in-store/member.js.map +1 -1
- package/dist/in-store/ordinary-element.d.ts +47 -0
- package/dist/in-store/ordinary-element.d.ts.map +1 -0
- package/dist/in-store/ordinary-element.js +38 -0
- package/dist/in-store/ordinary-element.js.map +1 -0
- package/dist/in-store/placement-frame.d.ts +6 -1
- package/dist/in-store/placement-frame.d.ts.map +1 -1
- package/dist/in-store/placement-frame.js +5 -1
- package/dist/in-store/placement-frame.js.map +1 -1
- package/dist/in-store/resolve-anchor.d.ts +3 -2
- package/dist/in-store/resolve-anchor.d.ts.map +1 -1
- package/dist/in-store/resolve-anchor.js +7 -5
- package/dist/in-store/resolve-anchor.js.map +1 -1
- package/dist/in-store/resolve-relations.d.ts +3 -1
- package/dist/in-store/resolve-relations.d.ts.map +1 -1
- package/dist/in-store/resolve-relations.js +8 -3
- package/dist/in-store/resolve-relations.js.map +1 -1
- package/dist/in-store/room-candidates.d.ts +58 -0
- package/dist/in-store/room-candidates.d.ts.map +1 -0
- package/dist/in-store/room-candidates.js +135 -0
- package/dist/in-store/room-candidates.js.map +1 -0
- package/dist/in-store/room-creation-plan.d.ts +16 -0
- package/dist/in-store/room-creation-plan.d.ts.map +1 -0
- package/dist/in-store/room-creation-plan.js +28 -0
- package/dist/in-store/room-creation-plan.js.map +1 -0
- package/dist/in-store/room-floor-height.d.ts +24 -0
- package/dist/in-store/room-floor-height.d.ts.map +1 -0
- package/dist/in-store/room-floor-height.js +32 -0
- package/dist/in-store/room-floor-height.js.map +1 -0
- package/dist/in-store/room-footprint-native.d.ts +19 -0
- package/dist/in-store/room-footprint-native.d.ts.map +1 -0
- package/dist/in-store/room-footprint-native.js +117 -0
- package/dist/in-store/room-footprint-native.js.map +1 -0
- package/dist/in-store/room-layout-cache.d.ts +23 -0
- package/dist/in-store/room-layout-cache.d.ts.map +1 -0
- package/dist/in-store/room-layout-cache.js +84 -0
- package/dist/in-store/room-layout-cache.js.map +1 -0
- package/dist/in-store/room-layout-core.d.ts +68 -0
- package/dist/in-store/room-layout-core.d.ts.map +1 -0
- package/dist/in-store/room-layout-core.js +153 -0
- package/dist/in-store/room-layout-core.js.map +1 -0
- package/dist/in-store/room-population.d.ts +5 -0
- package/dist/in-store/room-population.d.ts.map +1 -0
- package/dist/in-store/room-population.js +28 -0
- package/dist/in-store/room-population.js.map +1 -0
- package/dist/in-store/room-space-meshes.d.ts +15 -0
- package/dist/in-store/room-space-meshes.d.ts.map +1 -0
- package/dist/in-store/room-space-meshes.js +38 -0
- package/dist/in-store/room-space-meshes.js.map +1 -0
- package/dist/in-store/room-store.d.ts +55 -0
- package/dist/in-store/room-store.d.ts.map +1 -0
- package/dist/in-store/room-store.js +173 -0
- package/dist/in-store/room-store.js.map +1 -0
- package/dist/in-store/room-storey-elevation.d.ts +5 -0
- package/dist/in-store/room-storey-elevation.d.ts.map +1 -0
- package/dist/in-store/room-storey-elevation.js +42 -0
- package/dist/in-store/room-storey-elevation.js.map +1 -0
- package/dist/in-store/room-storey-frame.d.ts +47 -0
- package/dist/in-store/room-storey-frame.d.ts.map +1 -0
- package/dist/in-store/room-storey-frame.js +48 -0
- package/dist/in-store/room-storey-frame.js.map +1 -0
- package/dist/in-store/room-wall-rects.d.ts +117 -0
- package/dist/in-store/room-wall-rects.d.ts.map +1 -0
- package/dist/in-store/room-wall-rects.js +157 -0
- package/dist/in-store/room-wall-rects.js.map +1 -0
- package/dist/in-store/schema-attributes.d.ts +3 -3
- package/dist/in-store/schema-attributes.d.ts.map +1 -1
- package/dist/in-store/schema-attributes.js +9 -7
- package/dist/in-store/schema-attributes.js.map +1 -1
- package/dist/in-store/slab.d.ts.map +1 -1
- package/dist/in-store/slab.js +1 -4
- package/dist/in-store/slab.js.map +1 -1
- package/dist/in-store/stair-removal.d.ts +17 -0
- package/dist/in-store/stair-removal.d.ts.map +1 -0
- package/dist/in-store/stair-removal.js +134 -0
- package/dist/in-store/stair-removal.js.map +1 -0
- package/dist/in-store/storey-plan-frame.d.ts +2 -1
- package/dist/in-store/storey-plan-frame.d.ts.map +1 -1
- package/dist/in-store/storey-plan-frame.js +20 -11
- package/dist/in-store/storey-plan-frame.js.map +1 -1
- package/dist/in-store/storey-reassignment-plan.d.ts +53 -0
- package/dist/in-store/storey-reassignment-plan.d.ts.map +1 -0
- package/dist/in-store/storey-reassignment-plan.js +237 -0
- package/dist/in-store/storey-reassignment-plan.js.map +1 -0
- package/dist/in-store/storey-reassignment.d.ts +8 -0
- package/dist/in-store/storey-reassignment.d.ts.map +1 -0
- package/dist/in-store/storey-reassignment.js +52 -0
- package/dist/in-store/storey-reassignment.js.map +1 -0
- package/dist/in-store/trim-extend-plan.d.ts +27 -0
- package/dist/in-store/trim-extend-plan.d.ts.map +1 -0
- package/dist/in-store/trim-extend-plan.js +49 -0
- package/dist/in-store/trim-extend-plan.js.map +1 -0
- package/dist/in-store/wall-join-edit.d.ts +0 -17
- package/dist/in-store/wall-join-edit.d.ts.map +1 -1
- package/dist/in-store/wall-join-edit.js +41 -7
- package/dist/in-store/wall-join-edit.js.map +1 -1
- package/dist/in-store/wall-section-edit.d.ts +16 -0
- package/dist/in-store/wall-section-edit.d.ts.map +1 -0
- package/dist/in-store/wall-section-edit.js +75 -0
- package/dist/in-store/wall-section-edit.js.map +1 -0
- package/dist/in-store/wall-size-edit.d.ts +29 -0
- package/dist/in-store/wall-size-edit.d.ts.map +1 -0
- package/dist/in-store/wall-size-edit.js +65 -0
- package/dist/in-store/wall-size-edit.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1,275 @@
|
|
|
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 { asExpressIdRef, asCoordinateTriple, readAttributes, resolvePlacementChain, } from './placement-core.js';
|
|
5
|
+
import { clipPolygonByLine } from './polygon-clip.js';
|
|
6
|
+
import { polygonArea } from '../room-footprint-offset.js';
|
|
7
|
+
import { resolveSolidPositionXform, slabExtrusionFrame } from './slab-edit-frame.js';
|
|
8
|
+
const SLAB_LIKE_STEP_TYPES = {
|
|
9
|
+
IFCSLAB: 'IfcSlab',
|
|
10
|
+
IFCROOF: 'IfcRoof',
|
|
11
|
+
IFCPLATE: 'IfcPlate',
|
|
12
|
+
IFCSPACE: 'IfcSpace',
|
|
13
|
+
};
|
|
14
|
+
function stepTypeToSlabLike(stepType) {
|
|
15
|
+
return SLAB_LIKE_STEP_TYPES[stepType.toUpperCase()] ?? null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Derive a rectangle profile's outline from its centred placement.
|
|
19
|
+
* `IfcRectangleProfileDef` extends from `-XDim/2` to `+XDim/2`
|
|
20
|
+
* along the profile's local X (and same for YDim along local Y),
|
|
21
|
+
* centred at the IfcAxis2Placement2D's Location point.
|
|
22
|
+
*/
|
|
23
|
+
function rectangleFootprint(placementOrigin, profileOrigin2D, xdim, ydim, solidXform) {
|
|
24
|
+
// Rectangle corners in the profile coordinate system (centred on the
|
|
25
|
+
// profile origin), mapped through the solid Position into plan space,
|
|
26
|
+
// then offset by the slab's placement origin.
|
|
27
|
+
const [px, py] = placementOrigin;
|
|
28
|
+
const [cx, cy] = profileOrigin2D;
|
|
29
|
+
const corners = [
|
|
30
|
+
[cx - xdim / 2, cy - ydim / 2],
|
|
31
|
+
[cx + xdim / 2, cy - ydim / 2],
|
|
32
|
+
[cx + xdim / 2, cy + ydim / 2],
|
|
33
|
+
[cx - xdim / 2, cy + ydim / 2],
|
|
34
|
+
];
|
|
35
|
+
return corners.map((c) => {
|
|
36
|
+
const [wx, wy] = solidXform(c);
|
|
37
|
+
return [px + wx, py + wy];
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read an IfcPolyline's vertex list and return them as 2D storey-
|
|
42
|
+
* local points (adding the placement origin so the result is in
|
|
43
|
+
* the same frame as a rectangle footprint).
|
|
44
|
+
*/
|
|
45
|
+
function polylineFootprint(dataStore, view, editor, polylineId, placementOrigin, profileOrigin2D, solidXform) {
|
|
46
|
+
const attrs = readAttributes(dataStore, view, editor, polylineId);
|
|
47
|
+
if (!attrs)
|
|
48
|
+
return null;
|
|
49
|
+
// IfcPolyline.Points is a list of IfcCartesianPoint refs at attr 0.
|
|
50
|
+
const refList = attrs[0];
|
|
51
|
+
if (!Array.isArray(refList) || refList.length < 3)
|
|
52
|
+
return null;
|
|
53
|
+
const [px, py] = placementOrigin;
|
|
54
|
+
const [cx, cy] = profileOrigin2D;
|
|
55
|
+
const out = [];
|
|
56
|
+
for (const ref of refList) {
|
|
57
|
+
const ptId = asExpressIdRef(ref);
|
|
58
|
+
if (ptId === null)
|
|
59
|
+
return null;
|
|
60
|
+
const ptAttrs = readAttributes(dataStore, view, editor, ptId);
|
|
61
|
+
if (!ptAttrs)
|
|
62
|
+
return null;
|
|
63
|
+
// IfcCartesianPoint.Coordinates is a list of doubles at attr 0.
|
|
64
|
+
// Polyline points are 2D here (slab profiles), but treat 3D
|
|
65
|
+
// tolerantly — IFC files in the wild sometimes pad with Z=0.
|
|
66
|
+
const coords = asCoordinateTriple(ptAttrs[0]);
|
|
67
|
+
if (!coords)
|
|
68
|
+
return null;
|
|
69
|
+
// Point in profile CS → solid plan (Position translation + rotation)
|
|
70
|
+
// → slab placement origin.
|
|
71
|
+
const [wx, wy] = solidXform([cx + coords[0], cy + coords[1]]);
|
|
72
|
+
out.push([px + wx, py + wy]);
|
|
73
|
+
}
|
|
74
|
+
// IfcPolyline for a closed profile may or may not repeat the
|
|
75
|
+
// first vertex at the end — strip if present, our clip API
|
|
76
|
+
// wants the implicit-close form.
|
|
77
|
+
if (out.length >= 2) {
|
|
78
|
+
const first = out[0];
|
|
79
|
+
const last = out[out.length - 1];
|
|
80
|
+
if (Math.abs(first[0] - last[0]) < 1e-9 && Math.abs(first[1] - last[1]) < 1e-9) {
|
|
81
|
+
out.pop();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return out.length >= 3 ? out : null;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Scale a chain's coordinate-bearing fields (footprint, placement
|
|
88
|
+
* origin, thickness) by `scale`. Identity when `scale === 1`. Used to
|
|
89
|
+
* lift a native-unit (e.g. millimetre) STEP read into the viewer's
|
|
90
|
+
* metre working space — see `resolveSlabEditChain`'s `lengthUnitScale`.
|
|
91
|
+
*/
|
|
92
|
+
function scaleSlabChain(chain, scale) {
|
|
93
|
+
const scaled = scale === 1 ? chain : {
|
|
94
|
+
...chain,
|
|
95
|
+
placementOrigin: [
|
|
96
|
+
chain.placementOrigin[0] * scale,
|
|
97
|
+
chain.placementOrigin[1] * scale,
|
|
98
|
+
chain.placementOrigin[2] * scale,
|
|
99
|
+
],
|
|
100
|
+
baseElevation: chain.baseElevation === null ? null : chain.baseElevation * scale,
|
|
101
|
+
footprint: chain.footprint.map(([x, y]) => [x * scale, y * scale]),
|
|
102
|
+
thickness: chain.thickness * scale,
|
|
103
|
+
};
|
|
104
|
+
if (!Number.isFinite(scaled.thickness) || scaled.thickness <= 0
|
|
105
|
+
|| !scaled.placementOrigin.every(Number.isFinite)
|
|
106
|
+
|| (scaled.baseElevation !== null && !Number.isFinite(scaled.baseElevation))
|
|
107
|
+
|| scaled.footprint.some(point => !point.every(Number.isFinite)))
|
|
108
|
+
return null;
|
|
109
|
+
const area = polygonArea(scaled.footprint);
|
|
110
|
+
// Tilted extrusions may project to a line; their null baseElevation already refuses plan splitting.
|
|
111
|
+
return Number.isFinite(area) && (scaled.baseElevation === null || area > 0) ? scaled : null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Resolve the slab chain (placement + footprint + extrusion). Works
|
|
115
|
+
* for IfcSlab / IfcRoof / IfcPlate / IfcSpace whose representation
|
|
116
|
+
* matches the in-store builder shape; null otherwise.
|
|
117
|
+
*
|
|
118
|
+
* `lengthUnitScale` is the model's native-unit → metre factor (e.g.
|
|
119
|
+
* `0.001` for a millimetre file). Raw STEP coordinate reads are in
|
|
120
|
+
* native units, but the rest of the split flow — raycast cut points,
|
|
121
|
+
* preview meshes, selection hit-tests — lives in metres, so the
|
|
122
|
+
* resolved footprint/thickness are scaled to match. Authored overlay
|
|
123
|
+
* entities are scaled too: the in-store builders convert their metre
|
|
124
|
+
* params to the file's native unit (`toNativePoint3` / `toNativeLength`),
|
|
125
|
+
* so an authored slab in a millimetre file stores millimetres (#6233).
|
|
126
|
+
*/
|
|
127
|
+
export function resolveSlabEditChain(dataStore, view, editor, expressId, lengthUnitScale = 1,
|
|
128
|
+
/** A validated extrusion beneath an envelope's clipping results. */
|
|
129
|
+
bodyItemId) {
|
|
130
|
+
const rawType = editor.getEntityType(expressId);
|
|
131
|
+
if (!rawType)
|
|
132
|
+
return null;
|
|
133
|
+
const elementType = stepTypeToSlabLike(rawType);
|
|
134
|
+
if (!elementType)
|
|
135
|
+
return null;
|
|
136
|
+
const scale = lengthUnitScale;
|
|
137
|
+
if (!Number.isFinite(scale) || scale <= 0)
|
|
138
|
+
return null;
|
|
139
|
+
const chain = resolvePlacementChain(dataStore, view, editor, expressId);
|
|
140
|
+
if (!chain)
|
|
141
|
+
return null;
|
|
142
|
+
const placementOrigin = chain.coordinates;
|
|
143
|
+
const elementAttrs = readAttributes(dataStore, view, editor, expressId);
|
|
144
|
+
if (!elementAttrs)
|
|
145
|
+
return null;
|
|
146
|
+
const productShapeId = asExpressIdRef(elementAttrs[6]);
|
|
147
|
+
if (productShapeId === null)
|
|
148
|
+
return null;
|
|
149
|
+
const productShapeAttrs = readAttributes(dataStore, view, editor, productShapeId);
|
|
150
|
+
if (!productShapeAttrs)
|
|
151
|
+
return null;
|
|
152
|
+
const reps = productShapeAttrs[2];
|
|
153
|
+
if (!Array.isArray(reps) || reps.length === 0)
|
|
154
|
+
return null;
|
|
155
|
+
const shapeRepId = asExpressIdRef(reps[0]);
|
|
156
|
+
if (shapeRepId === null)
|
|
157
|
+
return null;
|
|
158
|
+
const shapeRepAttrs = readAttributes(dataStore, view, editor, shapeRepId);
|
|
159
|
+
if (!shapeRepAttrs)
|
|
160
|
+
return null;
|
|
161
|
+
const items = shapeRepAttrs[3];
|
|
162
|
+
if (!Array.isArray(items) || items.length === 0)
|
|
163
|
+
return null;
|
|
164
|
+
const solidId = bodyItemId ?? asExpressIdRef(items[0]);
|
|
165
|
+
if (solidId === null)
|
|
166
|
+
return null;
|
|
167
|
+
if (editor.getEntityType(solidId)?.toUpperCase() !== 'IFCEXTRUDEDAREASOLID')
|
|
168
|
+
return null;
|
|
169
|
+
const solidAttrs = readAttributes(dataStore, view, editor, solidId);
|
|
170
|
+
if (!solidAttrs)
|
|
171
|
+
return null;
|
|
172
|
+
const profileId = asExpressIdRef(solidAttrs[0]);
|
|
173
|
+
const thicknessRaw = solidAttrs[3];
|
|
174
|
+
if (profileId === null || typeof thicknessRaw !== 'number' || !Number.isFinite(thicknessRaw) || thicknessRaw <= 0)
|
|
175
|
+
return null;
|
|
176
|
+
// Only a vertical extrusion of the plan outline can be cut in plan (#6233).
|
|
177
|
+
const frame = slabExtrusionFrame(dataStore, view, editor, chain.axisPlacementId, solidAttrs, thicknessRaw);
|
|
178
|
+
const baseElevation = frame === null ? null : placementOrigin[2] + frame.base;
|
|
179
|
+
const extrusionUp = frame?.up ?? true;
|
|
180
|
+
// IfcExtrudedAreaSolid.Position (attr 1) is an IfcAxis2Placement3D that
|
|
181
|
+
// places the profile in the solid's frame — real authoring tools bake
|
|
182
|
+
// the slab's plan offset + rotation here (in-store-built slabs leave it
|
|
183
|
+
// identity). Fold it into the footprint so the preview, cut line, and
|
|
184
|
+
// resulting halves land where the rendered mesh actually is.
|
|
185
|
+
const solidXform = resolveSolidPositionXform(dataStore, view, editor, asExpressIdRef(solidAttrs[1]));
|
|
186
|
+
// Profile dispatch — rectangle vs polygon, both produced by
|
|
187
|
+
// addSlabToStore. Source-buffer slabs with mapped representations,
|
|
188
|
+
// I-shape profiles, etc. land in `null` here and the slice
|
|
189
|
+
// surfaces a "not supported" toast.
|
|
190
|
+
const profileAttrs = readAttributes(dataStore, view, editor, profileId);
|
|
191
|
+
if (!profileAttrs)
|
|
192
|
+
return null;
|
|
193
|
+
const profileType = editor.getEntityType(profileId);
|
|
194
|
+
// Profile-local origin (IfcAxis2Placement2D.Location) — both
|
|
195
|
+
// profile kinds share this. May be null for the slot, in which
|
|
196
|
+
// case the spec defaults to origin = (0, 0).
|
|
197
|
+
const profilePosId = asExpressIdRef(profileAttrs[2]);
|
|
198
|
+
let profileOrigin2D = [0, 0];
|
|
199
|
+
if (profilePosId !== null) {
|
|
200
|
+
const profilePosAttrs = readAttributes(dataStore, view, editor, profilePosId);
|
|
201
|
+
if (profilePosAttrs) {
|
|
202
|
+
const profileOriginPtId = asExpressIdRef(profilePosAttrs[0]);
|
|
203
|
+
if (profileOriginPtId !== null) {
|
|
204
|
+
const profileOriginAttrs = readAttributes(dataStore, view, editor, profileOriginPtId);
|
|
205
|
+
if (profileOriginAttrs) {
|
|
206
|
+
const c = asCoordinateTriple(profileOriginAttrs[0]);
|
|
207
|
+
if (c)
|
|
208
|
+
profileOrigin2D = [c[0], c[1]];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (profileType && profileType.toUpperCase() === 'IFCRECTANGLEPROFILEDEF') {
|
|
214
|
+
const xdim = profileAttrs[3];
|
|
215
|
+
const ydim = profileAttrs[4];
|
|
216
|
+
if (typeof xdim !== 'number' || typeof ydim !== 'number'
|
|
217
|
+
|| !Number.isFinite(xdim) || xdim <= 0 || !Number.isFinite(ydim) || ydim <= 0)
|
|
218
|
+
return null;
|
|
219
|
+
return scaleSlabChain({
|
|
220
|
+
elementType,
|
|
221
|
+
placementOrigin,
|
|
222
|
+
baseElevation,
|
|
223
|
+
extrusionUp,
|
|
224
|
+
footprint: rectangleFootprint(placementOrigin, profileOrigin2D, xdim, ydim, solidXform),
|
|
225
|
+
extrudedSolidId: solidId,
|
|
226
|
+
thickness: thicknessRaw,
|
|
227
|
+
profileKind: 'rectangle',
|
|
228
|
+
}, scale);
|
|
229
|
+
}
|
|
230
|
+
if (profileType && profileType.toUpperCase() === 'IFCARBITRARYCLOSEDPROFILEDEF') {
|
|
231
|
+
// OuterCurve at attr 2.
|
|
232
|
+
const polylineId = asExpressIdRef(profileAttrs[2]);
|
|
233
|
+
if (polylineId === null)
|
|
234
|
+
return null;
|
|
235
|
+
const fp = polylineFootprint(dataStore, view, editor, polylineId, placementOrigin, profileOrigin2D, solidXform);
|
|
236
|
+
if (!fp)
|
|
237
|
+
return null;
|
|
238
|
+
return scaleSlabChain({
|
|
239
|
+
elementType,
|
|
240
|
+
placementOrigin,
|
|
241
|
+
baseElevation,
|
|
242
|
+
extrusionUp,
|
|
243
|
+
footprint: fp,
|
|
244
|
+
extrudedSolidId: solidId,
|
|
245
|
+
thickness: thicknessRaw,
|
|
246
|
+
profileKind: 'polygon',
|
|
247
|
+
}, scale);
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Pure split-geometry helper. Clips the slab's footprint by a cut
|
|
253
|
+
* line (defined by two storey-local 2D points) and returns the two
|
|
254
|
+
* halves so the caller can build new slabs with `addSlab`. Both
|
|
255
|
+
* halves carry the source's thickness + storey placement; only the
|
|
256
|
+
* outer-curve polygon changes.
|
|
257
|
+
*
|
|
258
|
+
* Returns the underlying polygon-clip reason on failure so the UI
|
|
259
|
+
* can surface "Cut line does not cross the slab" verbatim.
|
|
260
|
+
*/
|
|
261
|
+
export function computeSlabSplitGeometry(chain, cutA, cutB) {
|
|
262
|
+
const clipped = clipPolygonByLine(chain.footprint, cutA, cutB);
|
|
263
|
+
if (!clipped.ok) {
|
|
264
|
+
return { ok: false, reason: clipped.reason };
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
ok: true,
|
|
268
|
+
leftFootprint: clipped.left,
|
|
269
|
+
rightFootprint: clipped.right,
|
|
270
|
+
thickness: chain.thickness,
|
|
271
|
+
placementOrigin: chain.placementOrigin,
|
|
272
|
+
elementType: chain.elementType,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=slab-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slab-edit.js","sourceRoot":"","sources":["../../../src/in-store/edit/slab-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SplitEnvironment as SplitEnv } from '../element-split.js';
|
|
2
|
+
import type { SlabEditChain } from './slab-edit.js';
|
|
3
|
+
import type { Point2D } from './polygon-clip.js';
|
|
4
|
+
export interface SlabOpeningCarry {
|
|
5
|
+
readonly openingId: number;
|
|
6
|
+
/** Native-unit location in the new host, which starts at the body base. */
|
|
7
|
+
readonly location: [number, number, number];
|
|
8
|
+
}
|
|
9
|
+
export declare function planSlabOpeningCarry(env: SplitEnv, sourceId: number, chain: SlabEditChain, cut: readonly Point2D[], cutA: Point2D, cutB: Point2D, baseElevation: number): SlabOpeningCarry[];
|
|
10
|
+
//# sourceMappingURL=slab-opening-carry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slab-opening-carry.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/slab-opening-carry.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,OAAO,EAAE,EAC9E,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAClD,gBAAgB,EAAE,CA0CpB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
/** #6232: classify the entire physical cut before a slab split writes.
|
|
5
|
+
* Conservative canonical body bounds may refuse a crossing cut; a cut is
|
|
6
|
+
* never assigned from its origin alone. The shared placement writer commits
|
|
7
|
+
* the plan after the destination host exists. */
|
|
8
|
+
import { placedBodyExtent } from '../resolve-host.js';
|
|
9
|
+
import { resolveSpatialAnchor } from '../resolve-anchor.js';
|
|
10
|
+
import { toNativeLength } from '../anchor.js';
|
|
11
|
+
import { readHostedOpeningBatch } from '../hosted-fill-read.js';
|
|
12
|
+
import { AnchorEntityReader } from '../resolve-anchor.js';
|
|
13
|
+
import { refId } from '../host-geometry-frame.js';
|
|
14
|
+
export function planSlabOpeningCarry(env, sourceId, chain, cut, cutA, cutB, baseElevation) {
|
|
15
|
+
const reader = new AnchorEntityReader(env.dataStore, env.view), openingIds = new Set();
|
|
16
|
+
for (const id of reader.ids('IFCRELVOIDSELEMENT')) {
|
|
17
|
+
const rel = reader.entity(id);
|
|
18
|
+
if (!rel || refId(rel.attributes[4]) !== sourceId)
|
|
19
|
+
continue;
|
|
20
|
+
const openingId = refId(rel.attributes[5]);
|
|
21
|
+
if (openingId === null || openingIds.has(openingId))
|
|
22
|
+
throw new Error('A slab cut requires one readable void relationship per opening');
|
|
23
|
+
openingIds.add(openingId);
|
|
24
|
+
}
|
|
25
|
+
if (openingIds.size === 0)
|
|
26
|
+
return [];
|
|
27
|
+
// The footprint reader's accepted frame is unrotated and storey-local.
|
|
28
|
+
// Refuse a different placement parent rather than infer world offsets.
|
|
29
|
+
const host = reader.entity(sourceId), placementId = host ? refId(host.attributes[5]) : null;
|
|
30
|
+
const placement = placementId === null ? null : reader.entity(placementId);
|
|
31
|
+
const anchor = resolveSpatialAnchor(env.dataStore, env.storeyExpressId, env.view);
|
|
32
|
+
if (refId(placement?.attributes[0]) !== anchor.storeyPlacementId)
|
|
33
|
+
throw new Error('A slab with openings must be placed directly in its storey to split safely');
|
|
34
|
+
const dx = cutB[0] - cutA[0], dy = cutB[1] - cutA[1], length = Math.hypot(dx, dy);
|
|
35
|
+
const distance = (x, y) => (dx * (y - cutA[1]) - dy * (x - cutA[0])) / length;
|
|
36
|
+
const epsilon = 1e-7;
|
|
37
|
+
const sample = cut.map(([x, y]) => distance(x, y)).find(value => Math.abs(value) > epsilon);
|
|
38
|
+
if (sample === undefined)
|
|
39
|
+
throw new Error('The destination slab has no readable side of the cut');
|
|
40
|
+
const moves = [], k = env.lengthUnitScale;
|
|
41
|
+
const native = (metres) => toNativeLength({ lengthUnitScale: k }, metres);
|
|
42
|
+
const reads = readHostedOpeningBatch(env.dataStore, openingIds, env.view);
|
|
43
|
+
for (const openingId of openingIds) {
|
|
44
|
+
const read = reads.get(openingId);
|
|
45
|
+
const bounds = placedBodyExtent(env.dataStore, openingId, env.view);
|
|
46
|
+
if (!read || read.hostId !== sourceId || !bounds)
|
|
47
|
+
throw new Error('An unreadable slab opening cannot be carried safely');
|
|
48
|
+
const values = [bounds.min[0], bounds.max[0]].flatMap(x => [bounds.min[1], bounds.max[1]].map(y => distance(x * k + chain.placementOrigin[0], y * k + chain.placementOrigin[1])));
|
|
49
|
+
const min = Math.min(...values), max = Math.max(...values);
|
|
50
|
+
if (min < -epsilon && max > epsilon)
|
|
51
|
+
throw new Error('The slab split crosses a hosted opening');
|
|
52
|
+
const side = max > epsilon ? 1 : min < -epsilon ? -1 : 0;
|
|
53
|
+
if (side === 0)
|
|
54
|
+
throw new Error('The slab opening has no readable side of the cut');
|
|
55
|
+
if (side !== Math.sign(sample))
|
|
56
|
+
continue;
|
|
57
|
+
moves.push({ openingId, location: [
|
|
58
|
+
read.location[0] + native(chain.placementOrigin[0]),
|
|
59
|
+
read.location[1] + native(chain.placementOrigin[1]),
|
|
60
|
+
read.location[2] + native(chain.placementOrigin[2] - baseElevation),
|
|
61
|
+
] });
|
|
62
|
+
}
|
|
63
|
+
return moves;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=slab-opening-carry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slab-opening-carry.js","sourceRoot":"","sources":["../../../src/in-store/edit/slab-opening-carry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
2
|
+
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
3
|
+
/** ifc-lite's fixed namespace for split-piece GlobalIds. Never change it:
|
|
4
|
+
* every derived id in every saved model depends on it. */
|
|
5
|
+
export declare const SPLIT_GLOBALID_NAMESPACE = "5e904553-f79a-466a-8ec3-53d331437713";
|
|
6
|
+
/**
|
|
7
|
+
* The GlobalId for the next piece split off `sourceGlobalId`: the first
|
|
8
|
+
* `k = 0, 1, …` whose candidate `isTaken` rejects. Pure: the same source and
|
|
9
|
+
* the same set of existing ids give the same result.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deriveSplitGlobalId(sourceGlobalId: string, isTaken: (globalId: string) => boolean): string;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the FIRST piece (the one containing the axis / profile start) keeps
|
|
14
|
+
* the source identity: it is at least as large as the second. Sizes are
|
|
15
|
+
* lengths or areas.
|
|
16
|
+
*/
|
|
17
|
+
export declare function keepsFirstPiece(firstSize: number, secondSize: number): boolean;
|
|
18
|
+
/** What {@link globalIdTakenIn} needs of one loaded model. */
|
|
19
|
+
export interface GlobalIdScope {
|
|
20
|
+
dataStore: Pick<IfcDataStore, 'entities'> | null | undefined;
|
|
21
|
+
view: Pick<MutablePropertyView, 'getNewEntities'> | null | undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* "Does any loaded model already carry this GlobalId?" over the parsed index
|
|
25
|
+
* AND the entities authored this session, across every federated model — a
|
|
26
|
+
* split piece must not collide with an element of another model either.
|
|
27
|
+
*/
|
|
28
|
+
export declare function globalIdTakenIn(scopes: Iterable<GlobalIdScope>): (globalId: string) => boolean;
|
|
29
|
+
//# sourceMappingURL=split-guid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-guid.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/split-guid.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;2DAC2D;AAC3D,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAK1G;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7D,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CACtE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAY9F"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
* Identity policy for a split element (#6233, charter #6232 "Decisions").
|
|
6
|
+
*
|
|
7
|
+
* - The LARGER piece keeps the source entity: express id, GlobalId,
|
|
8
|
+
* containment, type, material, property sets. Larger is length for walls /
|
|
9
|
+
* beams / members / columns and footprint area for slabs / roofs / plates /
|
|
10
|
+
* spaces; a tie goes to the piece containing the axis / profile start
|
|
11
|
+
* ({@link keepsFirstPiece}).
|
|
12
|
+
* - The NEW piece's GlobalId is a name-based UUID (v5) of
|
|
13
|
+
* `${sourceGlobalId}/split/${k}` in {@link SPLIT_GLOBALID_NAMESPACE},
|
|
14
|
+
* encoded as the 22-character IFC GlobalId. `k` starts at 0 and increments
|
|
15
|
+
* while the candidate already exists ({@link deriveSplitGlobalId}). It does
|
|
16
|
+
* not depend on where the cut is, so the same source in the same model
|
|
17
|
+
* always yields the same id: a split replayed on another machine, or
|
|
18
|
+
* re-done after an undo, reproduces it.
|
|
19
|
+
*/
|
|
20
|
+
import { uuidToIfcGuid, uuidV5 } from '@ifc-lite/encoding';
|
|
21
|
+
/** ifc-lite's fixed namespace for split-piece GlobalIds. Never change it:
|
|
22
|
+
* every derived id in every saved model depends on it. */
|
|
23
|
+
export const SPLIT_GLOBALID_NAMESPACE = '5e904553-f79a-466a-8ec3-53d331437713';
|
|
24
|
+
/**
|
|
25
|
+
* The GlobalId for the next piece split off `sourceGlobalId`: the first
|
|
26
|
+
* `k = 0, 1, …` whose candidate `isTaken` rejects. Pure: the same source and
|
|
27
|
+
* the same set of existing ids give the same result.
|
|
28
|
+
*/
|
|
29
|
+
export function deriveSplitGlobalId(sourceGlobalId, isTaken) {
|
|
30
|
+
for (let k = 0;; k++) {
|
|
31
|
+
const candidate = uuidToIfcGuid(uuidV5(SPLIT_GLOBALID_NAMESPACE, `${sourceGlobalId}/split/${k}`));
|
|
32
|
+
if (!isTaken(candidate))
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Whether the FIRST piece (the one containing the axis / profile start) keeps
|
|
38
|
+
* the source identity: it is at least as large as the second. Sizes are
|
|
39
|
+
* lengths or areas.
|
|
40
|
+
*/
|
|
41
|
+
export function keepsFirstPiece(firstSize, secondSize) {
|
|
42
|
+
return firstSize >= secondSize;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* "Does any loaded model already carry this GlobalId?" over the parsed index
|
|
46
|
+
* AND the entities authored this session, across every federated model — a
|
|
47
|
+
* split piece must not collide with an element of another model either.
|
|
48
|
+
*/
|
|
49
|
+
export function globalIdTakenIn(scopes) {
|
|
50
|
+
const authored = new Set();
|
|
51
|
+
const stores = [];
|
|
52
|
+
for (const { dataStore, view } of scopes) {
|
|
53
|
+
if (dataStore)
|
|
54
|
+
stores.push(dataStore);
|
|
55
|
+
for (const entity of view?.getNewEntities() ?? []) {
|
|
56
|
+
const guid = entity.attributes[0];
|
|
57
|
+
if (typeof guid === 'string')
|
|
58
|
+
authored.add(guid);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return (globalId) => authored.has(globalId)
|
|
62
|
+
|| stores.some((store) => (store.entities.getExpressIdByGlobalId?.(globalId) ?? -1) > 0);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=split-guid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-guid.js","sourceRoot":"","sources":["../../../src/in-store/edit/split-guid.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI3D;2DAC2D;AAC3D,MAAM,CAAC,MAAM,wBAAwB,GAAG,sCAAsC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,cAAsB,EAAE,OAAsC;IAChG,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,EAAE,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,wBAAwB,EAAE,GAAG,cAAc,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QAClG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,UAAkB;IACnE,OAAO,SAAS,IAAI,UAAU,CAAC;AACjC,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAA+B;IAC7D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAA0C,EAAE,CAAC;IACzD,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACzC,IAAI,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;WACtC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7F,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE answer to "can the Split tool cut this element, and how?" (#6233).
|
|
3
|
+
*
|
|
4
|
+
* The Properties panel's Split button, the canvas click that commits a cut,
|
|
5
|
+
* and the numeric-distance entry all route through {@link resolveSplitTarget}.
|
|
6
|
+
* They used to ask different questions: the button probed the wall reader
|
|
7
|
+
* (which, lacking a type check, also accepted beams and members), the click
|
|
8
|
+
* tried wall → linear → slab and on a miss printed a generic "not a
|
|
9
|
+
* splittable element". So the button could offer a split the commit then
|
|
10
|
+
* refused, and hide one with no explanation.
|
|
11
|
+
*
|
|
12
|
+
* A target is exactly one of three chain kinds, dispatched by IFC class:
|
|
13
|
+
* - `wall` — IfcWall / IfcWallStandardCase, rectangle profile, split by
|
|
14
|
+
* re-authoring two walls (`splitWallAtDistance`).
|
|
15
|
+
* - `linear` — IfcBeam / IfcColumn / IfcMember, rectangle profile, split by
|
|
16
|
+
* shrinking the extrusion (`splitLinearElementAtDistance`).
|
|
17
|
+
* - `slab` — IfcSlab / IfcRoof / IfcPlate / IfcSpace, rectangle or
|
|
18
|
+
* polyline profile, split by a cut line (`splitSlabByLine`).
|
|
19
|
+
* Anything else is a {@link SplitUnavailableCode} naming WHY, which the UI
|
|
20
|
+
* shows as the disabled button's tooltip and the tool's error notice.
|
|
21
|
+
*/
|
|
22
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
23
|
+
import type { MutablePropertyView, StoreEditor } from '@ifc-lite/mutations';
|
|
24
|
+
type TranslationKey = `splitTool.unavailable.${SplitUnavailableCode | 'kind'}`;
|
|
25
|
+
import { type WallEditChain } from './wall-edit.js';
|
|
26
|
+
import { type LinearElementEditChain } from './linear-element-edit.js';
|
|
27
|
+
import { type SlabEditChain } from './slab-edit.js';
|
|
28
|
+
export type SplitUnavailableCode =
|
|
29
|
+
/** Not a wall / beam / column / member / slab / roof / plate / space. */
|
|
30
|
+
'type'
|
|
31
|
+
/** Not contained in any spatial element; the halves need a storey to live in. */
|
|
32
|
+
| 'storey'
|
|
33
|
+
/** Contained in a spatial element that is not a storey (IfcBuilding, IfcSite): the halves still need one. */
|
|
34
|
+
| 'container'
|
|
35
|
+
/** No body representation to cut. */
|
|
36
|
+
| 'noBody'
|
|
37
|
+
/** Triangulated / faceted / B-rep / surface-model body: no profile to cut. */
|
|
38
|
+
| 'mesh'
|
|
39
|
+
/** A mapped (type-instanced) body: cutting it would cut every instance. */
|
|
40
|
+
| 'mapped'
|
|
41
|
+
/** A boolean-clipped body (e.g. a wall clipped under a roof). */
|
|
42
|
+
| 'boolean'
|
|
43
|
+
/** An extrusion, but of a profile the cut math does not handle. */
|
|
44
|
+
| 'profile'
|
|
45
|
+
/** Supported shape family, but its placement / representation layout is not the one the reader walks. */
|
|
46
|
+
| 'shape';
|
|
47
|
+
/** A slab-like chain the split can cut: a vertical extrusion of its outline. */
|
|
48
|
+
export type SlabSplitChain = SlabEditChain & {
|
|
49
|
+
baseElevation: number;
|
|
50
|
+
};
|
|
51
|
+
export type SplitTarget = {
|
|
52
|
+
ok: true;
|
|
53
|
+
kind: 'wall';
|
|
54
|
+
chain: WallEditChain;
|
|
55
|
+
} | {
|
|
56
|
+
ok: true;
|
|
57
|
+
kind: 'linear';
|
|
58
|
+
chain: LinearElementEditChain;
|
|
59
|
+
} | {
|
|
60
|
+
ok: true;
|
|
61
|
+
kind: 'slab';
|
|
62
|
+
chain: SlabSplitChain;
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
code: SplitUnavailableCode;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Classify `expressId` for the Split tool. All lengths on a returned chain
|
|
69
|
+
* are metres (`lengthUnitScale` is the model's native-unit → metre factor).
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveSplitTarget(dataStore: IfcDataStore, view: MutablePropertyView, editor: StoreEditor, expressId: number, lengthUnitScale: number): SplitTarget;
|
|
72
|
+
export interface SplitChains {
|
|
73
|
+
wall: WallEditChain;
|
|
74
|
+
linear: LinearElementEditChain;
|
|
75
|
+
slab: SlabSplitChain;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A commit action's gate: the chain when `target` is the `kind` that action
|
|
79
|
+
* cuts, else the catalogue key of the refusal — the same reason the Split
|
|
80
|
+
* button's tooltip shows for this element.
|
|
81
|
+
*/
|
|
82
|
+
export declare function splitChainOfKind<K extends keyof SplitChains>(target: SplitTarget, kind: K): {
|
|
83
|
+
chain: SplitChains[K];
|
|
84
|
+
} | {
|
|
85
|
+
reasonKey: TranslationKey;
|
|
86
|
+
};
|
|
87
|
+
/** Catalogue key for each {@link SplitUnavailableCode}. */
|
|
88
|
+
export declare function splitUnavailableKey(code: SplitUnavailableCode): TranslationKey;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=split-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-target.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/split-target.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC5E,KAAK,cAAc,GAAG,yBAAyB,oBAAoB,GAAG,MAAM,EAAE,CAAC;AAE/E,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAA6B,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG1E,MAAM,MAAM,oBAAoB;AAC9B,yEAAyE;AACvE,MAAM;AACR,iFAAiF;GAC/E,QAAQ;AACV,6GAA6G;GAC3G,WAAW;AACb,qCAAqC;GACnC,QAAQ;AACV,8EAA8E;GAC5E,MAAM;AACR,2EAA2E;GACzE,QAAQ;AACV,iEAAiE;GAC/D,SAAS;AACX,mEAAmE;GACjE,SAAS;AACX,yGAAyG;GACvG,OAAO,CAAC;AAEZ,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAChD;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,sBAAsB,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GACjD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAW9C;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,WAAW,CA0Bb;AAqCD,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE;AAE1G;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,WAAW,EAC1D,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,CAAC,GACN;IAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,cAAc,CAAA;CAAE,CAK3D;AAED,2DAA2D;AAC3D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,cAAc,CAY9E"}
|