opengeometry 2.0.7 → 2.0.9
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 +8 -13
- package/index.js +575 -76
- package/index.js.map +1 -1
- package/opengeometry/pkg/opengeometry.d.ts +237 -201
- package/opengeometry/pkg/opengeometry.js +209 -42
- package/opengeometry/pkg/opengeometry_bg.wasm +0 -0
- package/opengeometry/pkg/opengeometry_bg.wasm.d.ts +206 -200
- package/opengeometry_bg.wasm +0 -0
- package/opengeometry_bg.wasm.d.ts +206 -200
- package/package.json +1 -1
- package/src/examples/wall-from-offsets.d.ts +30 -1
- package/src/operations/boolean-errors.d.ts +90 -0
- package/src/operations/boolean.d.ts +34 -3
- package/src/operations/index.d.ts +1 -0
package/index.js
CHANGED
|
@@ -77,20 +77,69 @@ function handleError(f, args) {
|
|
|
77
77
|
wasm.__wbindgen_exn_store(idx);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
function debugString(val) {
|
|
81
|
+
// primitive types
|
|
82
|
+
const type = typeof val;
|
|
83
|
+
if (type == 'number' || type == 'boolean' || val == null) {
|
|
84
|
+
return `${val}`;
|
|
85
|
+
}
|
|
86
|
+
if (type == 'string') {
|
|
87
|
+
return `"${val}"`;
|
|
88
|
+
}
|
|
89
|
+
if (type == 'symbol') {
|
|
90
|
+
const description = val.description;
|
|
91
|
+
if (description == null) {
|
|
92
|
+
return 'Symbol';
|
|
93
|
+
} else {
|
|
94
|
+
return `Symbol(${description})`;
|
|
95
|
+
}
|
|
86
96
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
if (type == 'function') {
|
|
98
|
+
const name = val.name;
|
|
99
|
+
if (typeof name == 'string' && name.length > 0) {
|
|
100
|
+
return `Function(${name})`;
|
|
101
|
+
} else {
|
|
102
|
+
return 'Function';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// objects
|
|
106
|
+
if (Array.isArray(val)) {
|
|
107
|
+
const length = val.length;
|
|
108
|
+
let debug = '[';
|
|
109
|
+
if (length > 0) {
|
|
110
|
+
debug += debugString(val[0]);
|
|
111
|
+
}
|
|
112
|
+
for (let i = 1; i < length; i++) {
|
|
113
|
+
debug += ', ' + debugString(val[i]);
|
|
114
|
+
}
|
|
115
|
+
debug += ']';
|
|
116
|
+
return debug;
|
|
117
|
+
}
|
|
118
|
+
// Test for built-in
|
|
119
|
+
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
|
120
|
+
let className;
|
|
121
|
+
if (builtInMatches && builtInMatches.length > 1) {
|
|
122
|
+
className = builtInMatches[1];
|
|
123
|
+
} else {
|
|
124
|
+
// Failed to match the standard '[object ClassName]'
|
|
125
|
+
return toString.call(val);
|
|
126
|
+
}
|
|
127
|
+
if (className == 'Object') {
|
|
128
|
+
// we're a user defined class or Object
|
|
129
|
+
// JSON.stringify avoids problems with cycles, and is generally much
|
|
130
|
+
// easier than looping through ownProperties of `val`.
|
|
131
|
+
try {
|
|
132
|
+
return 'Object(' + JSON.stringify(val) + ')';
|
|
133
|
+
} catch (_) {
|
|
134
|
+
return 'Object';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// errors
|
|
138
|
+
if (val instanceof Error) {
|
|
139
|
+
return `${val.name}: ${val.message}\n${val.stack}`;
|
|
140
|
+
}
|
|
141
|
+
// TODO we could test for more things here, like `Set`s and `Map`s.
|
|
142
|
+
return className;
|
|
94
143
|
}
|
|
95
144
|
let WASM_VECTOR_LEN = 0;
|
|
96
145
|
const cachedTextEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : {
|
|
@@ -138,6 +187,28 @@ function passStringToWasm0(arg, malloc, realloc) {
|
|
|
138
187
|
WASM_VECTOR_LEN = offset;
|
|
139
188
|
return ptr;
|
|
140
189
|
}
|
|
190
|
+
let cachedDataViewMemory0 = null;
|
|
191
|
+
function getDataViewMemory0() {
|
|
192
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {
|
|
193
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
194
|
+
}
|
|
195
|
+
return cachedDataViewMemory0;
|
|
196
|
+
}
|
|
197
|
+
const cachedTextDecoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', {
|
|
198
|
+
ignoreBOM: true,
|
|
199
|
+
fatal: true
|
|
200
|
+
}) : {
|
|
201
|
+
decode: () => {
|
|
202
|
+
throw Error('TextDecoder not available');
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
if (typeof TextDecoder !== 'undefined') {
|
|
206
|
+
cachedTextDecoder.decode();
|
|
207
|
+
}
|
|
208
|
+
function getStringFromWasm0(ptr, len) {
|
|
209
|
+
ptr = ptr >>> 0;
|
|
210
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
211
|
+
}
|
|
141
212
|
function _assertClass(instance, klass) {
|
|
142
213
|
if (!(instance instanceof klass)) {
|
|
143
214
|
throw new Error(`expected instance of ${klass.name}`);
|
|
@@ -159,39 +230,6 @@ function getArrayF64FromWasm0(ptr, len) {
|
|
|
159
230
|
ptr = ptr >>> 0;
|
|
160
231
|
return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
|
|
161
232
|
}
|
|
162
|
-
/**
|
|
163
|
-
* @param {string} local_brep_serialized
|
|
164
|
-
* @param {number} height
|
|
165
|
-
* @returns {string}
|
|
166
|
-
*/
|
|
167
|
-
function extrudeBrepFace$1(local_brep_serialized, height) {
|
|
168
|
-
let deferred3_0;
|
|
169
|
-
let deferred3_1;
|
|
170
|
-
try {
|
|
171
|
-
const ptr0 = passStringToWasm0(local_brep_serialized, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
172
|
-
const len0 = WASM_VECTOR_LEN;
|
|
173
|
-
const ret = wasm.extrudeBrepFace(ptr0, len0, height);
|
|
174
|
-
var ptr2 = ret[0];
|
|
175
|
-
var len2 = ret[1];
|
|
176
|
-
if (ret[3]) {
|
|
177
|
-
ptr2 = 0;
|
|
178
|
-
len2 = 0;
|
|
179
|
-
throw takeFromExternrefTable0(ret[2]);
|
|
180
|
-
}
|
|
181
|
-
deferred3_0 = ptr2;
|
|
182
|
-
deferred3_1 = len2;
|
|
183
|
-
return getStringFromWasm0(ptr2, len2);
|
|
184
|
-
} finally {
|
|
185
|
-
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
let cachedDataViewMemory0 = null;
|
|
189
|
-
function getDataViewMemory0() {
|
|
190
|
-
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {
|
|
191
|
-
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
192
|
-
}
|
|
193
|
-
return cachedDataViewMemory0;
|
|
194
|
-
}
|
|
195
233
|
function passArrayJsValueToWasm0(array, malloc) {
|
|
196
234
|
const ptr = malloc(array.length * 4, 4) >>> 0;
|
|
197
235
|
for (let i = 0; i < array.length; i++) {
|
|
@@ -287,6 +325,33 @@ function booleanSubtractionMany(lhs_brep_serialized, cutters_brep_serialized, op
|
|
|
287
325
|
}
|
|
288
326
|
return OGBooleanResult.__wrap(ret[0]);
|
|
289
327
|
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @param {string} local_brep_serialized
|
|
331
|
+
* @param {number} height
|
|
332
|
+
* @returns {string}
|
|
333
|
+
*/
|
|
334
|
+
function extrudeBrepFace$1(local_brep_serialized, height) {
|
|
335
|
+
let deferred3_0;
|
|
336
|
+
let deferred3_1;
|
|
337
|
+
try {
|
|
338
|
+
const ptr0 = passStringToWasm0(local_brep_serialized, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
339
|
+
const len0 = WASM_VECTOR_LEN;
|
|
340
|
+
const ret = wasm.extrudeBrepFace(ptr0, len0, height);
|
|
341
|
+
var ptr2 = ret[0];
|
|
342
|
+
var len2 = ret[1];
|
|
343
|
+
if (ret[3]) {
|
|
344
|
+
ptr2 = 0;
|
|
345
|
+
len2 = 0;
|
|
346
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
347
|
+
}
|
|
348
|
+
deferred3_0 = ptr2;
|
|
349
|
+
deferred3_1 = len2;
|
|
350
|
+
return getStringFromWasm0(ptr2, len2);
|
|
351
|
+
} finally {
|
|
352
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
290
355
|
function getArrayJsValueFromWasm0(ptr, len) {
|
|
291
356
|
ptr = ptr >>> 0;
|
|
292
357
|
const mem = getDataViewMemory0();
|
|
@@ -1666,6 +1731,99 @@ class OGCylinder {
|
|
|
1666
1731
|
return Vector3.__wrap(ret);
|
|
1667
1732
|
}
|
|
1668
1733
|
}
|
|
1734
|
+
const OGEntityRegistryFinalization = typeof FinalizationRegistry === 'undefined' ? {
|
|
1735
|
+
register: () => {},
|
|
1736
|
+
unregister: () => {}
|
|
1737
|
+
} : new FinalizationRegistry(ptr => wasm.__wbg_ogentityregistry_free(ptr >>> 0, 1));
|
|
1738
|
+
/**
|
|
1739
|
+
* Flat entity registry with a batched multi-view projection API.
|
|
1740
|
+
* Replaces the scene-centric OGSceneManager pattern for export use cases.
|
|
1741
|
+
*/
|
|
1742
|
+
class OGEntityRegistry {
|
|
1743
|
+
__destroy_into_raw() {
|
|
1744
|
+
const ptr = this.__wbg_ptr;
|
|
1745
|
+
this.__wbg_ptr = 0;
|
|
1746
|
+
OGEntityRegistryFinalization.unregister(this);
|
|
1747
|
+
return ptr;
|
|
1748
|
+
}
|
|
1749
|
+
free() {
|
|
1750
|
+
const ptr = this.__destroy_into_raw();
|
|
1751
|
+
wasm.__wbg_ogentityregistry_free(ptr, 0);
|
|
1752
|
+
}
|
|
1753
|
+
constructor() {
|
|
1754
|
+
const ret = wasm.ogentityregistry_new();
|
|
1755
|
+
this.__wbg_ptr = ret >>> 0;
|
|
1756
|
+
OGEntityRegistryFinalization.register(this, this.__wbg_ptr, this);
|
|
1757
|
+
return this;
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Register (or replace) an entity. `kind` must be an OGEntityKind string.
|
|
1761
|
+
* @param {string} id
|
|
1762
|
+
* @param {string} kind
|
|
1763
|
+
* @param {string} brep_json
|
|
1764
|
+
*/
|
|
1765
|
+
registerEntity(id, kind, brep_json) {
|
|
1766
|
+
const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1767
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1768
|
+
const ptr1 = passStringToWasm0(kind, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1769
|
+
const len1 = WASM_VECTOR_LEN;
|
|
1770
|
+
const ptr2 = passStringToWasm0(brep_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1771
|
+
const len2 = WASM_VECTOR_LEN;
|
|
1772
|
+
const ret = wasm.ogentityregistry_registerEntity(this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
|
|
1773
|
+
if (ret[1]) {
|
|
1774
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Remove a previously registered entity.
|
|
1779
|
+
* @param {string} id
|
|
1780
|
+
* @returns {boolean}
|
|
1781
|
+
*/
|
|
1782
|
+
unregisterEntity(id) {
|
|
1783
|
+
const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1784
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1785
|
+
const ret = wasm.ogentityregistry_unregisterEntity(this.__wbg_ptr, ptr0, len0);
|
|
1786
|
+
return ret !== 0;
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Remove all registered entities.
|
|
1790
|
+
*/
|
|
1791
|
+
clearEntities() {
|
|
1792
|
+
wasm.ogentityregistry_clearEntities(this.__wbg_ptr);
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Batched multi-view projection.
|
|
1796
|
+
*
|
|
1797
|
+
* Input: JSON array of `{ id, camera, hlr?, section_plane? }` (ViewRequest).
|
|
1798
|
+
* Output: JSON map of `{ viewportId: Scene2D }`.
|
|
1799
|
+
*
|
|
1800
|
+
* All viewports are projected in a single WASM call, amortising
|
|
1801
|
+
* serialisation overhead and keeping BRep data in WASM memory.
|
|
1802
|
+
* @param {string} views_json
|
|
1803
|
+
* @returns {string}
|
|
1804
|
+
*/
|
|
1805
|
+
projectCurrentToViews(views_json) {
|
|
1806
|
+
let deferred3_0;
|
|
1807
|
+
let deferred3_1;
|
|
1808
|
+
try {
|
|
1809
|
+
const ptr0 = passStringToWasm0(views_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1810
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1811
|
+
const ret = wasm.ogentityregistry_projectCurrentToViews(this.__wbg_ptr, ptr0, len0);
|
|
1812
|
+
var ptr2 = ret[0];
|
|
1813
|
+
var len2 = ret[1];
|
|
1814
|
+
if (ret[3]) {
|
|
1815
|
+
ptr2 = 0;
|
|
1816
|
+
len2 = 0;
|
|
1817
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
1818
|
+
}
|
|
1819
|
+
deferred3_0 = ptr2;
|
|
1820
|
+
deferred3_1 = len2;
|
|
1821
|
+
return getStringFromWasm0(ptr2, len2);
|
|
1822
|
+
} finally {
|
|
1823
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1669
1827
|
const OGFreeformEditorFinalization = typeof FinalizationRegistry === 'undefined' ? {
|
|
1670
1828
|
register: () => {},
|
|
1671
1829
|
unregister: () => {}
|
|
@@ -4996,7 +5154,7 @@ class OGSweep {
|
|
|
4996
5154
|
* @returns {Vector3}
|
|
4997
5155
|
*/
|
|
4998
5156
|
get_anchor() {
|
|
4999
|
-
const ret = wasm.
|
|
5157
|
+
const ret = wasm.ogsweep_get_anchor(this.__wbg_ptr);
|
|
5000
5158
|
return Vector3.__wrap(ret);
|
|
5001
5159
|
}
|
|
5002
5160
|
/**
|
|
@@ -5613,6 +5771,13 @@ function __wbg_get_imports() {
|
|
|
5613
5771
|
const ret = Vector3.__unwrap(arg0);
|
|
5614
5772
|
return ret;
|
|
5615
5773
|
};
|
|
5774
|
+
imports.wbg.__wbindgen_debug_string = function (arg0, arg1) {
|
|
5775
|
+
const ret = debugString(arg1);
|
|
5776
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
5777
|
+
const len1 = WASM_VECTOR_LEN;
|
|
5778
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
5779
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
5780
|
+
};
|
|
5616
5781
|
imports.wbg.__wbindgen_init_externref_table = function () {
|
|
5617
5782
|
const table = wasm.__wbindgen_export_2;
|
|
5618
5783
|
const offset = table.grow(4);
|
|
@@ -5692,6 +5857,7 @@ var OGKernel = /*#__PURE__*/Object.freeze({
|
|
|
5692
5857
|
OGCuboid: OGCuboid,
|
|
5693
5858
|
OGCurve: OGCurve,
|
|
5694
5859
|
OGCylinder: OGCylinder,
|
|
5860
|
+
OGEntityRegistry: OGEntityRegistry,
|
|
5695
5861
|
OGFreeformEditor: OGFreeformEditor,
|
|
5696
5862
|
OGFreeformGeometry: OGFreeformGeometry,
|
|
5697
5863
|
OGIfcExportResult: OGIfcExportResult,
|
|
@@ -6250,7 +6416,6 @@ function createFreeformGeometry(source, options) {
|
|
|
6250
6416
|
return geometry;
|
|
6251
6417
|
}
|
|
6252
6418
|
|
|
6253
|
-
/* eslint-enable no-unused-vars */
|
|
6254
6419
|
/**
|
|
6255
6420
|
* Simple Line defined by Two Points
|
|
6256
6421
|
*/
|
|
@@ -6473,7 +6638,6 @@ class Line extends THREE.Line {
|
|
|
6473
6638
|
}
|
|
6474
6639
|
}
|
|
6475
6640
|
|
|
6476
|
-
/* eslint-enable no-unused-vars */
|
|
6477
6641
|
/**
|
|
6478
6642
|
* Polyline wrapper backed by the kernel OGPolyline primitive.
|
|
6479
6643
|
*/
|
|
@@ -6913,7 +7077,6 @@ class Arc extends THREE.Line {
|
|
|
6913
7077
|
}
|
|
6914
7078
|
}
|
|
6915
7079
|
|
|
6916
|
-
/* eslint-enable no-unused-vars */
|
|
6917
7080
|
/**
|
|
6918
7081
|
* Rectangle wrapper backed by the kernel OGRectangle primitive.
|
|
6919
7082
|
*/
|
|
@@ -7151,7 +7314,6 @@ class Rectangle extends THREE.Line {
|
|
|
7151
7314
|
}
|
|
7152
7315
|
}
|
|
7153
7316
|
|
|
7154
|
-
/* eslint-enable no-unused-vars */
|
|
7155
7317
|
/**
|
|
7156
7318
|
* Curve wrapper backed by the kernel OGCurve primitive.
|
|
7157
7319
|
*/
|
|
@@ -7426,16 +7588,169 @@ function serializeBrepLike$1(value) {
|
|
|
7426
7588
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
7427
7589
|
}
|
|
7428
7590
|
|
|
7591
|
+
/**
|
|
7592
|
+
* Typed error hierarchy for boolean operations.
|
|
7593
|
+
*
|
|
7594
|
+
* The Rust kernel emits a structured `BooleanError` as JSON across the WASM
|
|
7595
|
+
* boundary (see `main/opengeometry/src/booleans/error.rs`). This module parses
|
|
7596
|
+
* that JSON and re-throws it as a typed `BooleanError` (or a more specific
|
|
7597
|
+
* subclass) so app code can `instanceof`-discriminate without parsing message
|
|
7598
|
+
* strings.
|
|
7599
|
+
*
|
|
7600
|
+
* Cutter indices are **0-based** to match `Vec` / array indexing on both
|
|
7601
|
+
* sides of the boundary.
|
|
7602
|
+
*/
|
|
7603
|
+
/**
|
|
7604
|
+
* Base class for every typed boolean error. Carries the structured payload the
|
|
7605
|
+
* kernel emitted across WASM. Specialized subclasses (`OverlappingCuttersError`,
|
|
7606
|
+
* `CutterExceedsHostError`, `NonManifoldOutputError`, `CoincidentFacesError`)
|
|
7607
|
+
* narrow the payload for the variants that carry extra fields.
|
|
7608
|
+
*/
|
|
7609
|
+
class BooleanError extends Error {
|
|
7610
|
+
constructor(payload) {
|
|
7611
|
+
super(payload.message);
|
|
7612
|
+
this.name = "BooleanError";
|
|
7613
|
+
this.reason = payload.kind.code;
|
|
7614
|
+
this.phase = payload.phase;
|
|
7615
|
+
this.cutterIndex = payload.cutter_index;
|
|
7616
|
+
this.details = payload.details;
|
|
7617
|
+
this.edgeSamples = payload.edge_samples
|
|
7618
|
+
? payload.edge_samples.map(([a, b]) => [
|
|
7619
|
+
new THREE.Vector3(a.x, a.y, a.z),
|
|
7620
|
+
new THREE.Vector3(b.x, b.y, b.z),
|
|
7621
|
+
])
|
|
7622
|
+
: null;
|
|
7623
|
+
}
|
|
7624
|
+
}
|
|
7625
|
+
/**
|
|
7626
|
+
* Two cutters overlap each other. `otherIndex` is the 0-based index of the
|
|
7627
|
+
* cutter that conflicts with the one at `cutterIndex`.
|
|
7628
|
+
*/
|
|
7629
|
+
class OverlappingCuttersError extends BooleanError {
|
|
7630
|
+
constructor(payload) {
|
|
7631
|
+
var _a;
|
|
7632
|
+
super(payload);
|
|
7633
|
+
this.name = "OverlappingCuttersError";
|
|
7634
|
+
this.otherIndex = (_a = payload.kind.other_index) !== null && _a !== void 0 ? _a : -1;
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7637
|
+
/**
|
|
7638
|
+
* A cutter extends past the host's hull along the named axis.
|
|
7639
|
+
*/
|
|
7640
|
+
class CutterExceedsHostError extends BooleanError {
|
|
7641
|
+
constructor(payload) {
|
|
7642
|
+
var _a, _b;
|
|
7643
|
+
super(payload);
|
|
7644
|
+
this.name = "CutterExceedsHostError";
|
|
7645
|
+
const axis = ((_a = payload.kind.axis) !== null && _a !== void 0 ? _a : "x").toLowerCase();
|
|
7646
|
+
this.axis = (axis === "y" || axis === "z" ? axis : "x");
|
|
7647
|
+
this.overshoot = (_b = payload.kind.overshoot) !== null && _b !== void 0 ? _b : 0;
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
/**
|
|
7651
|
+
* Output mesh has open or over-shared edges after a boolean. `edgeSamples`
|
|
7652
|
+
* carries up to ~8 sample non-manifold edges to aid app-side debugging.
|
|
7653
|
+
*/
|
|
7654
|
+
class NonManifoldOutputError extends BooleanError {
|
|
7655
|
+
constructor(payload) {
|
|
7656
|
+
super(payload);
|
|
7657
|
+
this.name = "NonManifoldOutputError";
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
/**
|
|
7661
|
+
* Cutter and host share a coplanar face. Distinct from
|
|
7662
|
+
* `DegenerateTriangleError` (zero-area input) — see `06a-snap-tolerance.md`.
|
|
7663
|
+
*/
|
|
7664
|
+
class CoincidentFacesError extends BooleanError {
|
|
7665
|
+
constructor(payload) {
|
|
7666
|
+
super(payload);
|
|
7667
|
+
this.name = "CoincidentFacesError";
|
|
7668
|
+
}
|
|
7669
|
+
}
|
|
7670
|
+
/**
|
|
7671
|
+
* Parses a WASM-thrown error and returns the appropriate typed `BooleanError`
|
|
7672
|
+
* subclass. If the error's message is not valid `BooleanError` JSON, returns a
|
|
7673
|
+
* fallback `BooleanError` with `reason: "kernel_failure"` carrying the original
|
|
7674
|
+
* string, so callers always get a typed error and never have to `try/catch`
|
|
7675
|
+
* twice.
|
|
7676
|
+
*/
|
|
7677
|
+
function parseBooleanError(raw) {
|
|
7678
|
+
var _a, _b, _c, _d, _e;
|
|
7679
|
+
const message = extractMessage(raw);
|
|
7680
|
+
let payload = null;
|
|
7681
|
+
try {
|
|
7682
|
+
const parsed = JSON.parse(message);
|
|
7683
|
+
if (parsed && typeof parsed === "object" && parsed.kind && typeof parsed.kind === "object") {
|
|
7684
|
+
payload = {
|
|
7685
|
+
kind: parsed.kind,
|
|
7686
|
+
phase: ((_a = parsed.phase) !== null && _a !== void 0 ? _a : "input_validation"),
|
|
7687
|
+
cutter_index: (_b = parsed.cutter_index) !== null && _b !== void 0 ? _b : null,
|
|
7688
|
+
message: (_c = parsed.message) !== null && _c !== void 0 ? _c : message,
|
|
7689
|
+
details: (_d = parsed.details) !== null && _d !== void 0 ? _d : null,
|
|
7690
|
+
edge_samples: (_e = parsed.edge_samples) !== null && _e !== void 0 ? _e : null,
|
|
7691
|
+
};
|
|
7692
|
+
}
|
|
7693
|
+
}
|
|
7694
|
+
catch (_f) {
|
|
7695
|
+
payload = null;
|
|
7696
|
+
}
|
|
7697
|
+
if (!payload) {
|
|
7698
|
+
payload = {
|
|
7699
|
+
kind: { code: "kernel_failure" },
|
|
7700
|
+
phase: "input_validation",
|
|
7701
|
+
cutter_index: null,
|
|
7702
|
+
message,
|
|
7703
|
+
details: null,
|
|
7704
|
+
edge_samples: null,
|
|
7705
|
+
};
|
|
7706
|
+
}
|
|
7707
|
+
switch (payload.kind.code) {
|
|
7708
|
+
case "overlapping_cutters":
|
|
7709
|
+
return new OverlappingCuttersError(payload);
|
|
7710
|
+
case "cutter_exceeds_host":
|
|
7711
|
+
return new CutterExceedsHostError(payload);
|
|
7712
|
+
case "non_manifold_edges":
|
|
7713
|
+
case "open_shell":
|
|
7714
|
+
return new NonManifoldOutputError(payload);
|
|
7715
|
+
case "coincident_faces":
|
|
7716
|
+
return new CoincidentFacesError(payload);
|
|
7717
|
+
default:
|
|
7718
|
+
return new BooleanError(payload);
|
|
7719
|
+
}
|
|
7720
|
+
}
|
|
7721
|
+
function extractMessage(raw) {
|
|
7722
|
+
if (raw === null || raw === undefined) {
|
|
7723
|
+
return "";
|
|
7724
|
+
}
|
|
7725
|
+
if (typeof raw === "string") {
|
|
7726
|
+
return raw;
|
|
7727
|
+
}
|
|
7728
|
+
if (raw instanceof Error) {
|
|
7729
|
+
return raw.message;
|
|
7730
|
+
}
|
|
7731
|
+
if (typeof raw === "object" && "message" in raw) {
|
|
7732
|
+
const message = raw.message;
|
|
7733
|
+
if (typeof message === "string") {
|
|
7734
|
+
return message;
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7737
|
+
try {
|
|
7738
|
+
return String(raw);
|
|
7739
|
+
}
|
|
7740
|
+
catch (_a) {
|
|
7741
|
+
return "Unknown boolean error";
|
|
7742
|
+
}
|
|
7743
|
+
}
|
|
7744
|
+
|
|
7429
7745
|
var _BooleanResult_outlineMesh;
|
|
7430
|
-
/* eslint-enable no-unused-vars */
|
|
7431
7746
|
const BOOLEAN_CREASE_ANGLE = Math.PI / 5;
|
|
7432
7747
|
const BOOLEAN_OUTLINE_THRESHOLD_DEGREES = 26;
|
|
7433
7748
|
/**
|
|
7434
7749
|
* Renderable result mesh returned by the kernel boolean helpers.
|
|
7435
7750
|
*/
|
|
7436
7751
|
class BooleanResult extends THREE.Mesh {
|
|
7437
|
-
constructor(kernelResult, options) {
|
|
7438
|
-
var _a, _b
|
|
7752
|
+
constructor(kernelResult, options, host = null) {
|
|
7753
|
+
var _a, _b;
|
|
7439
7754
|
super();
|
|
7440
7755
|
this.report = null;
|
|
7441
7756
|
this.brepSerialized = "";
|
|
@@ -7448,15 +7763,47 @@ class BooleanResult extends THREE.Mesh {
|
|
|
7448
7763
|
this.ogid = getUUID();
|
|
7449
7764
|
this._fatOutlines = (_a = options === null || options === void 0 ? void 0 : options.fatOutlines) !== null && _a !== void 0 ? _a : false;
|
|
7450
7765
|
this._outlineWidth = sanitizeOutlineWidth(options === null || options === void 0 ? void 0 : options.outlineWidth);
|
|
7451
|
-
|
|
7452
|
-
if (
|
|
7766
|
+
const metadata = resolveOperandMetadata(host);
|
|
7767
|
+
if (metadata.name) {
|
|
7768
|
+
this.name = metadata.name;
|
|
7769
|
+
}
|
|
7770
|
+
if (metadata.userData) {
|
|
7771
|
+
this.userData = Object.assign({}, metadata.userData);
|
|
7772
|
+
}
|
|
7773
|
+
this.applyKernelResult(kernelResult, options, metadata.material);
|
|
7774
|
+
if ((_b = options === null || options === void 0 ? void 0 : options.outline) !== null && _b !== void 0 ? _b : false) {
|
|
7453
7775
|
this.outline = true;
|
|
7454
7776
|
}
|
|
7455
7777
|
}
|
|
7778
|
+
/**
|
|
7779
|
+
* Updates the result mesh's color in place without re-running the boolean
|
|
7780
|
+
* pipeline. Accepts any value Three.js accepts (`number`, hex string, css
|
|
7781
|
+
* color name, or `THREE.Color`). No-op for materials without a `color` field.
|
|
7782
|
+
*/
|
|
7783
|
+
set color(value) {
|
|
7784
|
+
const apply = (material) => {
|
|
7785
|
+
if ("color" in material) {
|
|
7786
|
+
material.color.set(value);
|
|
7787
|
+
}
|
|
7788
|
+
material.needsUpdate = true;
|
|
7789
|
+
};
|
|
7790
|
+
if (Array.isArray(this.material)) {
|
|
7791
|
+
this.material.forEach(apply);
|
|
7792
|
+
return;
|
|
7793
|
+
}
|
|
7794
|
+
apply(this.material);
|
|
7795
|
+
}
|
|
7796
|
+
get color() {
|
|
7797
|
+
const material = Array.isArray(this.material) ? this.material[0] : this.material;
|
|
7798
|
+
if (!material || !("color" in material)) {
|
|
7799
|
+
return null;
|
|
7800
|
+
}
|
|
7801
|
+
return material.color;
|
|
7802
|
+
}
|
|
7456
7803
|
/**
|
|
7457
7804
|
* Rebuilds the mesh, cached BRep payload, and outline geometry from the kernel output.
|
|
7458
7805
|
*/
|
|
7459
|
-
applyKernelResult(kernelResult,
|
|
7806
|
+
applyKernelResult(kernelResult, options, sourceMaterial = null) {
|
|
7460
7807
|
this.disposeGeometry();
|
|
7461
7808
|
this.brepSerialized = kernelResult.brepSerialized;
|
|
7462
7809
|
this.brepData = JSON.parse(kernelResult.brepSerialized);
|
|
@@ -7467,15 +7814,7 @@ class BooleanResult extends THREE.Mesh {
|
|
|
7467
7814
|
const geometry = toCreasedNormals(baseGeometry, BOOLEAN_CREASE_ANGLE);
|
|
7468
7815
|
geometry.computeBoundingBox();
|
|
7469
7816
|
this.outlinePositions = getRenderableOutlinePositions(geometry, kernelResult.outlineGeometrySerialized);
|
|
7470
|
-
const material =
|
|
7471
|
-
color,
|
|
7472
|
-
transparent: true,
|
|
7473
|
-
opacity: 0.82,
|
|
7474
|
-
side: THREE.FrontSide,
|
|
7475
|
-
polygonOffset: true,
|
|
7476
|
-
polygonOffsetFactor: 1,
|
|
7477
|
-
polygonOffsetUnits: 1,
|
|
7478
|
-
});
|
|
7817
|
+
const material = buildResultMaterial(sourceMaterial, options);
|
|
7479
7818
|
this.geometry = geometry;
|
|
7480
7819
|
this.material = material;
|
|
7481
7820
|
if (this._outlineEnabled) {
|
|
@@ -7602,12 +7941,21 @@ function executeBooleanSubtractionMany(lhs, cutters, options) {
|
|
|
7602
7941
|
}
|
|
7603
7942
|
const kernelFunction = booleanExport;
|
|
7604
7943
|
const kernelOptions = serializeKernelOptions(options === null || options === void 0 ? void 0 : options.kernel);
|
|
7605
|
-
|
|
7606
|
-
|
|
7944
|
+
let kernelResult;
|
|
7945
|
+
try {
|
|
7946
|
+
kernelResult = kernelFunction(resolveOperandSerialized(lhs), JSON.stringify(cutters.map(resolveOperandPayload)), kernelOptions);
|
|
7947
|
+
}
|
|
7948
|
+
catch (error) {
|
|
7949
|
+
throw parseBooleanError(error);
|
|
7950
|
+
}
|
|
7951
|
+
return createBooleanResult(kernelResult, options, lhs);
|
|
7607
7952
|
}
|
|
7608
7953
|
/**
|
|
7609
7954
|
* Normalizes mixed wrapper/raw operands, invokes the wasm boolean export, and
|
|
7610
7955
|
* returns the renderable result wrapper.
|
|
7956
|
+
*
|
|
7957
|
+
* @throws {BooleanError} (or a subclass) when the kernel rejects the operation.
|
|
7958
|
+
* See `boolean-errors.ts` for the typed hierarchy.
|
|
7611
7959
|
*/
|
|
7612
7960
|
function executeBoolean(exportName, lhs, rhs, options) {
|
|
7613
7961
|
const booleanExport = OGKernel[exportName];
|
|
@@ -7616,8 +7964,14 @@ function executeBoolean(exportName, lhs, rhs, options) {
|
|
|
7616
7964
|
}
|
|
7617
7965
|
const kernelFunction = booleanExport;
|
|
7618
7966
|
const kernelOptions = serializeKernelOptions(options === null || options === void 0 ? void 0 : options.kernel);
|
|
7619
|
-
|
|
7620
|
-
|
|
7967
|
+
let kernelResult;
|
|
7968
|
+
try {
|
|
7969
|
+
kernelResult = kernelFunction(resolveOperandSerialized(lhs), resolveOperandSerialized(rhs), kernelOptions);
|
|
7970
|
+
}
|
|
7971
|
+
catch (error) {
|
|
7972
|
+
throw parseBooleanError(error);
|
|
7973
|
+
}
|
|
7974
|
+
return createBooleanResult(kernelResult, options, lhs);
|
|
7621
7975
|
}
|
|
7622
7976
|
/**
|
|
7623
7977
|
* Accepts wrapper objects, raw BRep data, or serialized JSON and normalizes
|
|
@@ -7673,14 +8027,76 @@ function serializeKernelOptions(options) {
|
|
|
7673
8027
|
merge_coplanar_faces: options.mergeCoplanarFaces,
|
|
7674
8028
|
});
|
|
7675
8029
|
}
|
|
7676
|
-
function createBooleanResult(kernelResult, options) {
|
|
8030
|
+
function createBooleanResult(kernelResult, options, host = null) {
|
|
7677
8031
|
var _a;
|
|
7678
|
-
const result = new BooleanResult(kernelResult, options);
|
|
8032
|
+
const result = new BooleanResult(kernelResult, options, host);
|
|
7679
8033
|
if ((_a = options === null || options === void 0 ? void 0 : options.outline) !== null && _a !== void 0 ? _a : true) {
|
|
7680
8034
|
result.outline = true;
|
|
7681
8035
|
}
|
|
7682
8036
|
return result;
|
|
7683
8037
|
}
|
|
8038
|
+
/**
|
|
8039
|
+
* Returns the material, name, and userData carried on the operand when it is
|
|
8040
|
+
* a Three mesh subclass (Solid, Polygon, Cuboid, Opening, BooleanResult,
|
|
8041
|
+
* etc.) so the result mesh can drop into a scene graph as-is. Falls back to
|
|
8042
|
+
* empty metadata for serialized JSON, parsed BRep objects, or anything else
|
|
8043
|
+
* without a reachable host mesh.
|
|
8044
|
+
*/
|
|
8045
|
+
function resolveOperandMetadata(operand) {
|
|
8046
|
+
var _a, _b, _c;
|
|
8047
|
+
const empty = { material: null, name: "", userData: null };
|
|
8048
|
+
if (operand === null || typeof operand !== "object" || !(operand instanceof THREE.Mesh)) {
|
|
8049
|
+
return empty;
|
|
8050
|
+
}
|
|
8051
|
+
const rawMaterial = operand.material;
|
|
8052
|
+
let material = null;
|
|
8053
|
+
if (Array.isArray(rawMaterial)) {
|
|
8054
|
+
material = (_a = rawMaterial[0]) !== null && _a !== void 0 ? _a : null;
|
|
8055
|
+
}
|
|
8056
|
+
else if (rawMaterial instanceof THREE.Material) {
|
|
8057
|
+
material = rawMaterial;
|
|
8058
|
+
}
|
|
8059
|
+
return {
|
|
8060
|
+
material,
|
|
8061
|
+
name: (_b = operand.name) !== null && _b !== void 0 ? _b : "",
|
|
8062
|
+
userData: (_c = operand.userData) !== null && _c !== void 0 ? _c : null,
|
|
8063
|
+
};
|
|
8064
|
+
}
|
|
8065
|
+
/**
|
|
8066
|
+
* Builds the boolean result mesh's material by cloning the host (LHS) material
|
|
8067
|
+
* when available so the result inherits the host's color, transparency, and
|
|
8068
|
+
* side mode. Caller-provided overrides on `BooleanRenderOptions` win, and the
|
|
8069
|
+
* polygon-offset settings that prevent z-fighting with the result outline are
|
|
8070
|
+
* always reapplied after cloning.
|
|
8071
|
+
*/
|
|
8072
|
+
function buildResultMaterial(sourceMaterial, options) {
|
|
8073
|
+
const material = sourceMaterial
|
|
8074
|
+
? sourceMaterial.clone()
|
|
8075
|
+
: new THREE.MeshStandardMaterial({
|
|
8076
|
+
color: 0x2563eb,
|
|
8077
|
+
transparent: false,
|
|
8078
|
+
opacity: 1,
|
|
8079
|
+
side: THREE.FrontSide,
|
|
8080
|
+
});
|
|
8081
|
+
if ((options === null || options === void 0 ? void 0 : options.color) !== undefined && "color" in material) {
|
|
8082
|
+
material.color.set(options.color);
|
|
8083
|
+
}
|
|
8084
|
+
if ((options === null || options === void 0 ? void 0 : options.opacity) !== undefined) {
|
|
8085
|
+
material.opacity = options.opacity;
|
|
8086
|
+
material.transparent = options.opacity < 1 || material.transparent;
|
|
8087
|
+
}
|
|
8088
|
+
if ((options === null || options === void 0 ? void 0 : options.transparent) !== undefined) {
|
|
8089
|
+
material.transparent = options.transparent;
|
|
8090
|
+
}
|
|
8091
|
+
if ((options === null || options === void 0 ? void 0 : options.side) !== undefined) {
|
|
8092
|
+
material.side = options.side;
|
|
8093
|
+
}
|
|
8094
|
+
material.polygonOffset = true;
|
|
8095
|
+
material.polygonOffsetFactor = 1;
|
|
8096
|
+
material.polygonOffsetUnits = 1;
|
|
8097
|
+
material.needsUpdate = true;
|
|
8098
|
+
return material;
|
|
8099
|
+
}
|
|
7684
8100
|
/**
|
|
7685
8101
|
* Builds a display-quality outline buffer from the rendered mesh and falls back
|
|
7686
8102
|
* to the kernel-provided edges when the client-side extraction is empty.
|
|
@@ -9159,7 +9575,6 @@ class Opening extends THREE.Mesh {
|
|
|
9159
9575
|
_Opening_outlineMesh = new WeakMap();
|
|
9160
9576
|
|
|
9161
9577
|
var _Sphere_outlineMesh;
|
|
9162
|
-
/* eslint-enable no-unused-vars */
|
|
9163
9578
|
/**
|
|
9164
9579
|
* Sphere wrapper backed by the kernel sphere primitive.
|
|
9165
9580
|
*/
|
|
@@ -9704,7 +10119,6 @@ class Wedge extends THREE.Mesh {
|
|
|
9704
10119
|
_Wedge_outlineMesh = new WeakMap();
|
|
9705
10120
|
|
|
9706
10121
|
var _Sweep_outlineMesh;
|
|
9707
|
-
/* eslint-enable no-unused-vars */
|
|
9708
10122
|
/**
|
|
9709
10123
|
* Sweep wrapper backed by the kernel sweep primitive.
|
|
9710
10124
|
*/
|
|
@@ -10302,7 +10716,61 @@ function buildWallOutline(left, right) {
|
|
|
10302
10716
|
}
|
|
10303
10717
|
return outline;
|
|
10304
10718
|
}
|
|
10305
|
-
function
|
|
10719
|
+
function midpoint(a, b) {
|
|
10720
|
+
return new Vector3((a.x + b.x) * 0.5, (a.y + b.y) * 0.5, (a.z + b.z) * 0.5);
|
|
10721
|
+
}
|
|
10722
|
+
function buildDoorCutters(centerlinePoints, count, overshootMeters, wallThickness, doorHeight) {
|
|
10723
|
+
const cutters = [];
|
|
10724
|
+
const wallDepth = wallThickness + 2 * overshootMeters;
|
|
10725
|
+
const doorWidth = 0.6;
|
|
10726
|
+
const segments = centerlinePoints.length - 1;
|
|
10727
|
+
const stride = Math.max(1, Math.floor(segments / count));
|
|
10728
|
+
for (let doorIdx = 0; doorIdx < count; doorIdx++) {
|
|
10729
|
+
const segmentIdx = Math.min(segments - 1, doorIdx * stride);
|
|
10730
|
+
const a = centerlinePoints[segmentIdx];
|
|
10731
|
+
const b = centerlinePoints[segmentIdx + 1];
|
|
10732
|
+
const mid = midpoint(a, b);
|
|
10733
|
+
cutters.push(new Cuboid({
|
|
10734
|
+
width: doorWidth,
|
|
10735
|
+
height: doorHeight,
|
|
10736
|
+
depth: wallDepth,
|
|
10737
|
+
center: new Vector3(0, 0, 0),
|
|
10738
|
+
translation: new Vector3(mid.x, doorHeight * 0.5 + 0.001, mid.z),
|
|
10739
|
+
color: 0xef4444,
|
|
10740
|
+
}));
|
|
10741
|
+
}
|
|
10742
|
+
return cutters;
|
|
10743
|
+
}
|
|
10744
|
+
/**
|
|
10745
|
+
* Renders a human-readable description for a typed `BooleanError` (or any
|
|
10746
|
+
* other thrown value). Used by the example HTML to surface kernel failures
|
|
10747
|
+
* in a status panel without losing the structured payload.
|
|
10748
|
+
*/
|
|
10749
|
+
function describeWallSubtractError(error) {
|
|
10750
|
+
var _a, _b, _c, _d, _e;
|
|
10751
|
+
if (error instanceof OverlappingCuttersError) {
|
|
10752
|
+
return `OverlappingCuttersError @ cutter #${error.cutterIndex} (other #${error.otherIndex}): ${(_a = error.details) !== null && _a !== void 0 ? _a : error.message}`;
|
|
10753
|
+
}
|
|
10754
|
+
if (error instanceof CutterExceedsHostError) {
|
|
10755
|
+
return `CutterExceedsHostError: cutter overshoots ${error.axis} by ${error.overshoot.toExponential(3)}`;
|
|
10756
|
+
}
|
|
10757
|
+
if (error instanceof CoincidentFacesError) {
|
|
10758
|
+
return `CoincidentFacesError: ${(_b = error.details) !== null && _b !== void 0 ? _b : error.message}`;
|
|
10759
|
+
}
|
|
10760
|
+
if (error instanceof NonManifoldOutputError) {
|
|
10761
|
+
const samples = (_d = (_c = error.edgeSamples) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0;
|
|
10762
|
+
return `NonManifoldOutputError: ${samples} non-manifold edges sampled — ${(_e = error.details) !== null && _e !== void 0 ? _e : error.message}`;
|
|
10763
|
+
}
|
|
10764
|
+
if (error instanceof BooleanError) {
|
|
10765
|
+
return `BooleanError (${error.reason}, phase ${error.phase}): ${error.message}`;
|
|
10766
|
+
}
|
|
10767
|
+
if (error instanceof Error) {
|
|
10768
|
+
return `Untyped error: ${error.message}`;
|
|
10769
|
+
}
|
|
10770
|
+
return `Untyped error: ${String(error)}`;
|
|
10771
|
+
}
|
|
10772
|
+
function createWallFromOffsetsExample(scene, options = {}) {
|
|
10773
|
+
var _a, _b, _c, _d;
|
|
10306
10774
|
const centerline = new Polyline({
|
|
10307
10775
|
points: [
|
|
10308
10776
|
new Vector3(-2.6, 0.0, -1.9),
|
|
@@ -10318,6 +10786,7 @@ function createWallFromOffsetsExample(scene) {
|
|
|
10318
10786
|
const half = wallThickness * 0.5;
|
|
10319
10787
|
const acuteThreshold = 35.0;
|
|
10320
10788
|
const bevel = true;
|
|
10789
|
+
const wallHeight = (_a = options.height) !== null && _a !== void 0 ? _a : 2.6;
|
|
10321
10790
|
const leftOffset = centerline.getOffset(half, acuteThreshold, bevel);
|
|
10322
10791
|
const rightOffset = centerline.getOffset(-0.225, acuteThreshold, bevel);
|
|
10323
10792
|
const leftOffsetPolyline = new Polyline({
|
|
@@ -10341,6 +10810,34 @@ function createWallFromOffsetsExample(scene) {
|
|
|
10341
10810
|
scene.add(leftOffsetPolyline);
|
|
10342
10811
|
scene.add(rightOffsetPolyline);
|
|
10343
10812
|
scene.add(wallPolygon);
|
|
10813
|
+
let cutResult = null;
|
|
10814
|
+
let cutError = null;
|
|
10815
|
+
if (((_b = options.doorCount) !== null && _b !== void 0 ? _b : 0) > 0) {
|
|
10816
|
+
const overshootMeters = ((_c = options.overshootMm) !== null && _c !== void 0 ? _c : 1) * 0.001;
|
|
10817
|
+
const wallSolid = wallPolygon.extrude(wallHeight);
|
|
10818
|
+
const cutters = buildDoorCutters([
|
|
10819
|
+
new Vector3(-2.6, 0.0, -1.9),
|
|
10820
|
+
new Vector3(-1.2, 0.0, -1),
|
|
10821
|
+
new Vector3(-0.2, 0.0, 0.1),
|
|
10822
|
+
new Vector3(0.6, 0.0, 0.2),
|
|
10823
|
+
new Vector3(0.1, 0.0, 1.0),
|
|
10824
|
+
new Vector3(2.6, 0.0, 2.0),
|
|
10825
|
+
], (_d = options.doorCount) !== null && _d !== void 0 ? _d : 0, overshootMeters, wallThickness, 2.1);
|
|
10826
|
+
try {
|
|
10827
|
+
const cutWall = wallSolid.subtract(cutters, {
|
|
10828
|
+
color: 0x3b82f6,
|
|
10829
|
+
transparent: false,
|
|
10830
|
+
opacity: 1,
|
|
10831
|
+
});
|
|
10832
|
+
scene.add(cutWall);
|
|
10833
|
+
cutResult = { wall: cutWall, cutters };
|
|
10834
|
+
}
|
|
10835
|
+
catch (error) {
|
|
10836
|
+
cutError = error;
|
|
10837
|
+
scene.add(wallSolid);
|
|
10838
|
+
cutResult = { wall: wallSolid, cutters };
|
|
10839
|
+
}
|
|
10840
|
+
}
|
|
10344
10841
|
return {
|
|
10345
10842
|
centerline,
|
|
10346
10843
|
leftOffsetPolyline,
|
|
@@ -10348,6 +10845,8 @@ function createWallFromOffsetsExample(scene) {
|
|
|
10348
10845
|
wallPolygon,
|
|
10349
10846
|
leftOffset,
|
|
10350
10847
|
rightOffset,
|
|
10848
|
+
cutResult,
|
|
10849
|
+
cutError,
|
|
10351
10850
|
};
|
|
10352
10851
|
}
|
|
10353
10852
|
|
|
@@ -10710,5 +11209,5 @@ class OpenGeometry {
|
|
|
10710
11209
|
OpenGeometry.version = OPEN_GEOMETRY_THREE_VERSION;
|
|
10711
11210
|
OpenGeometry.instance = null;
|
|
10712
11211
|
|
|
10713
|
-
export { Arc, BooleanResult, Cuboid, Curve, Cylinder, FreeformEditor, FreeformGeometry, Line, OGSceneManager, OpenGeometry, Opening, Polygon, Polyline, Rectangle, Solid, Sphere, SpotLabel, Sweep, Vector3, Wedge, booleanIntersection, booleanSubtraction, booleanUnion, clonePlacement, createBooleanExample, createEditorModesExample, createFreeformEditor, createFreeformGeometry, createOffsetExample, createParametricEditCapabilities, createPrimitivesExample, createShapesExample, createSweepExample, createWallFromOffsetsExample, executeBooleanSubtractionMany, extrudeBrepFace, toObjectTransformation$1 as toObjectTransformation };
|
|
11212
|
+
export { Arc, BooleanError, BooleanResult, CoincidentFacesError, Cuboid, Curve, CutterExceedsHostError, Cylinder, FreeformEditor, FreeformGeometry, Line, NonManifoldOutputError, OGSceneManager, OpenGeometry, Opening, OverlappingCuttersError, Polygon, Polyline, Rectangle, Solid, Sphere, SpotLabel, Sweep, Vector3, Wedge, booleanIntersection, booleanSubtraction, booleanUnion, clonePlacement, createBooleanExample, createEditorModesExample, createFreeformEditor, createFreeformGeometry, createOffsetExample, createParametricEditCapabilities, createPrimitivesExample, createShapesExample, createSweepExample, createWallFromOffsetsExample, describeWallSubtractError, executeBooleanSubtractionMany, extrudeBrepFace, parseBooleanError, toObjectTransformation$1 as toObjectTransformation };
|
|
10714
11213
|
//# sourceMappingURL=index.js.map
|