opengeometry 2.0.6 → 2.0.8
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 +40 -14
- package/index.js +199 -57
- package/index.js.map +1 -1
- package/opengeometry/pkg/opengeometry.d.ts +228 -192
- package/opengeometry/pkg/opengeometry.js +100 -6
- package/opengeometry/pkg/opengeometry_bg.wasm +0 -0
- package/opengeometry/pkg/opengeometry_bg.wasm.d.ts +198 -192
- package/opengeometry_bg.wasm +0 -0
- package/opengeometry_bg.wasm.d.ts +198 -192
- package/package.json +1 -1
- package/src/base-types.d.ts +3 -0
- package/src/operations/boolean.d.ts +9 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<h1 align="center">OpenGeometry</h1>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
|
-
<strong>CAD kernel
|
|
10
|
+
<strong>Browser-native CAD kernel built with Rust, WebAssembly, and Three.js.</strong>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
|
|
31
31
|
## What is OpenGeometry?
|
|
32
32
|
|
|
33
|
-
OpenGeometry is an **open-source CAD kernel
|
|
33
|
+
OpenGeometry is an **open-source, browser-native CAD kernel**. The geometry engine is written in **Rust**, compiled to **WebAssembly**, and paired with a **Three.js-friendly TypeScript layer** so you can build real CAD tools that run in the browser.
|
|
34
34
|
|
|
35
|
-
OpenGeometry is best suited for **browser-based CAD, AEC/BIM, configurators, and geometry-heavy web tools**. Whether you're building a parametric modeler, a wall/opening workflow, a BIM viewer, or a custom Three.js modeling tool, OpenGeometry gives you kernel-backed primitives and operations without leaving JavaScript.
|
|
35
|
+
OpenGeometry is best suited for **browser-based CAD, AEC/BIM, configurators, and geometry-heavy web tools**. Whether you're building a parametric modeler, a wall/opening workflow, a BIM viewer, or a custom Three.js modeling tool, OpenGeometry gives you deterministic, kernel-backed primitives and operations without leaving JavaScript.
|
|
36
36
|
|
|
37
|
-
OpenPlans is
|
|
37
|
+
It is the geometry engine layer, not a full CAD application. OpenPlans is a downstream application/toolkit built on top of OpenGeometry for AEC workflows. In this repository, OpenGeometry is the primary SDK and engine.
|
|
38
38
|
|
|
39
39
|
## When to use OpenGeometry
|
|
40
40
|
|
|
@@ -45,15 +45,38 @@ Use OpenGeometry when you need:
|
|
|
45
45
|
- polygon extrusion into solids for CAD or AEC modeling
|
|
46
46
|
- IFC, STEP, STL, and PDF-style export/projection in web apps
|
|
47
47
|
- a Three.js-friendly CAD kernel instead of ad hoc mesh math
|
|
48
|
+
- a deterministic geometry engine behind AI-assisted CAD or design workflows
|
|
49
|
+
|
|
50
|
+
## Why it works well for AI-powered CAD apps
|
|
51
|
+
|
|
52
|
+
OpenGeometry is a good fit for **AI-assisted CAD apps** because the kernel layer stays explicit and deterministic. An AI copilot or agent can suggest modeling steps, generate profiles, or orchestrate edits, while OpenGeometry executes the actual geometry operations, booleans, projections, and exports in a predictable browser runtime.
|
|
53
|
+
|
|
54
|
+
Good examples include:
|
|
55
|
+
|
|
56
|
+
- AI copilots that translate user intent into concrete modeling operations
|
|
57
|
+
- prompt-to-geometry or agent-driven editing flows inside browser CAD tools
|
|
58
|
+
- AI-assisted design interfaces that still need reliable extrusion, boolean, projection, and export workflows
|
|
59
|
+
|
|
60
|
+
## Good fit / Not the right fit
|
|
61
|
+
|
|
62
|
+
**Good fit**
|
|
63
|
+
|
|
64
|
+
- browser CAD, AEC/BIM, and geometry-heavy web applications
|
|
65
|
+
- Three.js-based modeling tools that need a real kernel behind them
|
|
66
|
+
- AI-assisted CAD frontends that need deterministic geometry execution in the browser
|
|
67
|
+
|
|
68
|
+
**Not the default fit**
|
|
69
|
+
|
|
70
|
+
- desktop-native CAD products instead of an embeddable web SDK
|
|
71
|
+
- non-browser runtimes with no WebAssembly or browser delivery story
|
|
72
|
+
- pure visualization-only apps where raw Three.js is enough and kernel-backed modeling is unnecessary
|
|
48
73
|
|
|
49
74
|
## AI and Coding Agent Entrypoints
|
|
50
75
|
|
|
51
76
|
If you are using ChatGPT, Claude, Gemini, Copilot, or other coding agents on this repository, start here:
|
|
52
77
|
|
|
53
|
-
- [
|
|
54
|
-
- [
|
|
55
|
-
- [llm.txt](./llm.txt)
|
|
56
|
-
- [AGENTS.md](./AGENTS.md)
|
|
78
|
+
- [AGENTS.md](./AGENTS.md) - single source of truth for all coding agents (architecture, commands, gotchas, behavioral rules)
|
|
79
|
+
- [README.md](./README.md) - product overview, positioning, and quick start
|
|
57
80
|
- [Quickstart](https://docs.opengeometry.io/quickstart)
|
|
58
81
|
- [Three.js integration](https://docs.opengeometry.io/integration/threejs)
|
|
59
82
|
- [Boolean operations](https://docs.opengeometry.io/api/operations/boolean-operations)
|
|
@@ -66,7 +89,7 @@ If you are using ChatGPT, Claude, Gemini, Copilot, or other coding agents on thi
|
|
|
66
89
|
| **Primitives** | Lines, arcs, curves, polylines, rectangles |
|
|
67
90
|
| **Shapes** | Polygons, solids, cuboids, cylinders, spheres, wedges, sweeps, openings |
|
|
68
91
|
| **Operations** | Triangulation, extrusion, sweep, offset, boolean operations |
|
|
69
|
-
| **Exports** | STL, STEP, IFC, PDF projection |
|
|
92
|
+
| **Exports** | STL, STEP, IFC, PDF projection (PDF is currently native/Node-only — browser PDF is on the roadmap) |
|
|
70
93
|
| **Integration** | Three.js scene management, WebAssembly-powered performance |
|
|
71
94
|
|
|
72
95
|
## Demos
|
|
@@ -85,6 +108,8 @@ Install from npm:
|
|
|
85
108
|
npm install opengeometry
|
|
86
109
|
```
|
|
87
110
|
|
|
111
|
+
A practical browser deployment looks like this: install `opengeometry` from npm, serve `opengeometry_bg.wasm` from your app, then initialize the runtime once with `OpenGeometry.create({ wasmURL })` before creating `Vector3` values or kernel-backed wrappers.
|
|
112
|
+
|
|
88
113
|
```ts
|
|
89
114
|
import { Cuboid, OpenGeometry, Vector3 } from "opengeometry";
|
|
90
115
|
|
|
@@ -184,11 +209,12 @@ OpenGeometry is open source under the [MPL-2.0 license](./LICENSE.md). Contribut
|
|
|
184
209
|
|
|
185
210
|
## AI Agent Docs Policy
|
|
186
211
|
|
|
187
|
-
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
-
|
|
191
|
-
-
|
|
212
|
+
- All AI coding agent instructions live in a single file: [AGENTS.md](./AGENTS.md).
|
|
213
|
+
`CLAUDE.md` and `.github/copilot-instructions.md` are thin redirects to it.
|
|
214
|
+
- Stable architecture and domain notes are tracked in [`knowledge/`](./knowledge/).
|
|
215
|
+
- User-facing docs live in [`docs/`](./docs/) (Mintlify source).
|
|
216
|
+
- Agents should not create planning, handoff, or runbook files during a task. The
|
|
217
|
+
conversation, the diff, and the commit message are the handoff.
|
|
192
218
|
|
|
193
219
|
---
|
|
194
220
|
|
package/index.js
CHANGED
|
@@ -201,9 +201,6 @@ function extrudeBrepFace$1(local_brep_serialized, height) {
|
|
|
201
201
|
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
function isLikeNone(x) {
|
|
205
|
-
return x === undefined || x === null;
|
|
206
|
-
}
|
|
207
204
|
function getArrayJsValueFromWasm0(ptr, len) {
|
|
208
205
|
ptr = ptr >>> 0;
|
|
209
206
|
const mem = getDataViewMemory0();
|
|
@@ -214,6 +211,9 @@ function getArrayJsValueFromWasm0(ptr, len) {
|
|
|
214
211
|
wasm.__externref_drop_slice(ptr, len);
|
|
215
212
|
return result;
|
|
216
213
|
}
|
|
214
|
+
function isLikeNone(x) {
|
|
215
|
+
return x === undefined || x === null;
|
|
216
|
+
}
|
|
217
217
|
/**
|
|
218
218
|
* Wasm entry point for union.
|
|
219
219
|
* @param {string} lhs_brep_serialized
|
|
@@ -1666,6 +1666,99 @@ class OGCylinder {
|
|
|
1666
1666
|
return Vector3.__wrap(ret);
|
|
1667
1667
|
}
|
|
1668
1668
|
}
|
|
1669
|
+
const OGEntityRegistryFinalization = typeof FinalizationRegistry === 'undefined' ? {
|
|
1670
|
+
register: () => {},
|
|
1671
|
+
unregister: () => {}
|
|
1672
|
+
} : new FinalizationRegistry(ptr => wasm.__wbg_ogentityregistry_free(ptr >>> 0, 1));
|
|
1673
|
+
/**
|
|
1674
|
+
* Flat entity registry with a batched multi-view projection API.
|
|
1675
|
+
* Replaces the scene-centric OGSceneManager pattern for export use cases.
|
|
1676
|
+
*/
|
|
1677
|
+
class OGEntityRegistry {
|
|
1678
|
+
__destroy_into_raw() {
|
|
1679
|
+
const ptr = this.__wbg_ptr;
|
|
1680
|
+
this.__wbg_ptr = 0;
|
|
1681
|
+
OGEntityRegistryFinalization.unregister(this);
|
|
1682
|
+
return ptr;
|
|
1683
|
+
}
|
|
1684
|
+
free() {
|
|
1685
|
+
const ptr = this.__destroy_into_raw();
|
|
1686
|
+
wasm.__wbg_ogentityregistry_free(ptr, 0);
|
|
1687
|
+
}
|
|
1688
|
+
constructor() {
|
|
1689
|
+
const ret = wasm.ogentityregistry_new();
|
|
1690
|
+
this.__wbg_ptr = ret >>> 0;
|
|
1691
|
+
OGEntityRegistryFinalization.register(this, this.__wbg_ptr, this);
|
|
1692
|
+
return this;
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Register (or replace) an entity. `kind` must be an OGEntityKind string.
|
|
1696
|
+
* @param {string} id
|
|
1697
|
+
* @param {string} kind
|
|
1698
|
+
* @param {string} brep_json
|
|
1699
|
+
*/
|
|
1700
|
+
registerEntity(id, kind, brep_json) {
|
|
1701
|
+
const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1702
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1703
|
+
const ptr1 = passStringToWasm0(kind, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1704
|
+
const len1 = WASM_VECTOR_LEN;
|
|
1705
|
+
const ptr2 = passStringToWasm0(brep_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1706
|
+
const len2 = WASM_VECTOR_LEN;
|
|
1707
|
+
const ret = wasm.ogentityregistry_registerEntity(this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
|
|
1708
|
+
if (ret[1]) {
|
|
1709
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
/**
|
|
1713
|
+
* Remove a previously registered entity.
|
|
1714
|
+
* @param {string} id
|
|
1715
|
+
* @returns {boolean}
|
|
1716
|
+
*/
|
|
1717
|
+
unregisterEntity(id) {
|
|
1718
|
+
const ptr0 = passStringToWasm0(id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1719
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1720
|
+
const ret = wasm.ogentityregistry_unregisterEntity(this.__wbg_ptr, ptr0, len0);
|
|
1721
|
+
return ret !== 0;
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Remove all registered entities.
|
|
1725
|
+
*/
|
|
1726
|
+
clearEntities() {
|
|
1727
|
+
wasm.ogentityregistry_clearEntities(this.__wbg_ptr);
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Batched multi-view projection.
|
|
1731
|
+
*
|
|
1732
|
+
* Input: JSON array of `{ id, camera, hlr?, section_plane? }` (ViewRequest).
|
|
1733
|
+
* Output: JSON map of `{ viewportId: Scene2D }`.
|
|
1734
|
+
*
|
|
1735
|
+
* All viewports are projected in a single WASM call, amortising
|
|
1736
|
+
* serialisation overhead and keeping BRep data in WASM memory.
|
|
1737
|
+
* @param {string} views_json
|
|
1738
|
+
* @returns {string}
|
|
1739
|
+
*/
|
|
1740
|
+
projectCurrentToViews(views_json) {
|
|
1741
|
+
let deferred3_0;
|
|
1742
|
+
let deferred3_1;
|
|
1743
|
+
try {
|
|
1744
|
+
const ptr0 = passStringToWasm0(views_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1745
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1746
|
+
const ret = wasm.ogentityregistry_projectCurrentToViews(this.__wbg_ptr, ptr0, len0);
|
|
1747
|
+
var ptr2 = ret[0];
|
|
1748
|
+
var len2 = ret[1];
|
|
1749
|
+
if (ret[3]) {
|
|
1750
|
+
ptr2 = 0;
|
|
1751
|
+
len2 = 0;
|
|
1752
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
1753
|
+
}
|
|
1754
|
+
deferred3_0 = ptr2;
|
|
1755
|
+
deferred3_1 = len2;
|
|
1756
|
+
return getStringFromWasm0(ptr2, len2);
|
|
1757
|
+
} finally {
|
|
1758
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1669
1762
|
const OGFreeformEditorFinalization = typeof FinalizationRegistry === 'undefined' ? {
|
|
1670
1763
|
register: () => {},
|
|
1671
1764
|
unregister: () => {}
|
|
@@ -4996,7 +5089,7 @@ class OGSweep {
|
|
|
4996
5089
|
* @returns {Vector3}
|
|
4997
5090
|
*/
|
|
4998
5091
|
get_anchor() {
|
|
4999
|
-
const ret = wasm.
|
|
5092
|
+
const ret = wasm.ogsweep_get_anchor(this.__wbg_ptr);
|
|
5000
5093
|
return Vector3.__wrap(ret);
|
|
5001
5094
|
}
|
|
5002
5095
|
/**
|
|
@@ -5277,7 +5370,7 @@ class OGWedge {
|
|
|
5277
5370
|
* @returns {Vector3}
|
|
5278
5371
|
*/
|
|
5279
5372
|
get_anchor() {
|
|
5280
|
-
const ret = wasm.
|
|
5373
|
+
const ret = wasm.ogsweep_get_anchor(this.__wbg_ptr);
|
|
5281
5374
|
return Vector3.__wrap(ret);
|
|
5282
5375
|
}
|
|
5283
5376
|
}
|
|
@@ -5692,6 +5785,7 @@ var OGKernel = /*#__PURE__*/Object.freeze({
|
|
|
5692
5785
|
OGCuboid: OGCuboid,
|
|
5693
5786
|
OGCurve: OGCurve,
|
|
5694
5787
|
OGCylinder: OGCylinder,
|
|
5788
|
+
OGEntityRegistry: OGEntityRegistry,
|
|
5695
5789
|
OGFreeformEditor: OGFreeformEditor,
|
|
5696
5790
|
OGFreeformGeometry: OGFreeformGeometry,
|
|
5697
5791
|
OGIfcExportResult: OGIfcExportResult,
|
|
@@ -6250,7 +6344,6 @@ function createFreeformGeometry(source, options) {
|
|
|
6250
6344
|
return geometry;
|
|
6251
6345
|
}
|
|
6252
6346
|
|
|
6253
|
-
/* eslint-enable no-unused-vars */
|
|
6254
6347
|
/**
|
|
6255
6348
|
* Simple Line defined by Two Points
|
|
6256
6349
|
*/
|
|
@@ -6473,7 +6566,6 @@ class Line extends THREE.Line {
|
|
|
6473
6566
|
}
|
|
6474
6567
|
}
|
|
6475
6568
|
|
|
6476
|
-
/* eslint-enable no-unused-vars */
|
|
6477
6569
|
/**
|
|
6478
6570
|
* Polyline wrapper backed by the kernel OGPolyline primitive.
|
|
6479
6571
|
*/
|
|
@@ -6913,7 +7005,6 @@ class Arc extends THREE.Line {
|
|
|
6913
7005
|
}
|
|
6914
7006
|
}
|
|
6915
7007
|
|
|
6916
|
-
/* eslint-enable no-unused-vars */
|
|
6917
7008
|
/**
|
|
6918
7009
|
* Rectangle wrapper backed by the kernel OGRectangle primitive.
|
|
6919
7010
|
*/
|
|
@@ -7151,7 +7242,6 @@ class Rectangle extends THREE.Line {
|
|
|
7151
7242
|
}
|
|
7152
7243
|
}
|
|
7153
7244
|
|
|
7154
|
-
/* eslint-enable no-unused-vars */
|
|
7155
7245
|
/**
|
|
7156
7246
|
* Curve wrapper backed by the kernel OGCurve primitive.
|
|
7157
7247
|
*/
|
|
@@ -7427,15 +7517,14 @@ function serializeBrepLike$1(value) {
|
|
|
7427
7517
|
}
|
|
7428
7518
|
|
|
7429
7519
|
var _BooleanResult_outlineMesh;
|
|
7430
|
-
/* eslint-enable no-unused-vars */
|
|
7431
7520
|
const BOOLEAN_CREASE_ANGLE = Math.PI / 5;
|
|
7432
7521
|
const BOOLEAN_OUTLINE_THRESHOLD_DEGREES = 26;
|
|
7433
7522
|
/**
|
|
7434
7523
|
* Renderable result mesh returned by the kernel boolean helpers.
|
|
7435
7524
|
*/
|
|
7436
7525
|
class BooleanResult extends THREE.Mesh {
|
|
7437
|
-
constructor(kernelResult, options) {
|
|
7438
|
-
var _a, _b
|
|
7526
|
+
constructor(kernelResult, options, sourceMaterial = null) {
|
|
7527
|
+
var _a, _b;
|
|
7439
7528
|
super();
|
|
7440
7529
|
this.report = null;
|
|
7441
7530
|
this.brepSerialized = "";
|
|
@@ -7448,15 +7537,15 @@ class BooleanResult extends THREE.Mesh {
|
|
|
7448
7537
|
this.ogid = getUUID();
|
|
7449
7538
|
this._fatOutlines = (_a = options === null || options === void 0 ? void 0 : options.fatOutlines) !== null && _a !== void 0 ? _a : false;
|
|
7450
7539
|
this._outlineWidth = sanitizeOutlineWidth(options === null || options === void 0 ? void 0 : options.outlineWidth);
|
|
7451
|
-
this.applyKernelResult(kernelResult,
|
|
7452
|
-
if ((
|
|
7540
|
+
this.applyKernelResult(kernelResult, options, sourceMaterial);
|
|
7541
|
+
if ((_b = options === null || options === void 0 ? void 0 : options.outline) !== null && _b !== void 0 ? _b : false) {
|
|
7453
7542
|
this.outline = true;
|
|
7454
7543
|
}
|
|
7455
7544
|
}
|
|
7456
7545
|
/**
|
|
7457
7546
|
* Rebuilds the mesh, cached BRep payload, and outline geometry from the kernel output.
|
|
7458
7547
|
*/
|
|
7459
|
-
applyKernelResult(kernelResult,
|
|
7548
|
+
applyKernelResult(kernelResult, options, sourceMaterial = null) {
|
|
7460
7549
|
this.disposeGeometry();
|
|
7461
7550
|
this.brepSerialized = kernelResult.brepSerialized;
|
|
7462
7551
|
this.brepData = JSON.parse(kernelResult.brepSerialized);
|
|
@@ -7467,15 +7556,7 @@ class BooleanResult extends THREE.Mesh {
|
|
|
7467
7556
|
const geometry = toCreasedNormals(baseGeometry, BOOLEAN_CREASE_ANGLE);
|
|
7468
7557
|
geometry.computeBoundingBox();
|
|
7469
7558
|
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
|
-
});
|
|
7559
|
+
const material = buildResultMaterial(sourceMaterial, options);
|
|
7479
7560
|
this.geometry = geometry;
|
|
7480
7561
|
this.material = material;
|
|
7481
7562
|
if (this._outlineEnabled) {
|
|
@@ -7603,7 +7684,7 @@ function executeBooleanSubtractionMany(lhs, cutters, options) {
|
|
|
7603
7684
|
const kernelFunction = booleanExport;
|
|
7604
7685
|
const kernelOptions = serializeKernelOptions(options === null || options === void 0 ? void 0 : options.kernel);
|
|
7605
7686
|
const kernelResult = kernelFunction(resolveOperandSerialized(lhs), JSON.stringify(cutters.map(resolveOperandPayload)), kernelOptions);
|
|
7606
|
-
return createBooleanResult(kernelResult, options);
|
|
7687
|
+
return createBooleanResult(kernelResult, options, resolveOperandMaterial(lhs));
|
|
7607
7688
|
}
|
|
7608
7689
|
/**
|
|
7609
7690
|
* Normalizes mixed wrapper/raw operands, invokes the wasm boolean export, and
|
|
@@ -7617,7 +7698,7 @@ function executeBoolean(exportName, lhs, rhs, options) {
|
|
|
7617
7698
|
const kernelFunction = booleanExport;
|
|
7618
7699
|
const kernelOptions = serializeKernelOptions(options === null || options === void 0 ? void 0 : options.kernel);
|
|
7619
7700
|
const kernelResult = kernelFunction(resolveOperandSerialized(lhs), resolveOperandSerialized(rhs), kernelOptions);
|
|
7620
|
-
return createBooleanResult(kernelResult, options);
|
|
7701
|
+
return createBooleanResult(kernelResult, options, resolveOperandMaterial(lhs));
|
|
7621
7702
|
}
|
|
7622
7703
|
/**
|
|
7623
7704
|
* Accepts wrapper objects, raw BRep data, or serialized JSON and normalizes
|
|
@@ -7673,14 +7754,69 @@ function serializeKernelOptions(options) {
|
|
|
7673
7754
|
merge_coplanar_faces: options.mergeCoplanarFaces,
|
|
7674
7755
|
});
|
|
7675
7756
|
}
|
|
7676
|
-
function createBooleanResult(kernelResult, options) {
|
|
7757
|
+
function createBooleanResult(kernelResult, options, sourceMaterial = null) {
|
|
7677
7758
|
var _a;
|
|
7678
|
-
const result = new BooleanResult(kernelResult, options);
|
|
7759
|
+
const result = new BooleanResult(kernelResult, options, sourceMaterial);
|
|
7679
7760
|
if ((_a = options === null || options === void 0 ? void 0 : options.outline) !== null && _a !== void 0 ? _a : true) {
|
|
7680
7761
|
result.outline = true;
|
|
7681
7762
|
}
|
|
7682
7763
|
return result;
|
|
7683
7764
|
}
|
|
7765
|
+
/**
|
|
7766
|
+
* Returns a clonable `THREE.Material` from the operand when it is a Three mesh
|
|
7767
|
+
* subclass (Solid, Polygon, Cuboid, Opening, BooleanResult, etc.). Returns
|
|
7768
|
+
* `null` for serialized JSON, parsed BRep objects, or anything else without a
|
|
7769
|
+
* reachable material so the boolean result can fall back to the legacy default.
|
|
7770
|
+
*/
|
|
7771
|
+
function resolveOperandMaterial(operand) {
|
|
7772
|
+
var _a;
|
|
7773
|
+
if (typeof operand !== "object" || operand === null) {
|
|
7774
|
+
return null;
|
|
7775
|
+
}
|
|
7776
|
+
if (!(operand instanceof THREE.Mesh)) {
|
|
7777
|
+
return null;
|
|
7778
|
+
}
|
|
7779
|
+
const material = operand.material;
|
|
7780
|
+
if (Array.isArray(material)) {
|
|
7781
|
+
return (_a = material[0]) !== null && _a !== void 0 ? _a : null;
|
|
7782
|
+
}
|
|
7783
|
+
return material instanceof THREE.Material ? material : null;
|
|
7784
|
+
}
|
|
7785
|
+
/**
|
|
7786
|
+
* Builds the boolean result mesh's material by cloning the host (LHS) material
|
|
7787
|
+
* when available so the result inherits the host's color, transparency, and
|
|
7788
|
+
* side mode. Caller-provided overrides on `BooleanRenderOptions` win, and the
|
|
7789
|
+
* polygon-offset settings that prevent z-fighting with the result outline are
|
|
7790
|
+
* always reapplied after cloning.
|
|
7791
|
+
*/
|
|
7792
|
+
function buildResultMaterial(sourceMaterial, options) {
|
|
7793
|
+
const material = sourceMaterial
|
|
7794
|
+
? sourceMaterial.clone()
|
|
7795
|
+
: new THREE.MeshStandardMaterial({
|
|
7796
|
+
color: 0x2563eb,
|
|
7797
|
+
transparent: true,
|
|
7798
|
+
opacity: 0.82,
|
|
7799
|
+
side: THREE.FrontSide,
|
|
7800
|
+
});
|
|
7801
|
+
if ((options === null || options === void 0 ? void 0 : options.color) !== undefined && "color" in material) {
|
|
7802
|
+
material.color.set(options.color);
|
|
7803
|
+
}
|
|
7804
|
+
if ((options === null || options === void 0 ? void 0 : options.opacity) !== undefined) {
|
|
7805
|
+
material.opacity = options.opacity;
|
|
7806
|
+
material.transparent = options.opacity < 1 || material.transparent;
|
|
7807
|
+
}
|
|
7808
|
+
if ((options === null || options === void 0 ? void 0 : options.transparent) !== undefined) {
|
|
7809
|
+
material.transparent = options.transparent;
|
|
7810
|
+
}
|
|
7811
|
+
if ((options === null || options === void 0 ? void 0 : options.side) !== undefined) {
|
|
7812
|
+
material.side = options.side;
|
|
7813
|
+
}
|
|
7814
|
+
material.polygonOffset = true;
|
|
7815
|
+
material.polygonOffsetFactor = 1;
|
|
7816
|
+
material.polygonOffsetUnits = 1;
|
|
7817
|
+
material.needsUpdate = true;
|
|
7818
|
+
return material;
|
|
7819
|
+
}
|
|
7684
7820
|
/**
|
|
7685
7821
|
* Builds a display-quality outline buffer from the rendered mesh and falls back
|
|
7686
7822
|
* to the kernel-provided edges when the client-side extraction is empty.
|
|
@@ -7858,10 +7994,9 @@ class Solid extends THREE.Mesh {
|
|
|
7858
7994
|
var _a;
|
|
7859
7995
|
const bufferData = this.solid.getGeometryBuffer();
|
|
7860
7996
|
this.writePositionsToGeometry(this.geometry, bufferData);
|
|
7997
|
+
let material;
|
|
7861
7998
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
7862
|
-
this.material
|
|
7863
|
-
this.material.transparent = true;
|
|
7864
|
-
this.material.opacity = 0.6;
|
|
7999
|
+
material = this.material;
|
|
7865
8000
|
}
|
|
7866
8001
|
else {
|
|
7867
8002
|
if (Array.isArray(this.material)) {
|
|
@@ -7870,12 +8005,21 @@ class Solid extends THREE.Mesh {
|
|
|
7870
8005
|
else {
|
|
7871
8006
|
this.material.dispose();
|
|
7872
8007
|
}
|
|
7873
|
-
|
|
8008
|
+
material = new THREE.MeshStandardMaterial({
|
|
7874
8009
|
color: this.options.color,
|
|
7875
|
-
transparent:
|
|
7876
|
-
opacity:
|
|
8010
|
+
transparent: false,
|
|
8011
|
+
opacity: 1,
|
|
8012
|
+
depthWrite: true,
|
|
8013
|
+
side: THREE.FrontSide,
|
|
7877
8014
|
});
|
|
7878
|
-
|
|
8015
|
+
this.material = material;
|
|
8016
|
+
}
|
|
8017
|
+
material.color.set(this.options.color);
|
|
8018
|
+
material.transparent = false;
|
|
8019
|
+
material.opacity = 1;
|
|
8020
|
+
material.depthWrite = true;
|
|
8021
|
+
material.side = THREE.FrontSide;
|
|
8022
|
+
material.needsUpdate = true;
|
|
7879
8023
|
if (bufferData.length > 0) {
|
|
7880
8024
|
this.geometry.computeVertexNormals();
|
|
7881
8025
|
this.geometry.computeBoundingBox();
|
|
@@ -8486,8 +8630,8 @@ class Cylinder extends THREE.Mesh {
|
|
|
8486
8630
|
this.writePositionsToGeometry(this.geometry, bufferData);
|
|
8487
8631
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
8488
8632
|
this.material.color.set(this.options.color);
|
|
8489
|
-
this.material.transparent = true;
|
|
8490
|
-
this.material.opacity = 0.6;
|
|
8633
|
+
// this.material.transparent = true;
|
|
8634
|
+
// this.material.opacity = 0.6;
|
|
8491
8635
|
}
|
|
8492
8636
|
else {
|
|
8493
8637
|
if (Array.isArray(this.material)) {
|
|
@@ -8498,8 +8642,8 @@ class Cylinder extends THREE.Mesh {
|
|
|
8498
8642
|
}
|
|
8499
8643
|
this.material = new THREE.MeshStandardMaterial({
|
|
8500
8644
|
color: this.options.color,
|
|
8501
|
-
transparent: true,
|
|
8502
|
-
opacity: 0.6,
|
|
8645
|
+
// transparent: true,
|
|
8646
|
+
// opacity: 0.6,
|
|
8503
8647
|
});
|
|
8504
8648
|
}
|
|
8505
8649
|
this.geometry.computeVertexNormals();
|
|
@@ -8697,8 +8841,8 @@ class Cuboid extends THREE.Mesh {
|
|
|
8697
8841
|
this.writePositionsToGeometry(this.geometry, geometryData);
|
|
8698
8842
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
8699
8843
|
this.material.color.set(this.options.color);
|
|
8700
|
-
this.material.transparent = true;
|
|
8701
|
-
this.material.opacity = 0.6;
|
|
8844
|
+
// this.material.transparent = true;
|
|
8845
|
+
// this.material.opacity = 0.6;
|
|
8702
8846
|
}
|
|
8703
8847
|
else {
|
|
8704
8848
|
if (Array.isArray(this.material)) {
|
|
@@ -8709,8 +8853,8 @@ class Cuboid extends THREE.Mesh {
|
|
|
8709
8853
|
}
|
|
8710
8854
|
this.material = new THREE.MeshStandardMaterial({
|
|
8711
8855
|
color: this.options.color,
|
|
8712
|
-
transparent: true,
|
|
8713
|
-
opacity: 0.6,
|
|
8856
|
+
// transparent: true,
|
|
8857
|
+
// opacity: 0.6,
|
|
8714
8858
|
});
|
|
8715
8859
|
}
|
|
8716
8860
|
this.geometry.computeVertexNormals();
|
|
@@ -9151,7 +9295,6 @@ class Opening extends THREE.Mesh {
|
|
|
9151
9295
|
_Opening_outlineMesh = new WeakMap();
|
|
9152
9296
|
|
|
9153
9297
|
var _Sphere_outlineMesh;
|
|
9154
|
-
/* eslint-enable no-unused-vars */
|
|
9155
9298
|
/**
|
|
9156
9299
|
* Sphere wrapper backed by the kernel sphere primitive.
|
|
9157
9300
|
*/
|
|
@@ -9310,8 +9453,8 @@ class Sphere extends THREE.Mesh {
|
|
|
9310
9453
|
this.writePositionsToGeometry(this.geometry, bufferData);
|
|
9311
9454
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
9312
9455
|
this.material.color.set(this.options.color);
|
|
9313
|
-
this.material.transparent = true;
|
|
9314
|
-
this.material.opacity = 0.6;
|
|
9456
|
+
// this.material.transparent = true;
|
|
9457
|
+
// this.material.opacity = 0.6;
|
|
9315
9458
|
}
|
|
9316
9459
|
else {
|
|
9317
9460
|
if (Array.isArray(this.material)) {
|
|
@@ -9322,8 +9465,8 @@ class Sphere extends THREE.Mesh {
|
|
|
9322
9465
|
}
|
|
9323
9466
|
this.material = new THREE.MeshStandardMaterial({
|
|
9324
9467
|
color: this.options.color,
|
|
9325
|
-
transparent: true,
|
|
9326
|
-
opacity: 0.6,
|
|
9468
|
+
// transparent: true,
|
|
9469
|
+
// opacity: 0.6,
|
|
9327
9470
|
});
|
|
9328
9471
|
}
|
|
9329
9472
|
this.geometry.computeVertexNormals();
|
|
@@ -9578,8 +9721,8 @@ class Wedge extends THREE.Mesh {
|
|
|
9578
9721
|
this.writePositionsToGeometry(this.geometry, bufferData);
|
|
9579
9722
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
9580
9723
|
this.material.color.set(this.options.color);
|
|
9581
|
-
this.material.transparent = true;
|
|
9582
|
-
this.material.opacity = 0.6;
|
|
9724
|
+
// this.material.transparent = true;
|
|
9725
|
+
// this.material.opacity = 0.6;
|
|
9583
9726
|
}
|
|
9584
9727
|
else {
|
|
9585
9728
|
if (Array.isArray(this.material)) {
|
|
@@ -9590,8 +9733,8 @@ class Wedge extends THREE.Mesh {
|
|
|
9590
9733
|
}
|
|
9591
9734
|
this.material = new THREE.MeshStandardMaterial({
|
|
9592
9735
|
color: this.options.color,
|
|
9593
|
-
transparent: true,
|
|
9594
|
-
opacity: 0.6,
|
|
9736
|
+
// transparent: true,
|
|
9737
|
+
// opacity: 0.6,
|
|
9595
9738
|
});
|
|
9596
9739
|
}
|
|
9597
9740
|
this.geometry.computeVertexNormals();
|
|
@@ -9696,7 +9839,6 @@ class Wedge extends THREE.Mesh {
|
|
|
9696
9839
|
_Wedge_outlineMesh = new WeakMap();
|
|
9697
9840
|
|
|
9698
9841
|
var _Sweep_outlineMesh;
|
|
9699
|
-
/* eslint-enable no-unused-vars */
|
|
9700
9842
|
/**
|
|
9701
9843
|
* Sweep wrapper backed by the kernel sweep primitive.
|
|
9702
9844
|
*/
|
|
@@ -9877,8 +10019,8 @@ class Sweep extends THREE.Mesh {
|
|
|
9877
10019
|
this.writePositionsToGeometry(this.geometry, bufferData);
|
|
9878
10020
|
if (this.material instanceof THREE.MeshStandardMaterial) {
|
|
9879
10021
|
this.material.color.set(this.options.color);
|
|
9880
|
-
this.material.transparent = true;
|
|
9881
|
-
this.material.opacity = 0.6;
|
|
10022
|
+
// this.material.transparent = true;
|
|
10023
|
+
// this.material.opacity = 0.6;
|
|
9882
10024
|
}
|
|
9883
10025
|
else {
|
|
9884
10026
|
if (Array.isArray(this.material)) {
|
|
@@ -9889,8 +10031,8 @@ class Sweep extends THREE.Mesh {
|
|
|
9889
10031
|
}
|
|
9890
10032
|
this.material = new THREE.MeshStandardMaterial({
|
|
9891
10033
|
color: this.options.color,
|
|
9892
|
-
transparent: true,
|
|
9893
|
-
opacity: 0.6,
|
|
10034
|
+
// transparent: true,
|
|
10035
|
+
// opacity: 0.6,
|
|
9894
10036
|
});
|
|
9895
10037
|
}
|
|
9896
10038
|
this.geometry.computeVertexNormals();
|