opengeometry 2.0.10 → 2.0.13

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/index.js CHANGED
@@ -239,9 +239,245 @@ function passArrayJsValueToWasm0(array, malloc) {
239
239
  WASM_VECTOR_LEN = array.length;
240
240
  return ptr;
241
241
  }
242
+ function passArrayF64ToWasm0(arg, malloc) {
243
+ const ptr = malloc(arg.length * 8, 8) >>> 0;
244
+ getFloat64ArrayMemory0().set(arg, ptr / 8);
245
+ WASM_VECTOR_LEN = arg.length;
246
+ return ptr;
247
+ }
248
+ function getArrayJsValueFromWasm0(ptr, len) {
249
+ ptr = ptr >>> 0;
250
+ const mem = getDataViewMemory0();
251
+ const result = [];
252
+ for (let i = ptr; i < ptr + 4 * len; i += 4) {
253
+ result.push(wasm.__wbindgen_export_2.get(mem.getUint32(i, true)));
254
+ }
255
+ wasm.__externref_drop_slice(ptr, len);
256
+ return result;
257
+ }
242
258
  function isLikeNone(x) {
243
259
  return x === undefined || x === null;
244
260
  }
261
+ /**
262
+ * Wasm entry point: analyze a flat `[x0,y0,z0,…]` loop, returning the report as
263
+ * JSON (the corrected points are not returned here; use the kernel API).
264
+ * @param {Float64Array} flat_points
265
+ * @returns {string}
266
+ */
267
+ function analyzeProfile(flat_points) {
268
+ let deferred3_0;
269
+ let deferred3_1;
270
+ try {
271
+ const ptr0 = passArrayF64ToWasm0(flat_points, wasm.__wbindgen_malloc);
272
+ const len0 = WASM_VECTOR_LEN;
273
+ const ret = wasm.analyzeProfile(ptr0, len0);
274
+ var ptr2 = ret[0];
275
+ var len2 = ret[1];
276
+ if (ret[3]) {
277
+ ptr2 = 0;
278
+ len2 = 0;
279
+ throw takeFromExternrefTable0(ret[2]);
280
+ }
281
+ deferred3_0 = ptr2;
282
+ deferred3_1 = len2;
283
+ return getStringFromWasm0(ptr2, len2);
284
+ } finally {
285
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Wasm entry point: check a serialized B-rep's geometric validity, returning
291
+ * the [`ValidityReport`] as JSON.
292
+ * @param {string} brep_json
293
+ * @returns {string}
294
+ */
295
+ function checkBrepValidity(brep_json) {
296
+ let deferred3_0;
297
+ let deferred3_1;
298
+ try {
299
+ const ptr0 = passStringToWasm0(brep_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
300
+ const len0 = WASM_VECTOR_LEN;
301
+ const ret = wasm.checkBrepValidity(ptr0, len0);
302
+ var ptr2 = ret[0];
303
+ var len2 = ret[1];
304
+ if (ret[3]) {
305
+ ptr2 = 0;
306
+ len2 = 0;
307
+ throw takeFromExternrefTable0(ret[2]);
308
+ }
309
+ deferred3_0 = ptr2;
310
+ deferred3_1 = len2;
311
+ return getStringFromWasm0(ptr2, len2);
312
+ } finally {
313
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Wasm entry point: heal a serialized B-rep, returning JSON
319
+ * `{ "brep": <healed brep>, "report": <heal report> }`.
320
+ * @param {string} brep_json
321
+ * @param {number} tolerance
322
+ * @returns {string}
323
+ */
324
+ function healBrep(brep_json, tolerance) {
325
+ let deferred3_0;
326
+ let deferred3_1;
327
+ try {
328
+ const ptr0 = passStringToWasm0(brep_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
329
+ const len0 = WASM_VECTOR_LEN;
330
+ const ret = wasm.healBrep(ptr0, len0, tolerance);
331
+ var ptr2 = ret[0];
332
+ var len2 = ret[1];
333
+ if (ret[3]) {
334
+ ptr2 = 0;
335
+ len2 = 0;
336
+ throw takeFromExternrefTable0(ret[2]);
337
+ }
338
+ deferred3_0 = ptr2;
339
+ deferred3_1 = len2;
340
+ return getStringFromWasm0(ptr2, len2);
341
+ } finally {
342
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Wasm entry point: offset a centreline by `width` into stroked regions via the
348
+ * deterministic analytic offset. `centreline_flat` is `[x0,y0,z0, …]`. Returns
349
+ * CW-outer / CCW-hole regions, canonicalised; empty (does NOT throw) when degenerate.
350
+ * @param {Float64Array} centreline_flat
351
+ * @param {number} width
352
+ * @param {boolean} closed
353
+ * @param {number} miter_limit
354
+ * @returns {OGOffsetRegionsResult}
355
+ */
356
+ function offsetPolylineRegions$1(centreline_flat, width, closed, miter_limit) {
357
+ const ptr0 = passArrayF64ToWasm0(centreline_flat, wasm.__wbindgen_malloc);
358
+ const len0 = WASM_VECTOR_LEN;
359
+ const ret = wasm.offsetPolylineRegions(ptr0, len0, width, closed, miter_limit);
360
+ if (ret[2]) {
361
+ throw takeFromExternrefTable0(ret[1]);
362
+ }
363
+ return OGOffsetRegionsResult.__wrap(ret[0]);
364
+ }
365
+
366
+ /**
367
+ * Wasm entry point: merge a GROUP of separate polylines (a crossing T / X / L
368
+ * overlap) into one clean stroked region by nonzero-winding union of their mitered
369
+ * bands. `polylines_json` is `[{centreline:[x,y,z,…], width, closed}, …]`. Returns
370
+ * CW-outer / CCW-hole regions (one or more); empty when nothing is buildable.
371
+ * @param {string} polylines_json
372
+ * @returns {OGOffsetRegionsResult}
373
+ */
374
+ function offsetPolylineGroupRegions$1(polylines_json) {
375
+ const ptr0 = passStringToWasm0(polylines_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
376
+ const len0 = WASM_VECTOR_LEN;
377
+ const ret = wasm.offsetPolylineGroupRegions(ptr0, len0);
378
+ if (ret[2]) {
379
+ throw takeFromExternrefTable0(ret[1]);
380
+ }
381
+ return OGOffsetRegionsResult.__wrap(ret[0]);
382
+ }
383
+
384
+ /**
385
+ * Wasm entry point: inset a CLOSED ring inward with one distance per edge
386
+ * (edge i = ring[i] → ring[i+1]). `ring_flat` is `[x0,y0,z0, …]`;
387
+ * `holes_json` is `[{ring:[x,y,z,…], distances:[…]}, …]` (`"[]"` = none) —
388
+ * excluded interior rings, each grown outward by its own per-edge distances.
389
+ * Returns CW-outer / CCW-hole regions, canonicalised; possibly several when a
390
+ * deep inset (or a hole) splits the ring, and empty (does NOT throw) when the
391
+ * inset collapses or the outer ring is degenerate. THROWS on malformed
392
+ * arguments: a distance count that does not match an edge count, a negative /
393
+ * non-finite distance, a degenerate hole, or unparsable `holes_json`. Corners
394
+ * where distances differ are circumscribed clearance arcs (conservative), so
395
+ * no output point is ever closer to an edge than that edge's distance —
396
+ * there is no miter-limit knob because there are no miters.
397
+ * @param {Float64Array} ring_flat
398
+ * @param {Float64Array} distances
399
+ * @param {string} holes_json
400
+ * @returns {OGOffsetRegionsResult}
401
+ */
402
+ function offsetRingVariable$1(ring_flat, distances, holes_json) {
403
+ const ptr0 = passArrayF64ToWasm0(ring_flat, wasm.__wbindgen_malloc);
404
+ const len0 = WASM_VECTOR_LEN;
405
+ const ptr1 = passArrayF64ToWasm0(distances, wasm.__wbindgen_malloc);
406
+ const len1 = WASM_VECTOR_LEN;
407
+ const ptr2 = passStringToWasm0(holes_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
408
+ const len2 = WASM_VECTOR_LEN;
409
+ const ret = wasm.offsetRingVariable(ptr0, len0, ptr1, len1, ptr2, len2);
410
+ if (ret[2]) {
411
+ throw takeFromExternrefTable0(ret[1]);
412
+ }
413
+ return OGOffsetRegionsResult.__wrap(ret[0]);
414
+ }
415
+
416
+ /**
417
+ * @param {string} local_brep_serialized
418
+ * @param {number} height
419
+ * @returns {string}
420
+ */
421
+ function extrudeBrepFace$1(local_brep_serialized, height) {
422
+ let deferred3_0;
423
+ let deferred3_1;
424
+ try {
425
+ const ptr0 = passStringToWasm0(local_brep_serialized, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
426
+ const len0 = WASM_VECTOR_LEN;
427
+ const ret = wasm.extrudeBrepFace(ptr0, len0, height);
428
+ var ptr2 = ret[0];
429
+ var len2 = ret[1];
430
+ if (ret[3]) {
431
+ ptr2 = 0;
432
+ len2 = 0;
433
+ throw takeFromExternrefTable0(ret[2]);
434
+ }
435
+ deferred3_0 = ptr2;
436
+ deferred3_1 = len2;
437
+ return getStringFromWasm0(ptr2, len2);
438
+ } finally {
439
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Wasm entry point for general extrude. `direction` is `[x,y,z]`; `extent_kind`
445
+ * is `"one_sided" | "symmetric" | "two_sided"`; `d_plus`/`d_minus` are the
446
+ * extent distances (`d_minus` ignored unless two-sided, `d_plus` is the
447
+ * distance for one-sided/symmetric).
448
+ * @param {string} local_brep_serialized
449
+ * @param {Float64Array} direction
450
+ * @param {string} extent_kind
451
+ * @param {number} d_plus
452
+ * @param {number} d_minus
453
+ * @returns {string}
454
+ */
455
+ function extrudeBrepFaceDirectional(local_brep_serialized, direction, extent_kind, d_plus, d_minus) {
456
+ let deferred5_0;
457
+ let deferred5_1;
458
+ try {
459
+ const ptr0 = passStringToWasm0(local_brep_serialized, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
460
+ const len0 = WASM_VECTOR_LEN;
461
+ const ptr1 = passArrayF64ToWasm0(direction, wasm.__wbindgen_malloc);
462
+ const len1 = WASM_VECTOR_LEN;
463
+ const ptr2 = passStringToWasm0(extent_kind, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
464
+ const len2 = WASM_VECTOR_LEN;
465
+ const ret = wasm.extrudeBrepFaceDirectional(ptr0, len0, ptr1, len1, ptr2, len2, d_plus, d_minus);
466
+ var ptr4 = ret[0];
467
+ var len4 = ret[1];
468
+ if (ret[3]) {
469
+ ptr4 = 0;
470
+ len4 = 0;
471
+ throw takeFromExternrefTable0(ret[2]);
472
+ }
473
+ deferred5_0 = ptr4;
474
+ deferred5_1 = len4;
475
+ return getStringFromWasm0(ptr4, len4);
476
+ } finally {
477
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
478
+ }
479
+ }
480
+
245
481
  /**
246
482
  * Wasm entry point for union.
247
483
  * @param {string} lhs_brep_serialized
@@ -327,40 +563,22 @@ function booleanSubtractionMany(lhs_brep_serialized, cutters_brep_serialized, op
327
563
  }
328
564
 
329
565
  /**
330
- * @param {string} local_brep_serialized
331
- * @param {number} height
332
- * @returns {string}
566
+ * Wasm entry point for array-backed batched union. Accepts a JSON array of
567
+ * serialized BReps and folds them with `batch_union` in one boundary crossing.
568
+ * @param {string} operands_brep_serialized
569
+ * @param {string | null} [options_json]
570
+ * @returns {OGBooleanResult}
333
571
  */
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
- }
355
- function getArrayJsValueFromWasm0(ptr, len) {
356
- ptr = ptr >>> 0;
357
- const mem = getDataViewMemory0();
358
- const result = [];
359
- for (let i = ptr; i < ptr + 4 * len; i += 4) {
360
- result.push(wasm.__wbindgen_export_2.get(mem.getUint32(i, true)));
572
+ function batchUnion(operands_brep_serialized, options_json) {
573
+ const ptr0 = passStringToWasm0(operands_brep_serialized, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
574
+ const len0 = WASM_VECTOR_LEN;
575
+ var ptr1 = isLikeNone(options_json) ? 0 : passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
576
+ var len1 = WASM_VECTOR_LEN;
577
+ const ret = wasm.batchUnion(ptr0, len0, ptr1, len1);
578
+ if (ret[2]) {
579
+ throw takeFromExternrefTable0(ret[1]);
361
580
  }
362
- wasm.__externref_drop_slice(ptr, len);
363
- return result;
581
+ return OGBooleanResult.__wrap(ret[0]);
364
582
  }
365
583
  const Matrix3Finalization = typeof FinalizationRegistry === 'undefined' ? {
366
584
  register: () => {},
@@ -1731,6 +1949,221 @@ class OGCylinder {
1731
1949
  return Vector3.__wrap(ret);
1732
1950
  }
1733
1951
  }
1952
+ const OGEllipticalArcFinalization = typeof FinalizationRegistry === 'undefined' ? {
1953
+ register: () => {},
1954
+ unregister: () => {}
1955
+ } : new FinalizationRegistry(ptr => wasm.__wbg_ogellipticalarc_free(ptr >>> 0, 1));
1956
+ class OGEllipticalArc {
1957
+ __destroy_into_raw() {
1958
+ const ptr = this.__wbg_ptr;
1959
+ this.__wbg_ptr = 0;
1960
+ OGEllipticalArcFinalization.unregister(this);
1961
+ return ptr;
1962
+ }
1963
+ free() {
1964
+ const ptr = this.__destroy_into_raw();
1965
+ wasm.__wbg_ogellipticalarc_free(ptr, 0);
1966
+ }
1967
+ /**
1968
+ * @param {string} id
1969
+ */
1970
+ set id(id) {
1971
+ const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1972
+ const len0 = WASM_VECTOR_LEN;
1973
+ wasm.ogellipticalarc_set_id(this.__wbg_ptr, ptr0, len0);
1974
+ }
1975
+ /**
1976
+ * @returns {string}
1977
+ */
1978
+ get id() {
1979
+ let deferred1_0;
1980
+ let deferred1_1;
1981
+ try {
1982
+ const ret = wasm.ogellipticalarc_id(this.__wbg_ptr);
1983
+ deferred1_0 = ret[0];
1984
+ deferred1_1 = ret[1];
1985
+ return getStringFromWasm0(ret[0], ret[1]);
1986
+ } finally {
1987
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
1988
+ }
1989
+ }
1990
+ /**
1991
+ * @param {string} id
1992
+ */
1993
+ constructor(id) {
1994
+ const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1995
+ const len0 = WASM_VECTOR_LEN;
1996
+ const ret = wasm.ogellipticalarc_new(ptr0, len0);
1997
+ this.__wbg_ptr = ret >>> 0;
1998
+ OGEllipticalArcFinalization.register(this, this.__wbg_ptr, this);
1999
+ return this;
2000
+ }
2001
+ /**
2002
+ * @param {Vector3} center
2003
+ * @param {number} radius_x
2004
+ * @param {number} radius_z
2005
+ * @param {number} start_angle
2006
+ * @param {number} end_angle
2007
+ * @param {number} segments
2008
+ */
2009
+ set_config(center, radius_x, radius_z, start_angle, end_angle, segments) {
2010
+ _assertClass(center, Vector3);
2011
+ var ptr0 = center.__destroy_into_raw();
2012
+ const ret = wasm.ogellipticalarc_set_config(this.__wbg_ptr, ptr0, radius_x, radius_z, start_angle, end_angle, segments);
2013
+ if (ret[1]) {
2014
+ throw takeFromExternrefTable0(ret[0]);
2015
+ }
2016
+ }
2017
+ /**
2018
+ * @param {Vector3} center
2019
+ */
2020
+ set_center(center) {
2021
+ _assertClass(center, Vector3);
2022
+ var ptr0 = center.__destroy_into_raw();
2023
+ wasm.ogellipticalarc_set_center(this.__wbg_ptr, ptr0);
2024
+ }
2025
+ /**
2026
+ * @param {Vector3} position
2027
+ * @param {Vector3} rotation
2028
+ * @param {Vector3} scale
2029
+ */
2030
+ set_transform(position, rotation, scale) {
2031
+ _assertClass(position, Vector3);
2032
+ var ptr0 = position.__destroy_into_raw();
2033
+ _assertClass(rotation, Vector3);
2034
+ var ptr1 = rotation.__destroy_into_raw();
2035
+ _assertClass(scale, Vector3);
2036
+ var ptr2 = scale.__destroy_into_raw();
2037
+ const ret = wasm.ogellipticalarc_set_transform(this.__wbg_ptr, ptr0, ptr1, ptr2);
2038
+ if (ret[1]) {
2039
+ throw takeFromExternrefTable0(ret[0]);
2040
+ }
2041
+ }
2042
+ /**
2043
+ * @param {Vector3} translation
2044
+ */
2045
+ set_translation(translation) {
2046
+ _assertClass(translation, Vector3);
2047
+ var ptr0 = translation.__destroy_into_raw();
2048
+ wasm.ogellipticalarc_set_translation(this.__wbg_ptr, ptr0);
2049
+ }
2050
+ /**
2051
+ * @param {Vector3} rotation
2052
+ */
2053
+ set_rotation(rotation) {
2054
+ _assertClass(rotation, Vector3);
2055
+ var ptr0 = rotation.__destroy_into_raw();
2056
+ wasm.ogellipticalarc_set_rotation(this.__wbg_ptr, ptr0);
2057
+ }
2058
+ /**
2059
+ * @param {Vector3} scale
2060
+ */
2061
+ set_scale(scale) {
2062
+ _assertClass(scale, Vector3);
2063
+ var ptr0 = scale.__destroy_into_raw();
2064
+ const ret = wasm.ogellipticalarc_set_scale(this.__wbg_ptr, ptr0);
2065
+ if (ret[1]) {
2066
+ throw takeFromExternrefTable0(ret[0]);
2067
+ }
2068
+ }
2069
+ generate_geometry() {
2070
+ const ret = wasm.ogellipticalarc_generate_geometry(this.__wbg_ptr);
2071
+ if (ret[1]) {
2072
+ throw takeFromExternrefTable0(ret[0]);
2073
+ }
2074
+ }
2075
+ dispose_points() {
2076
+ wasm.ogellipticalarc_dispose_points(this.__wbg_ptr);
2077
+ }
2078
+ destroy() {
2079
+ wasm.ogellipticalarc_destroy(this.__wbg_ptr);
2080
+ }
2081
+ /**
2082
+ * @returns {string}
2083
+ */
2084
+ get_brep_serialized() {
2085
+ let deferred1_0;
2086
+ let deferred1_1;
2087
+ try {
2088
+ const ret = wasm.ogellipticalarc_get_brep_serialized(this.__wbg_ptr);
2089
+ deferred1_0 = ret[0];
2090
+ deferred1_1 = ret[1];
2091
+ return getStringFromWasm0(ret[0], ret[1]);
2092
+ } finally {
2093
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
2094
+ }
2095
+ }
2096
+ /**
2097
+ * @returns {string}
2098
+ */
2099
+ get_local_brep_serialized() {
2100
+ let deferred1_0;
2101
+ let deferred1_1;
2102
+ try {
2103
+ const ret = wasm.ogellipticalarc_get_local_brep_serialized(this.__wbg_ptr);
2104
+ deferred1_0 = ret[0];
2105
+ deferred1_1 = ret[1];
2106
+ return getStringFromWasm0(ret[0], ret[1]);
2107
+ } finally {
2108
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
2109
+ }
2110
+ }
2111
+ /**
2112
+ * @returns {string}
2113
+ */
2114
+ get_geometry_serialized() {
2115
+ let deferred1_0;
2116
+ let deferred1_1;
2117
+ try {
2118
+ const ret = wasm.ogellipticalarc_get_geometry_serialized(this.__wbg_ptr);
2119
+ deferred1_0 = ret[0];
2120
+ deferred1_1 = ret[1];
2121
+ return getStringFromWasm0(ret[0], ret[1]);
2122
+ } finally {
2123
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
2124
+ }
2125
+ }
2126
+ /**
2127
+ * @returns {string}
2128
+ */
2129
+ get_local_geometry_serialized() {
2130
+ let deferred1_0;
2131
+ let deferred1_1;
2132
+ try {
2133
+ const ret = wasm.ogellipticalarc_get_local_geometry_serialized(this.__wbg_ptr);
2134
+ deferred1_0 = ret[0];
2135
+ deferred1_1 = ret[1];
2136
+ return getStringFromWasm0(ret[0], ret[1]);
2137
+ } finally {
2138
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
2139
+ }
2140
+ }
2141
+ /**
2142
+ * @returns {Float64Array}
2143
+ */
2144
+ get_geometry_buffer() {
2145
+ const ret = wasm.ogellipticalarc_get_geometry_buffer(this.__wbg_ptr);
2146
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
2147
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
2148
+ return v1;
2149
+ }
2150
+ /**
2151
+ * @returns {Float64Array}
2152
+ */
2153
+ get_local_geometry_buffer() {
2154
+ const ret = wasm.ogellipticalarc_get_local_geometry_buffer(this.__wbg_ptr);
2155
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
2156
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
2157
+ return v1;
2158
+ }
2159
+ /**
2160
+ * @returns {Vector3}
2161
+ */
2162
+ get_anchor() {
2163
+ const ret = wasm.ogellipticalarc_get_anchor(this.__wbg_ptr);
2164
+ return Vector3.__wrap(ret);
2165
+ }
2166
+ }
1734
2167
  const OGEntityRegistryFinalization = typeof FinalizationRegistry === 'undefined' ? {
1735
2168
  register: () => {},
1736
2169
  unregister: () => {}
@@ -2818,7 +3251,7 @@ class OGLine {
2818
3251
  * @returns {Vector3}
2819
3252
  */
2820
3253
  get_anchor() {
2821
- const ret = wasm.ogcurve_get_anchor(this.__wbg_ptr);
3254
+ const ret = wasm.ogline_get_anchor(this.__wbg_ptr);
2822
3255
  return Vector3.__wrap(ret);
2823
3256
  }
2824
3257
  /**
@@ -2872,6 +3305,50 @@ class OGLine {
2872
3305
  }
2873
3306
  }
2874
3307
  }
3308
+ const OGOffsetRegionsResultFinalization = typeof FinalizationRegistry === 'undefined' ? {
3309
+ register: () => {},
3310
+ unregister: () => {}
3311
+ } : new FinalizationRegistry(ptr => wasm.__wbg_ogoffsetregionsresult_free(ptr >>> 0, 1));
3312
+ /**
3313
+ * Result payload for a polyline offset: a list of regions (each an outer ring +
3314
+ * inner-void holes). Normally one region; a self-crossing closed centreline (e.g.
3315
+ * a figure-8) yields one per simple sub-loop. The deterministic analytic offset —
3316
+ * no extrude/solid. Used to build the plan polygons + extruded base solids in JS.
3317
+ */
3318
+ class OGOffsetRegionsResult {
3319
+ static __wrap(ptr) {
3320
+ ptr = ptr >>> 0;
3321
+ const obj = Object.create(OGOffsetRegionsResult.prototype);
3322
+ obj.__wbg_ptr = ptr;
3323
+ OGOffsetRegionsResultFinalization.register(obj, obj.__wbg_ptr, obj);
3324
+ return obj;
3325
+ }
3326
+ __destroy_into_raw() {
3327
+ const ptr = this.__wbg_ptr;
3328
+ this.__wbg_ptr = 0;
3329
+ OGOffsetRegionsResultFinalization.unregister(this);
3330
+ return ptr;
3331
+ }
3332
+ free() {
3333
+ const ptr = this.__destroy_into_raw();
3334
+ wasm.__wbg_ogoffsetregionsresult_free(ptr, 0);
3335
+ }
3336
+ /**
3337
+ * @returns {string}
3338
+ */
3339
+ get regionsSerialized() {
3340
+ let deferred1_0;
3341
+ let deferred1_1;
3342
+ try {
3343
+ const ret = wasm.ogoffsetregionsresult_regionsSerialized(this.__wbg_ptr);
3344
+ deferred1_0 = ret[0];
3345
+ deferred1_1 = ret[1];
3346
+ return getStringFromWasm0(ret[0], ret[1]);
3347
+ } finally {
3348
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
3349
+ }
3350
+ }
3351
+ }
2875
3352
  const OGPolygonFinalization = typeof FinalizationRegistry === 'undefined' ? {
2876
3353
  register: () => {},
2877
3354
  unregister: () => {}
@@ -3444,7 +3921,7 @@ class OGPolyline {
3444
3921
  * @returns {Vector3}
3445
3922
  */
3446
3923
  get_anchor() {
3447
- const ret = wasm.ogcurve_get_anchor(this.__wbg_ptr);
3924
+ const ret = wasm.ogline_get_anchor(this.__wbg_ptr);
3448
3925
  return Vector3.__wrap(ret);
3449
3926
  }
3450
3927
  /**
@@ -4772,7 +5249,7 @@ class OGSphere {
4772
5249
  * @returns {Vector3}
4773
5250
  */
4774
5251
  get_anchor() {
4775
- const ret = wasm.ogsphere_get_anchor(this.__wbg_ptr);
5252
+ const ret = wasm.ogline_get_anchor(this.__wbg_ptr);
4776
5253
  return Vector3.__wrap(ret);
4777
5254
  }
4778
5255
  }
@@ -5154,7 +5631,7 @@ class OGSweep {
5154
5631
  * @returns {Vector3}
5155
5632
  */
5156
5633
  get_anchor() {
5157
- const ret = wasm.ogsweep_get_anchor(this.__wbg_ptr);
5634
+ const ret = wasm.ogellipticalarc_get_anchor(this.__wbg_ptr);
5158
5635
  return Vector3.__wrap(ret);
5159
5636
  }
5160
5637
  /**
@@ -5686,46 +6163,140 @@ class Vector3 {
5686
6163
  *
5687
6164
  * @returns {Vector3}
5688
6165
  */
5689
- normalize() {
5690
- const ret = wasm.vector3_normalize(this.__wbg_ptr);
6166
+ normalize() {
6167
+ const ret = wasm.vector3_normalize(this.__wbg_ptr);
6168
+ return Vector3.__wrap(ret);
6169
+ }
6170
+ /**
6171
+ *
6172
+ * * Calculate the cross product and return the result as a new Vector3
6173
+ *
6174
+ * @param {Vector3} other
6175
+ * @returns {Vector3}
6176
+ */
6177
+ cross(other) {
6178
+ _assertClass(other, Vector3);
6179
+ const ret = wasm.vector3_cross(this.__wbg_ptr, other.__wbg_ptr);
6180
+ return Vector3.__wrap(ret);
6181
+ }
6182
+ /**
6183
+ *
6184
+ * * Calculate the distance between this vector and another Vector3 instance.
6185
+ * * Return the distance as a f64 value in Euclidean space.
6186
+ *
6187
+ * @param {Vector3} other
6188
+ * @returns {number}
6189
+ */
6190
+ distance(other) {
6191
+ _assertClass(other, Vector3);
6192
+ const ret = wasm.vector3_distance(this.__wbg_ptr, other.__wbg_ptr);
6193
+ return ret;
6194
+ }
6195
+ /**
6196
+ *
6197
+ * * Apply a transformation matrix to the vector.
6198
+ * * This method assumes the transformation matrix is a 4x4 matrix.
6199
+ *
6200
+ * @param {Matrix4} matrix
6201
+ */
6202
+ apply_matrix4(matrix) {
6203
+ _assertClass(matrix, Matrix4);
6204
+ var ptr0 = matrix.__destroy_into_raw();
6205
+ wasm.vector3_apply_matrix4(this.__wbg_ptr, ptr0);
6206
+ }
6207
+ }
6208
+ const WorkPlaneFinalization = typeof FinalizationRegistry === 'undefined' ? {
6209
+ register: () => {},
6210
+ unregister: () => {}
6211
+ } : new FinalizationRegistry(ptr => wasm.__wbg_workplane_free(ptr >>> 0, 1));
6212
+ class WorkPlane {
6213
+ static __wrap(ptr) {
6214
+ ptr = ptr >>> 0;
6215
+ const obj = Object.create(WorkPlane.prototype);
6216
+ obj.__wbg_ptr = ptr;
6217
+ WorkPlaneFinalization.register(obj, obj.__wbg_ptr, obj);
6218
+ return obj;
6219
+ }
6220
+ __destroy_into_raw() {
6221
+ const ptr = this.__wbg_ptr;
6222
+ this.__wbg_ptr = 0;
6223
+ WorkPlaneFinalization.unregister(this);
6224
+ return ptr;
6225
+ }
6226
+ free() {
6227
+ const ptr = this.__destroy_into_raw();
6228
+ wasm.__wbg_workplane_free(ptr, 0);
6229
+ }
6230
+ /**
6231
+ * Builds a work plane from an origin and normal, choosing a stable in-plane
6232
+ * `u` axis automatically (`v = normal × u`).
6233
+ * @param {Vector3} origin
6234
+ * @param {Vector3} normal
6235
+ * @returns {WorkPlane}
6236
+ */
6237
+ static fromOriginNormal(origin, normal) {
6238
+ _assertClass(origin, Vector3);
6239
+ var ptr0 = origin.__destroy_into_raw();
6240
+ _assertClass(normal, Vector3);
6241
+ var ptr1 = normal.__destroy_into_raw();
6242
+ const ret = wasm.workplane_fromOriginNormal(ptr0, ptr1);
6243
+ return WorkPlane.__wrap(ret);
6244
+ }
6245
+ /**
6246
+ * Builds a work plane from an origin, normal, and a preferred `u` axis. The
6247
+ * `u` axis is projected onto the plane and orthonormalized; `v = normal × u`.
6248
+ * @param {Vector3} origin
6249
+ * @param {Vector3} normal
6250
+ * @param {Vector3} u_hint
6251
+ */
6252
+ constructor(origin, normal, u_hint) {
6253
+ _assertClass(origin, Vector3);
6254
+ var ptr0 = origin.__destroy_into_raw();
6255
+ _assertClass(normal, Vector3);
6256
+ var ptr1 = normal.__destroy_into_raw();
6257
+ _assertClass(u_hint, Vector3);
6258
+ var ptr2 = u_hint.__destroy_into_raw();
6259
+ const ret = wasm.workplane_new(ptr0, ptr1, ptr2);
6260
+ this.__wbg_ptr = ret >>> 0;
6261
+ WorkPlaneFinalization.register(this, this.__wbg_ptr, this);
6262
+ return this;
6263
+ }
6264
+ /**
6265
+ * Lifts a single 2D in-plane coordinate to 3D world space.
6266
+ * @param {number} u
6267
+ * @param {number} v
6268
+ * @returns {Vector3}
6269
+ */
6270
+ liftPoint(u, v) {
6271
+ const ret = wasm.workplane_liftPoint(this.__wbg_ptr, u, v);
5691
6272
  return Vector3.__wrap(ret);
5692
6273
  }
5693
6274
  /**
5694
- *
5695
- * * Calculate the cross product and return the result as a new Vector3
5696
- *
5697
- * @param {Vector3} other
5698
- * @returns {Vector3}
6275
+ * Lifts a flat `[u0,v0,u1,v1,…]` buffer to a flat `[x0,y0,z0,…]` world buffer.
6276
+ * @param {Float64Array} uv
6277
+ * @returns {Float64Array}
5699
6278
  */
5700
- cross(other) {
5701
- _assertClass(other, Vector3);
5702
- const ret = wasm.vector3_cross(this.__wbg_ptr, other.__wbg_ptr);
5703
- return Vector3.__wrap(ret);
6279
+ liftPoints(uv) {
6280
+ const ptr0 = passArrayF64ToWasm0(uv, wasm.__wbindgen_malloc);
6281
+ const len0 = WASM_VECTOR_LEN;
6282
+ const ret = wasm.workplane_liftPoints(this.__wbg_ptr, ptr0, len0);
6283
+ var v2 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
6284
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
6285
+ return v2;
5704
6286
  }
5705
6287
  /**
5706
- *
5707
- * * Calculate the distance between this vector and another Vector3 instance.
5708
- * * Return the distance as a f64 value in Euclidean space.
5709
- *
5710
- * @param {Vector3} other
5711
- * @returns {number}
6288
+ * @returns {Vector3}
5712
6289
  */
5713
- distance(other) {
5714
- _assertClass(other, Vector3);
5715
- const ret = wasm.vector3_distance(this.__wbg_ptr, other.__wbg_ptr);
5716
- return ret;
6290
+ get origin() {
6291
+ const ret = wasm.workplane_origin(this.__wbg_ptr);
6292
+ return Vector3.__wrap(ret);
5717
6293
  }
5718
6294
  /**
5719
- *
5720
- * * Apply a transformation matrix to the vector.
5721
- * * This method assumes the transformation matrix is a 4x4 matrix.
5722
- *
5723
- * @param {Matrix4} matrix
6295
+ * @returns {Vector3}
5724
6296
  */
5725
- apply_matrix4(matrix) {
5726
- _assertClass(matrix, Matrix4);
5727
- var ptr0 = matrix.__destroy_into_raw();
5728
- wasm.vector3_apply_matrix4(this.__wbg_ptr, ptr0);
6297
+ get normal() {
6298
+ const ret = wasm.workplane_normal(this.__wbg_ptr);
6299
+ return Vector3.__wrap(ret);
5729
6300
  }
5730
6301
  }
5731
6302
  async function __wbg_load(module, imports) {
@@ -5857,11 +6428,13 @@ var OGKernel = /*#__PURE__*/Object.freeze({
5857
6428
  OGCuboid: OGCuboid,
5858
6429
  OGCurve: OGCurve,
5859
6430
  OGCylinder: OGCylinder,
6431
+ OGEllipticalArc: OGEllipticalArc,
5860
6432
  OGEntityRegistry: OGEntityRegistry,
5861
6433
  OGFreeformEditor: OGFreeformEditor,
5862
6434
  OGFreeformGeometry: OGFreeformGeometry,
5863
6435
  OGIfcExportResult: OGIfcExportResult,
5864
6436
  OGLine: OGLine,
6437
+ OGOffsetRegionsResult: OGOffsetRegionsResult,
5865
6438
  OGPolygon: OGPolygon,
5866
6439
  OGPolyline: OGPolyline,
5867
6440
  OGRectangle: OGRectangle,
@@ -5872,13 +6445,22 @@ var OGKernel = /*#__PURE__*/Object.freeze({
5872
6445
  OGSweep: OGSweep,
5873
6446
  OGWedge: OGWedge,
5874
6447
  Vector3: Vector3,
6448
+ WorkPlane: WorkPlane,
6449
+ analyzeProfile: analyzeProfile,
6450
+ batchUnion: batchUnion,
5875
6451
  booleanIntersection: booleanIntersection$1,
5876
6452
  booleanSubtraction: booleanSubtraction$1,
5877
6453
  booleanSubtractionMany: booleanSubtractionMany,
5878
6454
  booleanUnion: booleanUnion$1,
6455
+ checkBrepValidity: checkBrepValidity,
5879
6456
  default: __wbg_init,
5880
6457
  extrudeBrepFace: extrudeBrepFace$1,
5881
- initSync: initSync
6458
+ extrudeBrepFaceDirectional: extrudeBrepFaceDirectional,
6459
+ healBrep: healBrep,
6460
+ initSync: initSync,
6461
+ offsetPolylineGroupRegions: offsetPolylineGroupRegions$1,
6462
+ offsetPolylineRegions: offsetPolylineRegions$1,
6463
+ offsetRingVariable: offsetRingVariable$1
5882
6464
  });
5883
6465
 
5884
6466
  function spotLabelElement() {
@@ -7469,6 +8051,214 @@ class Curve extends THREE.Line {
7469
8051
  }
7470
8052
  }
7471
8053
 
8054
+ /**
8055
+ * EllipticalArc wrapper backed by the kernel OGEllipticalArc primitive.
8056
+ */
8057
+ class EllipticalArc extends THREE.Line {
8058
+ set color(color) {
8059
+ this.options.color = color;
8060
+ if (this.material instanceof THREE.LineBasicMaterial) {
8061
+ this.material.color.set(color);
8062
+ }
8063
+ if (this.fatLine && this.fatLine.material instanceof LineMaterial) {
8064
+ this.fatLine.material.color.set(color);
8065
+ }
8066
+ }
8067
+ constructor(options) {
8068
+ var _a, _b, _c, _d;
8069
+ super();
8070
+ this.options = {
8071
+ center: new Vector3(0, 0, 0),
8072
+ radiusX: 1.0,
8073
+ radiusZ: 0.5,
8074
+ startAngle: 0,
8075
+ endAngle: Math.PI * 2,
8076
+ segments: 32,
8077
+ color: 0x00ff00,
8078
+ fatLines: false,
8079
+ width: 20,
8080
+ translation: new Vector3(0, 0, 0),
8081
+ rotation: new Vector3(0, 0, 0),
8082
+ scale: new Vector3(1, 1, 1),
8083
+ };
8084
+ this.fatLine = null;
8085
+ this.ogid = (_a = options === null || options === void 0 ? void 0 : options.ogid) !== null && _a !== void 0 ? _a : getUUID();
8086
+ this.ellipticalArc = new OGEllipticalArc(this.ogid);
8087
+ this.options = Object.assign(Object.assign({}, this.options), options);
8088
+ this.options.ogid = this.ogid;
8089
+ this.setConfig({
8090
+ center: this.options.center.clone(),
8091
+ radiusX: this.options.radiusX,
8092
+ radiusZ: this.options.radiusZ,
8093
+ startAngle: this.options.startAngle,
8094
+ endAngle: this.options.endAngle,
8095
+ segments: this.options.segments,
8096
+ color: this.options.color,
8097
+ fatLines: this.options.fatLines,
8098
+ width: this.options.width,
8099
+ });
8100
+ this.setPlacement({
8101
+ translation: (_b = this.options.translation) === null || _b === void 0 ? void 0 : _b.clone(),
8102
+ rotation: (_c = this.options.rotation) === null || _c === void 0 ? void 0 : _c.clone(),
8103
+ scale: (_d = this.options.scale) === null || _d === void 0 ? void 0 : _d.clone(),
8104
+ });
8105
+ }
8106
+ validateOptions() {
8107
+ if (!this.options) {
8108
+ throw new Error("Options are not defined for EllipticalArc");
8109
+ }
8110
+ }
8111
+ setConfig(options) {
8112
+ this.validateOptions();
8113
+ const nextOptions = Object.assign(Object.assign({}, this.options), options);
8114
+ const geometryChanged = "center" in options ||
8115
+ "radiusX" in options ||
8116
+ "radiusZ" in options ||
8117
+ "segments" in options ||
8118
+ "startAngle" in options ||
8119
+ "endAngle" in options;
8120
+ const renderChanged = "color" in options ||
8121
+ "fatLines" in options ||
8122
+ "width" in options;
8123
+ this.options = nextOptions;
8124
+ if (geometryChanged) {
8125
+ this.ellipticalArc.set_config(nextOptions.center.clone(), nextOptions.radiusX, nextOptions.radiusZ, nextOptions.startAngle, nextOptions.endAngle, nextOptions.segments);
8126
+ this.generateGeometry();
8127
+ return;
8128
+ }
8129
+ if (renderChanged) {
8130
+ this.updateRenderStyle();
8131
+ }
8132
+ }
8133
+ getAnchor() {
8134
+ const anchor = this.ellipticalArc.get_anchor();
8135
+ return new Vector3(anchor.x, anchor.y, anchor.z);
8136
+ }
8137
+ setPlacement(placement) {
8138
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
8139
+ this.options.translation = (_b = (_a = placement.translation) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : this.options.translation;
8140
+ this.options.rotation = (_d = (_c = placement.rotation) === null || _c === void 0 ? void 0 : _c.clone()) !== null && _d !== void 0 ? _d : this.options.rotation;
8141
+ this.options.scale = (_f = (_e = placement.scale) === null || _e === void 0 ? void 0 : _e.clone()) !== null && _f !== void 0 ? _f : this.options.scale;
8142
+ this.ellipticalArc.set_transform((_h = (_g = this.options.translation) === null || _g === void 0 ? void 0 : _g.clone()) !== null && _h !== void 0 ? _h : new Vector3(0, 0, 0), (_k = (_j = this.options.rotation) === null || _j === void 0 ? void 0 : _j.clone()) !== null && _k !== void 0 ? _k : new Vector3(0, 0, 0), (_m = (_l = this.options.scale) === null || _l === void 0 ? void 0 : _l.clone()) !== null && _m !== void 0 ? _m : new Vector3(1, 1, 1));
8143
+ this.generateGeometry();
8144
+ }
8145
+ setTransform(translation, rotation, scale) {
8146
+ this.setPlacement({ translation, rotation, scale });
8147
+ }
8148
+ setTranslation(translation) {
8149
+ this.setPlacement({ translation });
8150
+ }
8151
+ setRotation(rotation) {
8152
+ this.setPlacement({ rotation });
8153
+ }
8154
+ setScale(scale) {
8155
+ this.setPlacement({ scale });
8156
+ }
8157
+ getConfig() {
8158
+ return this.options;
8159
+ }
8160
+ getPlacement() {
8161
+ return clonePlacement({
8162
+ translation: this.options.translation,
8163
+ rotation: this.options.rotation,
8164
+ scale: this.options.scale,
8165
+ });
8166
+ }
8167
+ getEditCapabilities() {
8168
+ return createParametricEditCapabilities("elliptical_arc", "curve");
8169
+ }
8170
+ canConvertToFreeform() {
8171
+ return true;
8172
+ }
8173
+ toFreeform(id = this.ogid) {
8174
+ if (!this.canConvertToFreeform()) {
8175
+ throw new Error("This entity cannot be converted to freeform.");
8176
+ }
8177
+ return createFreeformGeometry(this.ellipticalArc.get_local_brep_serialized(), {
8178
+ id,
8179
+ placement: this.getPlacement(),
8180
+ });
8181
+ }
8182
+ getCurrentPositions() {
8183
+ const attribute = this.geometry.getAttribute("position");
8184
+ if (!attribute || attribute.itemSize !== 3) {
8185
+ return [];
8186
+ }
8187
+ const positions = [];
8188
+ for (let index = 0; index < attribute.count; index += 1) {
8189
+ positions.push(attribute.getX(index), attribute.getY(index), attribute.getZ(index));
8190
+ }
8191
+ return positions;
8192
+ }
8193
+ updateRenderStyle(bufferData) {
8194
+ var _a;
8195
+ const positions = bufferData !== null && bufferData !== void 0 ? bufferData : this.getCurrentPositions();
8196
+ if (this.options.fatLines) {
8197
+ if (!this.fatLine) {
8198
+ this.fatLine = new Line2(new LineGeometry(), new LineMaterial({
8199
+ color: this.options.color,
8200
+ linewidth: this.options.width,
8201
+ resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
8202
+ }));
8203
+ this.add(this.fatLine);
8204
+ }
8205
+ this.fatLine.geometry.setPositions(positions);
8206
+ this.fatLine.material.color.set(this.options.color);
8207
+ this.fatLine.material.linewidth = (_a = this.options.width) !== null && _a !== void 0 ? _a : 5;
8208
+ this.fatLine.material.resolution.set(window.innerWidth, window.innerHeight);
8209
+ this.fatLine.visible = true;
8210
+ }
8211
+ else if (this.fatLine) {
8212
+ this.fatLine.visible = false;
8213
+ }
8214
+ if (this.material instanceof THREE.LineBasicMaterial) {
8215
+ this.material.color.set(this.options.color);
8216
+ this.material.visible = !this.options.fatLines;
8217
+ }
8218
+ }
8219
+ generateGeometry() {
8220
+ const bufferData = Array.from(this.ellipticalArc.get_geometry_buffer());
8221
+ this.writePositionsToGeometry(this.geometry, bufferData);
8222
+ this.geometry.computeBoundingBox();
8223
+ this.geometry.computeBoundingSphere();
8224
+ if (this.material instanceof THREE.LineBasicMaterial) {
8225
+ this.material.color.set(this.options.color);
8226
+ }
8227
+ else {
8228
+ if (Array.isArray(this.material)) {
8229
+ this.material.forEach((material) => material.dispose());
8230
+ }
8231
+ else {
8232
+ this.material.dispose();
8233
+ }
8234
+ this.material = new THREE.LineBasicMaterial({ color: this.options.color });
8235
+ }
8236
+ this.updateRenderStyle(bufferData);
8237
+ }
8238
+ getBrep() {
8239
+ const brepData = this.ellipticalArc.get_brep_serialized();
8240
+ if (!brepData) {
8241
+ throw new Error("Brep data is not available for EllipticalArc");
8242
+ }
8243
+ return JSON.parse(brepData);
8244
+ }
8245
+ discardGeometry() {
8246
+ this.geometry.dispose();
8247
+ }
8248
+ writePositionsToGeometry(geometry, positions) {
8249
+ const existing = geometry.getAttribute("position");
8250
+ if (!(existing instanceof THREE.BufferAttribute) ||
8251
+ existing.itemSize !== 3 ||
8252
+ existing.count !== positions.length / 3) {
8253
+ geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
8254
+ return;
8255
+ }
8256
+ const array = existing.array;
8257
+ array.set(positions);
8258
+ existing.needsUpdate = true;
8259
+ }
8260
+ }
8261
+
7472
8262
  const DEFAULT_OUTLINE_COLOR = 0x000000;
7473
8263
  const DEFAULT_OUTLINE_WIDTH = 1;
7474
8264
  function getOutlineResolution() {
@@ -10697,6 +11487,139 @@ function createOffsetExample(scene) {
10697
11487
  };
10698
11488
  }
10699
11489
 
11490
+ /**
11491
+ * Offset a centreline by ±half-width into one or more filled REGIONS, via the
11492
+ * deterministic analytic offset — miters / flat bevels at `miterLimit`, concave
11493
+ * trims, and nonzero-winding resolution of reflex / closed loops. NO boolean union
11494
+ * (so it is deterministic, unlike the 3D-mesh CSG path). A simple centreline returns
11495
+ * one region; a self-crossing closed centreline (e.g. a figure-8) returns one per
11496
+ * simple sub-loop. Returns an EMPTY array for a genuinely unbuildable input (does
11497
+ * not throw, so it never looks like a kernel crash). Rings are CW-outer / CCW-holes.
11498
+ *
11499
+ * @param centrelineFlat centreline points as `[x,y,z, …]`.
11500
+ * @param width full stroke width (offset ±width/2 on each side).
11501
+ * @param miterLimit SVG stroke-miterlimit; corners sharper than this bevel. Default 4.
11502
+ */
11503
+ function offsetPolylineRegions(centrelineFlat, width, closed, miterLimit = 4) {
11504
+ const buildExport = offsetPolylineRegions$1;
11505
+ if (typeof buildExport !== "function") {
11506
+ throw new Error("offsetPolylineRegions is not available in the loaded wasm package. Rebuild opengeometry wasm bindings.");
11507
+ }
11508
+ const flat = centrelineFlat instanceof Float64Array ? centrelineFlat : new Float64Array(centrelineFlat);
11509
+ const result = buildExport(flat, width, closed, miterLimit);
11510
+ return JSON.parse(result.regionsSerialized);
11511
+ }
11512
+ /**
11513
+ * Inset a CLOSED ring inward with one distance per edge (edge i =
11514
+ * `ring[i] → ring[i+1]`; an explicit closing duplicate point is accepted and
11515
+ * stripped, the distance count stays one per unique edge). Built for setback
11516
+ * envelopes: the result is the CLEARANCE-EXACT buildable region — the ring's
11517
+ * interior minus every point within `distances[i]` of edge i's SEGMENT, so
11518
+ * distant lot lines are honoured across notches and corners where distances
11519
+ * differ become circumscribed clearance arcs (conservative). There is no
11520
+ * `miterLimit` parameter, deliberately: miters and bevels only approximate the
11521
+ * clearance arc, and a bevel would claim points inside the required distance.
11522
+ *
11523
+ * `holes` are excluded interior rings, each grown outward by its own per-edge
11524
+ * distances — the region keeps clear of a hole's edges exactly as it keeps
11525
+ * clear of the lot lines, so a hole can split the region or swallow it.
11526
+ *
11527
+ * Returns CW-outer / CCW-hole regions (canonical start vertex), possibly
11528
+ * SEVERAL when a deep inset (or a hole) splits a waisted ring into disjoint
11529
+ * lobes, and an EMPTY array when the inset collapses or the outer ring is
11530
+ * degenerate (< 3 unique points, zero area, self-intersecting). THROWS on
11531
+ * malformed arguments: a distance count that does not match an edge count, a
11532
+ * negative / non-finite distance, or a degenerate hole — those are caller
11533
+ * bugs, not geometry.
11534
+ *
11535
+ * @param ring closed ring points as `[x,y,z, …]` (Y is carried through).
11536
+ * @param distances inward inset distance per edge, metres, each >= 0
11537
+ * (0 = the edge stays in place, e.g. lot-line construction).
11538
+ * @param holes excluded interior rings with their own per-edge distances.
11539
+ */
11540
+ function offsetRingVariable(ring, distances, holes = []) {
11541
+ const buildExport = offsetRingVariable$1;
11542
+ if (typeof buildExport !== "function") {
11543
+ throw new Error("offsetRingVariable is not available in the loaded wasm package. It requires opengeometry >= 2.0.12 — rebuild or upgrade the opengeometry wasm bindings.");
11544
+ }
11545
+ const flatRing = ring instanceof Float64Array ? ring : new Float64Array(ring);
11546
+ const flatDistances = distances instanceof Float64Array ? distances : new Float64Array(distances);
11547
+ const holesJson = JSON.stringify(holes.map((hole) => ({ ring: Array.from(hole.ring), distances: Array.from(hole.distances) })));
11548
+ const result = buildExport(flatRing, flatDistances, holesJson);
11549
+ return JSON.parse(result.regionsSerialized);
11550
+ }
11551
+ /**
11552
+ * Merge a GROUP of separate polylines (a crossing T / X / L overlap) into one clean
11553
+ * region by nonzero-winding union of their mitered bands — the overlapping strokes
11554
+ * merge into a single region with mitered/bevelled corners, no internal edges.
11555
+ * Returns CW-outer / CCW-hole regions (one or more); empty if nothing is buildable.
11556
+ * No CSG. Used to render/extrude an overlapping crossing as one joined mass.
11557
+ */
11558
+ function offsetPolylineGroupRegions(polylines) {
11559
+ const buildExport = offsetPolylineGroupRegions$1;
11560
+ if (typeof buildExport !== "function") {
11561
+ throw new Error("offsetPolylineGroupRegions is not available in the loaded wasm package. Rebuild opengeometry wasm bindings.");
11562
+ }
11563
+ const result = buildExport(JSON.stringify(polylines));
11564
+ return JSON.parse(result.regionsSerialized);
11565
+ }
11566
+
11567
+ /** Close a kernel ring for Polyline rendering (repeat the first point). */
11568
+ function closedRingPoints(ring) {
11569
+ const points = ring.map((point) => new Vector3(point.x, point.y, point.z));
11570
+ if (points.length > 0) {
11571
+ const first = ring[0];
11572
+ points.push(new Vector3(first.x, first.y, first.z));
11573
+ }
11574
+ return points;
11575
+ }
11576
+ /**
11577
+ * Variable (per-edge) ring inset: a rectangular "parcel" inset by front 6 /
11578
+ * side 1.5 / rear 3 setbacks, and a waisted (dumbbell) parcel whose uniform
11579
+ * 3 m inset SPLITS into two disjoint buildable envelopes — the case a uniform
11580
+ * offset cannot express.
11581
+ */
11582
+ function createOffsetRingVariableExample(scene) {
11583
+ const scale = 0.2; // metres → scene units, keeps both parcels in frame
11584
+ const parcel = [0, 0, 0, 20, 0, 0, 20, 0, 30, 0, 0, 30].map((v) => v * scale);
11585
+ const parcelSetbacks = [6, 1.5, 3, 1.5].map((v) => v * scale);
11586
+ const dumbbell = [
11587
+ 0, 0, 0, 20, 0, 0, 20, 0, 14, 12, 0, 14, 12, 0, 26, 20, 0, 26, 20, 0, 40, 0, 0, 40, 0, 0, 26,
11588
+ 8, 0, 26, 8, 0, 14, 0, 0, 14,
11589
+ ].map((v, index) => (index % 3 === 0 ? v * scale + 6 : v * scale)); // shifted +x
11590
+ const dumbbellSetbacks = new Array(12).fill(3 * scale);
11591
+ const parcelOutline = new Polyline({
11592
+ points: closedRingPoints(Array.from({ length: parcel.length / 3 }, (_, i) => ({
11593
+ x: parcel[i * 3],
11594
+ y: parcel[i * 3 + 1],
11595
+ z: parcel[i * 3 + 2],
11596
+ }))),
11597
+ color: 0x1f2937,
11598
+ });
11599
+ scene.add(parcelOutline);
11600
+ const dumbbellOutline = new Polyline({
11601
+ points: closedRingPoints(Array.from({ length: dumbbell.length / 3 }, (_, i) => ({
11602
+ x: dumbbell[i * 3],
11603
+ y: dumbbell[i * 3 + 1],
11604
+ z: dumbbell[i * 3 + 2],
11605
+ }))),
11606
+ color: 0x1f2937,
11607
+ });
11608
+ scene.add(dumbbellOutline);
11609
+ const envelopes = [];
11610
+ for (const region of offsetRingVariable(parcel, parcelSetbacks)) {
11611
+ const envelope = new Polyline({ points: closedRingPoints(region.outer), color: 0x16a34a });
11612
+ envelopes.push(envelope);
11613
+ scene.add(envelope);
11614
+ }
11615
+ for (const region of offsetRingVariable(dumbbell, dumbbellSetbacks)) {
11616
+ const envelope = new Polyline({ points: closedRingPoints(region.outer), color: 0xdc2626 });
11617
+ envelopes.push(envelope);
11618
+ scene.add(envelope);
11619
+ }
11620
+ return { parcelOutline, dumbbellOutline, envelopes };
11621
+ }
11622
+
10700
11623
  const EPSILON = 1.0e-9;
10701
11624
  function areClose(a, b) {
10702
11625
  const dx = a.x - b.x;
@@ -11209,5 +12132,5 @@ class OpenGeometry {
11209
12132
  OpenGeometry.version = OPEN_GEOMETRY_THREE_VERSION;
11210
12133
  OpenGeometry.instance = null;
11211
12134
 
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 };
12135
+ export { Arc, BooleanError, BooleanResult, CoincidentFacesError, Cuboid, Curve, CutterExceedsHostError, Cylinder, EllipticalArc, 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, createOffsetRingVariableExample, createParametricEditCapabilities, createPrimitivesExample, createShapesExample, createSweepExample, createWallFromOffsetsExample, describeWallSubtractError, executeBooleanSubtractionMany, extrudeBrepFace, offsetPolylineGroupRegions, offsetPolylineRegions, offsetRingVariable, parseBooleanError, toObjectTransformation$1 as toObjectTransformation };
11213
12136
  //# sourceMappingURL=index.js.map