@jgphilpott/polytree 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -56
- package/package.json +1 -1
- package/polytree.bundle.browser.js +507 -44
- package/polytree.bundle.browser.min.js +1 -1
- package/polytree.bundle.js +553 -44
- package/polytree.bundle.min.js +1 -1
package/README.md
CHANGED
|
@@ -6,21 +6,49 @@
|
|
|
6
6
|
|
|
7
7
|
<details open>
|
|
8
8
|
|
|
9
|
-
<summary><h2 style="display:inline">Intro</h2></summary
|
|
9
|
+
<summary><h2 style="display:inline">Intro</h2></summary>
|
|
10
10
|
|
|
11
|
-
**Polytree** is a modern, high-performance Constructive Solid Geometry (CSG) library for JavaScript and Node.js
|
|
11
|
+
**Polytree** is a modern, high-performance spatial querying and Constructive Solid Geometry (CSG) library for JavaScript and Node.js Built on an efficient [Octree data structure](https://en.wikipedia.org/wiki/Octree), it is designed for advanced 3D modeling, mesh analysis, geometric search, and seamless integration with [three.js](https://github.com/mrdoob/three.js).
|
|
12
|
+
|
|
13
|
+
Polytree goes beyond traditional CSG libraries by providing a comprehensive suite of spatial query functions—such as closest point, distance field, intersection testing, layer slicing, and volume analysis—making it ideal for 3D printing, CAD, simulation, and mesh analysis applications.
|
|
14
|
+
|
|
15
|
+
**▶️ [View the Polytree Demo Site with GitHub Pages](https://jgphilpott.github.io/polytree)**
|
|
16
|
+
|
|
17
|
+
**📦 [View the Polytree npm Package](https://www.npmjs.com/package/@jgphilpott/polytree)**
|
|
12
18
|
|
|
13
19
|
### Features
|
|
14
20
|
|
|
21
|
+
- **Advanced Spatial Queries**: Closest point search, distance calculations, intersection testing, layer slicing, and volume analysis—optimized for mesh analysis, 3D printing, and simulation workflows.
|
|
15
22
|
- **Complete CSG Operations**: Union, subtraction, and intersection with full test coverage.
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
23
|
+
- **3D Printing & CAD Support**: Layer slicing, cross-section analysis, and spatial operations for manufacturing and design applications.
|
|
24
|
+
- **High Performance**: Octree-based spatial partitioning for fast queries and operations on large meshes.
|
|
25
|
+
- **Dual API**: Both synchronous and asynchronous operation modes for flexible integration.
|
|
26
|
+
- **Multi-Input Support**: Works directly with Three.js meshes, BufferGeometry, and Polytree instances.
|
|
18
27
|
- **Lightweight**: Minimal dependencies with efficient memory usage.
|
|
19
|
-
- **Three.js Integration**: Direct mesh-to-mesh operations with material preservation.
|
|
20
|
-
- **Well Documented**: Comprehensive API documentation and examples.
|
|
21
|
-
- **Robust Testing**:
|
|
28
|
+
- **Three.js Integration**: Direct mesh-to-mesh operations and spatial queries with material preservation.
|
|
29
|
+
- **Well Documented**: Comprehensive API documentation and interactive examples.
|
|
30
|
+
- **Robust Testing**: 490+ tests ensuring reliability across edge cases.
|
|
31
|
+
|
|
32
|
+
</details>
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
<details open>
|
|
35
|
+
|
|
36
|
+
<summary><h2 style="display:inline">Table of Contents</h2></summary>
|
|
37
|
+
|
|
38
|
+
- [Intro](#intro)
|
|
39
|
+
- [Getting Started](#getting-started)
|
|
40
|
+
- [Usage](#usage)
|
|
41
|
+
- [Utility Functions](#utility-functions)
|
|
42
|
+
- [Basic CSG Operations](#basic-csg-operations)
|
|
43
|
+
- [Async CSG Operations](#async-csg-operations)
|
|
44
|
+
- [Async Array Operations](#async-array-operations)
|
|
45
|
+
- [Spatial Query Functions](#spatial-query-functions)
|
|
46
|
+
- [Advanced Polytree-to-Polytree Operations](#advanced-polytree-to-polytree-operations)
|
|
47
|
+
- [Performance](#performance)
|
|
48
|
+
- [Applications](#applications)
|
|
49
|
+
- [Contributing](#contributing)
|
|
50
|
+
|
|
51
|
+
</details>
|
|
24
52
|
|
|
25
53
|
<details open>
|
|
26
54
|
|
|
@@ -63,15 +91,76 @@ import Polytree from 'polytree';
|
|
|
63
91
|
|
|
64
92
|
The browser bundle (`polytree.bundle.browser.js`) is specifically designed for ES module imports in browsers, while the main bundle (`polytree.bundle.js`) is for Node.js environments.
|
|
65
93
|
|
|
66
|
-
</details
|
|
94
|
+
</details>
|
|
67
95
|
|
|
68
96
|
<details open>
|
|
69
97
|
|
|
70
|
-
<summary><h2 style="display:inline">Usage</h2></summary
|
|
98
|
+
<summary><h2 style="display:inline">Usage</h2></summary>
|
|
71
99
|
|
|
72
100
|
<details open>
|
|
73
101
|
|
|
74
|
-
<summary><h3 style="display:inline">
|
|
102
|
+
<summary><h3 style="display:inline">Utility Functions</h3></summary>
|
|
103
|
+
|
|
104
|
+
Polytree provides utility functions for geometry analysis and calculations:
|
|
105
|
+
|
|
106
|
+
#### Surface Area Calculation
|
|
107
|
+
|
|
108
|
+
Calculate the surface area of Three.js meshes or geometries:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
// Calculate surface area from a mesh:
|
|
112
|
+
const boxGeometry = new THREE.BoxGeometry(2, 3, 4);
|
|
113
|
+
const boxMesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial());
|
|
114
|
+
const surfaceArea = Polytree.getSurface(boxMesh);
|
|
115
|
+
|
|
116
|
+
console.log(`Surface area: ${surfaceArea}`); // Output: 52
|
|
117
|
+
|
|
118
|
+
// Calculate surface area directly from geometry:
|
|
119
|
+
const sphereGeometry = new THREE.SphereGeometry(1);
|
|
120
|
+
const sphereSurfaceArea = Polytree.getSurface(sphereGeometry);
|
|
121
|
+
|
|
122
|
+
console.log(`Sphere surface area: ${sphereSurfaceArea}`); // Output: ~12.47
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The `getSurface()` method:
|
|
126
|
+
|
|
127
|
+
- Accepts either Three.js `Mesh` objects or `BufferGeometry` objects.
|
|
128
|
+
- Returns the total surface area as a number.
|
|
129
|
+
- Works by summing the areas of all triangular faces.
|
|
130
|
+
- Handles both indexed and non-indexed geometries.
|
|
131
|
+
|
|
132
|
+
#### Volume Calculation
|
|
133
|
+
|
|
134
|
+
Calculate the volume of Three.js meshes or geometries:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
// Calculate volume from a mesh:
|
|
138
|
+
const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
|
|
139
|
+
const boxMesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial());
|
|
140
|
+
const volume = Polytree.getVolume(boxMesh);
|
|
141
|
+
|
|
142
|
+
console.log(`Volume: ${volume}`); // Output: 8
|
|
143
|
+
|
|
144
|
+
// Calculate volume directly from geometry:
|
|
145
|
+
const sphereGeometry = new THREE.SphereGeometry(1);
|
|
146
|
+
const sphereVolume = Polytree.getVolume(sphereGeometry);
|
|
147
|
+
|
|
148
|
+
console.log(`Sphere volume: ${sphereVolume}`); // Output: ~4.19 (approx 4/3 * π)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The `getVolume()` method:
|
|
152
|
+
|
|
153
|
+
- Accepts either Three.js `Mesh` objects or `BufferGeometry` objects.
|
|
154
|
+
- Returns the total volume as a number.
|
|
155
|
+
- Uses the divergence theorem with signed tetrahedron volumes.
|
|
156
|
+
- Handles both indexed and non-indexed geometries.
|
|
157
|
+
- Automatically handles edge cases like empty geometries.
|
|
158
|
+
|
|
159
|
+
</details>
|
|
160
|
+
|
|
161
|
+
<details open>
|
|
162
|
+
|
|
163
|
+
<summary><h3 style="display:inline">Basic CSG Operations</h3></summary>
|
|
75
164
|
|
|
76
165
|
Polytree provides three core CSG operations that work directly with Three.js meshes:
|
|
77
166
|
|
|
@@ -139,11 +228,11 @@ const result = await Polytree.intersect(sphere1, sphere2);
|
|
|
139
228
|
scene.add(result);
|
|
140
229
|
```
|
|
141
230
|
|
|
142
|
-
</details
|
|
231
|
+
</details>
|
|
143
232
|
|
|
144
233
|
<details>
|
|
145
234
|
|
|
146
|
-
<summary><h3 style="display:inline">
|
|
235
|
+
<summary><h3 style="display:inline">Async CSG Operations</h3></summary>
|
|
147
236
|
|
|
148
237
|
For better performance in web applications, use async operations to prevent UI blocking:
|
|
149
238
|
|
|
@@ -159,11 +248,146 @@ const unionResult = await Polytree.unite(mesh1, mesh2);
|
|
|
159
248
|
scene.add(unionResult);
|
|
160
249
|
```
|
|
161
250
|
|
|
162
|
-
</details
|
|
251
|
+
</details>
|
|
163
252
|
|
|
164
253
|
<details>
|
|
165
254
|
|
|
166
|
-
<summary><h3 style="display:inline">
|
|
255
|
+
<summary><h3 style="display:inline">Async Array Operations</h3></summary>
|
|
256
|
+
|
|
257
|
+
Process multiple objects efficiently:
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
// Unite multiple objects asynchronously.
|
|
261
|
+
const meshArray = [mesh1, mesh2, mesh3, mesh4 ... meshX];
|
|
262
|
+
const polytreeArray = meshArray.map(mesh => Polytree.fromMesh(mesh));
|
|
263
|
+
|
|
264
|
+
Polytree.async.uniteArray(polytreeArray).then(result => {
|
|
265
|
+
|
|
266
|
+
const finalMesh = Polytree.toMesh(result);
|
|
267
|
+
scene.add(finalMesh);
|
|
268
|
+
|
|
269
|
+
// Clean up.
|
|
270
|
+
polytreeArray.forEach(polytree => {
|
|
271
|
+
polytree.delete()
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
result.delete();
|
|
275
|
+
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
</details>
|
|
280
|
+
|
|
281
|
+
<details open>
|
|
282
|
+
|
|
283
|
+
<summary><h3 style="display:inline">Spatial Query Functions</h3></summary>
|
|
284
|
+
|
|
285
|
+
Polytree now includes advanced spatial query capabilities inspired by the `three-mesh-bvh` library, transforming it from a pure CSG library into a comprehensive spatial querying tool optimized for 3D printing applications.
|
|
286
|
+
|
|
287
|
+
#### Point-based Queries
|
|
288
|
+
|
|
289
|
+
Find the closest points and calculate distances for collision detection and mesh analysis:
|
|
290
|
+
|
|
291
|
+
```js
|
|
292
|
+
const geometry = new THREE.BoxGeometry(2, 2, 2);
|
|
293
|
+
const mesh = new THREE.Mesh(geometry, material);
|
|
294
|
+
const testPoint = new THREE.Vector3(5, 0, 0);
|
|
295
|
+
|
|
296
|
+
// Find closest point on surface - works with Mesh, BufferGeometry, or Polytree.
|
|
297
|
+
const closestPoint = Polytree.closestPointToPoint(mesh, testPoint);
|
|
298
|
+
console.log(`Closest point: (${closestPoint.x}, ${closestPoint.y}, ${closestPoint.z})`);
|
|
299
|
+
|
|
300
|
+
// Calculate distance to surface.
|
|
301
|
+
const distance = Polytree.distanceToPoint(mesh, testPoint);
|
|
302
|
+
console.log(`Distance: ${distance} units`);
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Volume Analysis
|
|
306
|
+
|
|
307
|
+
Perform both exact and statistical volume calculations:
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
// Exact volume calculation.
|
|
311
|
+
const exactVolume = Polytree.getVolume(mesh);
|
|
312
|
+
|
|
313
|
+
// Monte Carlo volume estimation for complex geometries.
|
|
314
|
+
const estimatedVolume = Polytree.estimateVolumeViaSampling(mesh, 50000);
|
|
315
|
+
console.log(`Exact: ${exactVolume}, Estimated: ${estimatedVolume}`);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### Intersection Testing
|
|
319
|
+
|
|
320
|
+
Test intersections with bounding volumes for collision detection:
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
// Test sphere intersection.
|
|
324
|
+
const sphere = new THREE.Sphere(new THREE.Vector3(0, 0, 0), 2);
|
|
325
|
+
const intersectsSphere = Polytree.intersectsSphere(mesh, sphere);
|
|
326
|
+
|
|
327
|
+
// Test bounding box intersection.
|
|
328
|
+
const box = new THREE.Box3(min, max);
|
|
329
|
+
const intersectsBox = Polytree.intersectsBox(mesh, box);
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### 3D Printing Layer Slicing
|
|
333
|
+
|
|
334
|
+
Generate layer slices for 3D printing applications:
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
// Slice geometry into horizontal layers.
|
|
338
|
+
const layers = Polytree.sliceIntoLayers(
|
|
339
|
+
mesh, // Input geometry
|
|
340
|
+
0.2, // Layer height (0.2mm)
|
|
341
|
+
-10, // Minimum Z
|
|
342
|
+
10, // Maximum Z
|
|
343
|
+
new THREE.Vector3(0, 0, 1) // Optional normal (default: Z-up)
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
console.log(`Generated ${layers.length} layers for 3D printing`);
|
|
347
|
+
|
|
348
|
+
// Single plane intersection for cross-section analysis.
|
|
349
|
+
const plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
|
350
|
+
const crossSection = Polytree.intersectPlane(mesh, plane);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### Advanced Spatial Operations
|
|
354
|
+
|
|
355
|
+
Custom spatial queries and triangle-based operations:
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
// Get triangles near a specific point.
|
|
359
|
+
const nearbyTriangles = Polytree.getTrianglesNearPoint(mesh, point, 2.0);
|
|
360
|
+
|
|
361
|
+
// Custom spatial query with callback.
|
|
362
|
+
const results = Polytree.shapecast(mesh, (triangle) => {
|
|
363
|
+
// Custom query logic - return true to collect triangle.
|
|
364
|
+
return triangle.normal.y > 0.8; // Find upward-facing triangles.
|
|
365
|
+
}, (triangle) => {
|
|
366
|
+
// Optional collection callback for processing results.
|
|
367
|
+
return { triangle, area: triangle.getArea() };
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
#### Multi-Input Support
|
|
372
|
+
|
|
373
|
+
All spatial query functions accept Three.js meshes, BufferGeometry, or Polytree instances:
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
const geometry = new THREE.BoxGeometry(2, 2, 2);
|
|
377
|
+
const mesh = new THREE.Mesh(geometry, material);
|
|
378
|
+
const polytree = Polytree.fromMesh(mesh);
|
|
379
|
+
|
|
380
|
+
// All of these work identically.
|
|
381
|
+
const result1 = Polytree.closestPointToPoint(mesh, testPoint); // Mesh
|
|
382
|
+
const result2 = Polytree.closestPointToPoint(geometry, testPoint); // BufferGeometry
|
|
383
|
+
const result3 = Polytree.closestPointToPoint(polytree, testPoint); // Polytree
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
</details>
|
|
387
|
+
|
|
388
|
+
<details>
|
|
389
|
+
|
|
390
|
+
<summary><h3 style="display:inline">Advanced Polytree-to-Polytree Operations</h3></summary>
|
|
167
391
|
|
|
168
392
|
For maximum performance when chaining operations, work directly with Polytree objects:
|
|
169
393
|
|
|
@@ -190,68 +414,44 @@ intermediate.delete();
|
|
|
190
414
|
final.delete();
|
|
191
415
|
```
|
|
192
416
|
|
|
193
|
-
</details><br>
|
|
194
|
-
|
|
195
|
-
<details>
|
|
196
|
-
|
|
197
|
-
<summary><h3 style="display:inline">Async Array Operations</h3></summary><br>
|
|
198
|
-
|
|
199
|
-
Process multiple objects efficiently:
|
|
200
|
-
|
|
201
|
-
```js
|
|
202
|
-
// Unite multiple objects asynchronously.
|
|
203
|
-
const meshArray = [mesh1, mesh2, mesh3, mesh4 ... meshX];
|
|
204
|
-
const polytreeArray = meshArray.map(mesh => Polytree.fromMesh(mesh));
|
|
205
|
-
|
|
206
|
-
Polytree.async.uniteArray(polytreeArray).then(result => {
|
|
207
|
-
|
|
208
|
-
const finalMesh = Polytree.toMesh(result);
|
|
209
|
-
scene.add(finalMesh);
|
|
210
|
-
|
|
211
|
-
// Clean up.
|
|
212
|
-
polytreeArray.forEach(polytree => {
|
|
213
|
-
polytree.delete()
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
result.delete();
|
|
217
|
-
|
|
218
|
-
});
|
|
219
|
-
```
|
|
220
|
-
|
|
221
417
|
</details>
|
|
222
418
|
|
|
223
|
-
</details
|
|
419
|
+
</details>
|
|
224
420
|
|
|
225
421
|
<details open>
|
|
226
422
|
|
|
227
|
-
<summary><h2 style="display:inline">Performance</h2></summary
|
|
423
|
+
<summary><h2 style="display:inline">Performance</h2></summary>
|
|
228
424
|
|
|
229
425
|
Polytree is designed for high-performance CSG operations:
|
|
230
426
|
|
|
231
|
-
- **Octree Optimization**: Spatial partitioning reduces computational complexity.
|
|
232
|
-
- **Memory Efficient**: Smart resource management with cleanup methods.
|
|
233
|
-
- **
|
|
427
|
+
- **Octree Optimization**: Spatial partitioning reduces computational complexity for both CSG and spatial query operations.
|
|
428
|
+
- **Memory Efficient**: Smart resource management with cleanup methods and automatic temporary object disposal.
|
|
429
|
+
- **Unified Architecture**: CSG operations + spatial queries in one optimized library, eliminating the need for multiple tools.
|
|
430
|
+
- **Multi-Input Support**: Functions work directly with Three.js meshes, geometries, and Polytree instances without manual conversion.
|
|
431
|
+
- **Comprehensive Testing**: 490+ test cases ensuring reliability and performance across all operations.
|
|
234
432
|
- **Async Support**: Non-blocking operations for smooth user experiences.
|
|
235
433
|
- **Minimal Dependencies**: Only Three.js as a dependency for lightweight integration.
|
|
236
434
|
|
|
237
|
-
</details
|
|
435
|
+
</details>
|
|
238
436
|
|
|
239
437
|
<details open>
|
|
240
438
|
|
|
241
|
-
<summary><h2 style="display:inline">Applications</h2></summary
|
|
439
|
+
<summary><h2 style="display:inline">Applications</h2></summary>
|
|
242
440
|
|
|
243
441
|
- **3D Modeling**: Professional-grade boolean operations for CAD applications.
|
|
244
442
|
- **Game Development**: Runtime mesh manipulation and procedural geometry.
|
|
245
|
-
- **3D Printing**:
|
|
246
|
-
- **
|
|
247
|
-
- **
|
|
248
|
-
- **
|
|
443
|
+
- **3D Printing & Manufacturing**: Complete slicing pipeline with layer generation, support analysis, and volume calculations.
|
|
444
|
+
- **Collision Detection**: Fast spatial queries for physics engines and interactive applications.
|
|
445
|
+
- **Mesh Analysis & Repair**: Distance field calculations, closest point queries, and geometric validation.
|
|
446
|
+
- **Architectural Visualization**: Complex building geometry operations with spatial analysis.
|
|
447
|
+
- **Educational Tools**: Interactive 3D geometry learning applications with real-time feedback.
|
|
448
|
+
- **Integration with [Polyslice](https://github.com/jgphilpott/polyslice)**: Advanced FDM slicing workflows and manufacturing optimization.
|
|
249
449
|
|
|
250
|
-
</details
|
|
450
|
+
</details>
|
|
251
451
|
|
|
252
452
|
<details open>
|
|
253
453
|
|
|
254
|
-
<summary><h2 style="display:inline">Contributing</h2></summary
|
|
454
|
+
<summary><h2 style="display:inline">Contributing</h2></summary>
|
|
255
455
|
|
|
256
456
|
Contributions, issues, and feature requests are welcome! Please [open an issue](https://github.com/jgphilpott/polytree/issues) or submit a [pull request](https://github.com/jgphilpott/polytree/pulls).
|
|
257
457
|
|
package/package.json
CHANGED