Repository: mikolalysenko/isosurface
Branch: master
Commit: 22eba3c8c646
Files: 9
Total size: 28.0 KB
Directory structure:
gitextract_ac15jcwx/
├── .gitignore
├── LICENSE
├── README.md
├── index.js
├── lib/
│ ├── marchingcubes.js
│ ├── marchingtetrahedra.js
│ └── surfacenets.js
├── package.json
└── test/
└── sphere.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2013 Mikola Lysenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
isosurface
==========
Isosurface polygonizer algorithms in JavaScript. For more details, see the following blog posts:
* [What is a solid?](http://0fps.wordpress.com/2012/08/29/what-is-a-solid/)
* Smooth voxel terrain [Part 1](http://0fps.wordpress.com/2012/07/10/smooth-voxel-terrain-part-1/) [Part 2](http://0fps.wordpress.com/2012/07/12/smooth-voxel-terrain-part-2/)
[Or try out a live demo](http://mikolalysenko.github.com/Isosurface/)
# Example
```javascript
var isosurface = require("isosurface")
var mesh = isosurface.surfaceNets([64,64,64], function(x,y,z) {
return x*x + y*y + z*z - 100
}, [[-11,-11,-11], [11,11,11]])
console.log(mesh)
```
# Install
```
npm install isosurface
```
# API
```javascript
var isosurface = require("isosurface")
```
#### `isosurface.surfaceNets(dims, potential[, bounds])`
Extracts an isosurface from `potential` using surface nets with resolution given by `dims`.
Params:
* `dims`: A 3D vector of integers representing the resolution of the isosurface
* `potential(x,y,z)`: A scalar valued potential function taking 3 coordinates as arguments returning a scalar.
* `bounds`: A pair of 3D vectors `[lo, hi]` giving bounds on the potential to sample. If not specified, default is `[[0,0,0], dims]`.
Returns: A mesh object with the following members:
* `positions`: The coordinates of the vertices of the mesh
* `cells`: The faces of the mesh.
#### `isosurface..marchingCubes(dims, potential[, bounds])`
Same as above, except uses marching cubes instead of surface nets to extract the isosurface.
#### `isosurface.marchingTetrahedra(dims, potential[, bounds])`
Same as above, except uses marching tetrahedra instead of surface nets to extract the isosurface.
# Credits
(c) 2012-2014 Mikola Lysenko. MIT License
================================================
FILE: index.js
================================================
exports.surfaceNets = require("./lib/surfacenets.js").surfaceNets;
exports.marchingCubes = require("./lib/marchingcubes.js").marchingCubes;
exports.marchingTetrahedra = require("./lib/marchingtetrahedra.js").marchingTetrahedra;
================================================
FILE: lib/marchingcubes.js
================================================
/**
* Javascript Marching Cubes
*
* Based on Paul Bourke's classic implementation:
* http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
*
* JS port by Mikola Lysenko
*/
var edgeTable= new Uint32Array([
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ])
, triTable = [
[],
[0, 8, 3],
[0, 1, 9],
[1, 8, 3, 9, 8, 1],
[1, 2, 10],
[0, 8, 3, 1, 2, 10],
[9, 2, 10, 0, 2, 9],
[2, 8, 3, 2, 10, 8, 10, 9, 8],
[3, 11, 2],
[0, 11, 2, 8, 11, 0],
[1, 9, 0, 2, 3, 11],
[1, 11, 2, 1, 9, 11, 9, 8, 11],
[3, 10, 1, 11, 10, 3],
[0, 10, 1, 0, 8, 10, 8, 11, 10],
[3, 9, 0, 3, 11, 9, 11, 10, 9],
[9, 8, 10, 10, 8, 11],
[4, 7, 8],
[4, 3, 0, 7, 3, 4],
[0, 1, 9, 8, 4, 7],
[4, 1, 9, 4, 7, 1, 7, 3, 1],
[1, 2, 10, 8, 4, 7],
[3, 4, 7, 3, 0, 4, 1, 2, 10],
[9, 2, 10, 9, 0, 2, 8, 4, 7],
[2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4],
[8, 4, 7, 3, 11, 2],
[11, 4, 7, 11, 2, 4, 2, 0, 4],
[9, 0, 1, 8, 4, 7, 2, 3, 11],
[4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1],
[3, 10, 1, 3, 11, 10, 7, 8, 4],
[1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4],
[4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3],
[4, 7, 11, 4, 11, 9, 9, 11, 10],
[9, 5, 4],
[9, 5, 4, 0, 8, 3],
[0, 5, 4, 1, 5, 0],
[8, 5, 4, 8, 3, 5, 3, 1, 5],
[1, 2, 10, 9, 5, 4],
[3, 0, 8, 1, 2, 10, 4, 9, 5],
[5, 2, 10, 5, 4, 2, 4, 0, 2],
[2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8],
[9, 5, 4, 2, 3, 11],
[0, 11, 2, 0, 8, 11, 4, 9, 5],
[0, 5, 4, 0, 1, 5, 2, 3, 11],
[2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5],
[10, 3, 11, 10, 1, 3, 9, 5, 4],
[4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10],
[5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3],
[5, 4, 8, 5, 8, 10, 10, 8, 11],
[9, 7, 8, 5, 7, 9],
[9, 3, 0, 9, 5, 3, 5, 7, 3],
[0, 7, 8, 0, 1, 7, 1, 5, 7],
[1, 5, 3, 3, 5, 7],
[9, 7, 8, 9, 5, 7, 10, 1, 2],
[10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3],
[8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2],
[2, 10, 5, 2, 5, 3, 3, 5, 7],
[7, 9, 5, 7, 8, 9, 3, 11, 2],
[9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11],
[2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7],
[11, 2, 1, 11, 1, 7, 7, 1, 5],
[9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11],
[5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0],
[11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0],
[11, 10, 5, 7, 11, 5],
[10, 6, 5],
[0, 8, 3, 5, 10, 6],
[9, 0, 1, 5, 10, 6],
[1, 8, 3, 1, 9, 8, 5, 10, 6],
[1, 6, 5, 2, 6, 1],
[1, 6, 5, 1, 2, 6, 3, 0, 8],
[9, 6, 5, 9, 0, 6, 0, 2, 6],
[5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8],
[2, 3, 11, 10, 6, 5],
[11, 0, 8, 11, 2, 0, 10, 6, 5],
[0, 1, 9, 2, 3, 11, 5, 10, 6],
[5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11],
[6, 3, 11, 6, 5, 3, 5, 1, 3],
[0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6],
[3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9],
[6, 5, 9, 6, 9, 11, 11, 9, 8],
[5, 10, 6, 4, 7, 8],
[4, 3, 0, 4, 7, 3, 6, 5, 10],
[1, 9, 0, 5, 10, 6, 8, 4, 7],
[10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4],
[6, 1, 2, 6, 5, 1, 4, 7, 8],
[1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7],
[8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6],
[7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9],
[3, 11, 2, 7, 8, 4, 10, 6, 5],
[5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11],
[0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6],
[9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6],
[8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6],
[5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11],
[0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7],
[6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9],
[10, 4, 9, 6, 4, 10],
[4, 10, 6, 4, 9, 10, 0, 8, 3],
[10, 0, 1, 10, 6, 0, 6, 4, 0],
[8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10],
[1, 4, 9, 1, 2, 4, 2, 6, 4],
[3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4],
[0, 2, 4, 4, 2, 6],
[8, 3, 2, 8, 2, 4, 4, 2, 6],
[10, 4, 9, 10, 6, 4, 11, 2, 3],
[0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6],
[3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10],
[6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1],
[9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3],
[8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1],
[3, 11, 6, 3, 6, 0, 0, 6, 4],
[6, 4, 8, 11, 6, 8],
[7, 10, 6, 7, 8, 10, 8, 9, 10],
[0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10],
[10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0],
[10, 6, 7, 10, 7, 1, 1, 7, 3],
[1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7],
[2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9],
[7, 8, 0, 7, 0, 6, 6, 0, 2],
[7, 3, 2, 6, 7, 2],
[2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7],
[2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7],
[1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11],
[11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1],
[8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6],
[0, 9, 1, 11, 6, 7],
[7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0],
[7, 11, 6],
[7, 6, 11],
[3, 0, 8, 11, 7, 6],
[0, 1, 9, 11, 7, 6],
[8, 1, 9, 8, 3, 1, 11, 7, 6],
[10, 1, 2, 6, 11, 7],
[1, 2, 10, 3, 0, 8, 6, 11, 7],
[2, 9, 0, 2, 10, 9, 6, 11, 7],
[6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8],
[7, 2, 3, 6, 2, 7],
[7, 0, 8, 7, 6, 0, 6, 2, 0],
[2, 7, 6, 2, 3, 7, 0, 1, 9],
[1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6],
[10, 7, 6, 10, 1, 7, 1, 3, 7],
[10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8],
[0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7],
[7, 6, 10, 7, 10, 8, 8, 10, 9],
[6, 8, 4, 11, 8, 6],
[3, 6, 11, 3, 0, 6, 0, 4, 6],
[8, 6, 11, 8, 4, 6, 9, 0, 1],
[9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6],
[6, 8, 4, 6, 11, 8, 2, 10, 1],
[1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6],
[4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9],
[10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3],
[8, 2, 3, 8, 4, 2, 4, 6, 2],
[0, 4, 2, 4, 6, 2],
[1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8],
[1, 9, 4, 1, 4, 2, 2, 4, 6],
[8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1],
[10, 1, 0, 10, 0, 6, 6, 0, 4],
[4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3],
[10, 9, 4, 6, 10, 4],
[4, 9, 5, 7, 6, 11],
[0, 8, 3, 4, 9, 5, 11, 7, 6],
[5, 0, 1, 5, 4, 0, 7, 6, 11],
[11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5],
[9, 5, 4, 10, 1, 2, 7, 6, 11],
[6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5],
[7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2],
[3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6],
[7, 2, 3, 7, 6, 2, 5, 4, 9],
[9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7],
[3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0],
[6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8],
[9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7],
[1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4],
[4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10],
[7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10],
[6, 9, 5, 6, 11, 9, 11, 8, 9],
[3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5],
[0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11],
[6, 11, 3, 6, 3, 5, 5, 3, 1],
[1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6],
[0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10],
[11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5],
[6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3],
[5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2],
[9, 5, 6, 9, 6, 0, 0, 6, 2],
[1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8],
[1, 5, 6, 2, 1, 6],
[1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6],
[10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0],
[0, 3, 8, 5, 6, 10],
[10, 5, 6],
[11, 5, 10, 7, 5, 11],
[11, 5, 10, 11, 7, 5, 8, 3, 0],
[5, 11, 7, 5, 10, 11, 1, 9, 0],
[10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1],
[11, 1, 2, 11, 7, 1, 7, 5, 1],
[0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11],
[9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7],
[7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2],
[2, 5, 10, 2, 3, 5, 3, 7, 5],
[8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5],
[9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2],
[9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2],
[1, 3, 5, 3, 7, 5],
[0, 8, 7, 0, 7, 1, 1, 7, 5],
[9, 0, 3, 9, 3, 5, 5, 3, 7],
[9, 8, 7, 5, 9, 7],
[5, 8, 4, 5, 10, 8, 10, 11, 8],
[5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0],
[0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5],
[10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4],
[2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8],
[0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11],
[0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5],
[9, 4, 5, 2, 11, 3],
[2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4],
[5, 10, 2, 5, 2, 4, 4, 2, 0],
[3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9],
[5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2],
[8, 4, 5, 8, 5, 3, 3, 5, 1],
[0, 4, 5, 1, 0, 5],
[8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5],
[9, 4, 5],
[4, 11, 7, 4, 9, 11, 9, 10, 11],
[0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11],
[1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11],
[3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4],
[4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2],
[9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3],
[11, 7, 4, 11, 4, 2, 2, 4, 0],
[11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4],
[2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9],
[9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7],
[3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10],
[1, 10, 2, 8, 7, 4],
[4, 9, 1, 4, 1, 7, 7, 1, 3],
[4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1],
[4, 0, 3, 7, 4, 3],
[4, 8, 7],
[9, 10, 8, 10, 11, 8],
[3, 0, 9, 3, 9, 11, 11, 9, 10],
[0, 1, 10, 0, 10, 8, 8, 10, 11],
[3, 1, 10, 11, 3, 10],
[1, 2, 11, 1, 11, 9, 9, 11, 8],
[3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9],
[0, 2, 11, 8, 0, 11],
[3, 2, 11],
[2, 3, 8, 2, 8, 10, 10, 8, 9],
[9, 10, 2, 0, 9, 2],
[2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8],
[1, 10, 2],
[1, 3, 8, 9, 1, 8],
[0, 9, 1],
[0, 3, 8],
[]]
, cubeVerts = [
[0,0,0]
,[1,0,0]
,[1,1,0]
,[0,1,0]
,[0,0,1]
,[1,0,1]
,[1,1,1]
,[0,1,1]]
, edgeIndex = [ [0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7] ];
exports.marchingCubes = function(dims, potential, bounds) {
if(!bounds) {
bounds = [[0,0,0], dims];
}
var scale = [0,0,0];
var shift = [0,0,0];
for(var i=0; i<3; ++i) {
scale[i] = (bounds[1][i] - bounds[0][i]) / dims[i];
shift[i] = bounds[0][i];
}
var vertices = []
, faces = []
, n = 0
, grid = new Array(8)
, edges = new Array(12)
, x = [0,0,0];
//March over the volume
for(x[2]=0; x[2]<dims[2]-1; ++x[2], n+=dims[0])
for(x[1]=0; x[1]<dims[1]-1; ++x[1], ++n)
for(x[0]=0; x[0]<dims[0]-1; ++x[0], ++n) {
//For each cell, compute cube mask
var cube_index = 0;
for(var i=0; i<8; ++i) {
var v = cubeVerts[i]
, s = potential(
scale[0]*(x[0]+v[0])+shift[0],
scale[1]*(x[1]+v[1])+shift[1],
scale[2]*(x[2]+v[2])+shift[2]);
grid[i] = s;
cube_index |= (s > 0) ? 1 << i : 0;
}
//Compute vertices
var edge_mask = edgeTable[cube_index];
if(edge_mask === 0) {
continue;
}
for(var i=0; i<12; ++i) {
if((edge_mask & (1<<i)) === 0) {
continue;
}
edges[i] = vertices.length;
var nv = [0,0,0]
, e = edgeIndex[i]
, p0 = cubeVerts[e[0]]
, p1 = cubeVerts[e[1]]
, a = grid[e[0]]
, b = grid[e[1]]
, d = a - b
, t = 0;
if(Math.abs(d) > 1e-6) {
t = a / d;
}
for(var j=0; j<3; ++j) {
nv[j] = scale[j] * ((x[j] + p0[j]) + t * (p1[j] - p0[j])) + shift[j];
}
vertices.push(nv);
}
//Add faces
var f = triTable[cube_index];
for(var i=0; i<f.length; i += 3) {
faces.push([edges[f[i]], edges[f[i+1]], edges[f[i+2]]]);
}
}
return { positions: vertices, cells: faces };
};
================================================
FILE: lib/marchingtetrahedra.js
================================================
/**
* Marching Tetrahedra in Javascript
*
* Based on Paul Bourke's implementation
* http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
*
* (Several bug fixes were made to deal with oriented faces)
*
* Javascript port by Mikola Lysenko
*/
var cube_vertices = [
[0,0,0]
, [1,0,0]
, [1,1,0]
, [0,1,0]
, [0,0,1]
, [1,0,1]
, [1,1,1]
, [0,1,1] ]
, tetra_list = [
[0,2,3,7]
, [0,6,2,7]
, [0,4,6,7]
, [0,6,1,2]
, [0,1,6,4]
, [5,6,1,4] ];
exports.marchingTetrahedra = function(dims, potential, bounds) {
if(!bounds) {
bounds = [[0,0,0], dims];
}
var scale = [0,0,0];
var shift = [0,0,0];
for(var i=0; i<3; ++i) {
scale[i] = (bounds[1][i] - bounds[0][i]) / dims[i];
shift[i] = bounds[0][i];
}
var vertices = []
, faces = []
, n = 0
, grid = new Float32Array(8)
, edges = new Int32Array(12)
, x = [0,0,0];
function interp(i0, i1) {
var g0 = grid[i0]
, g1 = grid[i1]
, p0 = cube_vertices[i0]
, p1 = cube_vertices[i1]
, v = [x[0], x[1], x[2]]
, t = g0 - g1;
if(Math.abs(t) > 1e-6) {
t = g0 / t;
}
for(var i=0; i<3; ++i) {
v[i] = scale[i] * (v[i] + p0[i] + t * (p1[i] - p0[i])) + shift[i];
}
vertices.push(v);
return vertices.length - 1;
}
//March over the volume
for(x[2]=0; x[2]<dims[2]-1; ++x[2], n+=dims[0])
for(x[1]=0; x[1]<dims[1]-1; ++x[1], ++n)
for(x[0]=0; x[0]<dims[0]-1; ++x[0], ++n) {
//Read in cube
for(var i=0; i<8; ++i) {
var cube_vert = cube_vertices[i];
grid[i] = potential(
scale[0]*(x[0]+cube_vert[0])+shift[0],
scale[1]*(x[1]+cube_vert[1])+shift[1],
scale[2]*(x[2]+cube_vert[2])+shift[2]);
}
for(var i=0; i<tetra_list.length; ++i) {
var T = tetra_list[i]
, triindex = 0;
if (grid[T[0]] < 0) triindex |= 1;
if (grid[T[1]] < 0) triindex |= 2;
if (grid[T[2]] < 0) triindex |= 4;
if (grid[T[3]] < 0) triindex |= 8;
//Handle each case
switch (triindex) {
case 0x00:
case 0x0F:
break;
case 0x0E:
faces.push([
interp(T[0], T[1])
, interp(T[0], T[3])
, interp(T[0], T[2]) ]);
break;
case 0x01:
faces.push([
interp(T[0], T[1])
, interp(T[0], T[2])
, interp(T[0], T[3]) ]);
break;
case 0x0D:
faces.push([
interp(T[1], T[0])
, interp(T[1], T[2])
, interp(T[1], T[3]) ]);
break;
case 0x02:
faces.push([
interp(T[1], T[0])
, interp(T[1], T[3])
, interp(T[1], T[2]) ]);
break;
case 0x0C:
faces.push([
interp(T[1], T[2])
, interp(T[1], T[3])
, interp(T[0], T[3])
, interp(T[0], T[2]) ]);
break;
case 0x03:
faces.push([
interp(T[1], T[2])
, interp(T[0], T[2])
, interp(T[0], T[3])
, interp(T[1], T[3]) ]);
break;
case 0x04:
faces.push([
interp(T[2], T[0])
, interp(T[2], T[1])
, interp(T[2], T[3]) ]);
break;
case 0x0B:
faces.push([
interp(T[2], T[0])
, interp(T[2], T[3])
, interp(T[2], T[1]) ]);
break;
case 0x05:
faces.push([
interp(T[0], T[1])
, interp(T[1], T[2])
, interp(T[2], T[3])
, interp(T[0], T[3]) ]);
break;
case 0x0A:
faces.push([
interp(T[0], T[1])
, interp(T[0], T[3])
, interp(T[2], T[3])
, interp(T[1], T[2]) ]);
break;
case 0x06:
faces.push([
interp(T[2], T[3])
, interp(T[0], T[2])
, interp(T[0], T[1])
, interp(T[1], T[3]) ]);
break;
case 0x09:
faces.push([
interp(T[2], T[3])
, interp(T[1], T[3])
, interp(T[0], T[1])
, interp(T[0], T[2]) ]);
break;
case 0x07:
faces.push([
interp(T[3], T[0])
, interp(T[3], T[1])
, interp(T[3], T[2]) ]);
break;
case 0x08:
faces.push([
interp(T[3], T[0])
, interp(T[3], T[2])
, interp(T[3], T[1]) ]);
break;
}
}
}
return { positions: vertices, cells: faces };
}
================================================
FILE: lib/surfacenets.js
================================================
/**
* SurfaceNets in JavaScript
*
* Written by Mikola Lysenko (C) 2012
*
* MIT License
*
* Based on: S.F. Gibson, "Constrained Elastic Surface Nets". (1998) MERL Tech Report.
*/
"use strict";
//Precompute edge table, like Paul Bourke does.
// This saves a bit of time when computing the centroid of each boundary cell
var cube_edges = new Int32Array(24)
, edge_table = new Int32Array(256);
(function() {
//Initialize the cube_edges table
// This is just the vertex number of each cube
var k = 0;
for(var i=0; i<8; ++i) {
for(var j=1; j<=4; j<<=1) {
var p = i^j;
if(i <= p) {
cube_edges[k++] = i;
cube_edges[k++] = p;
}
}
}
//Initialize the intersection table.
// This is a 2^(cube configuration) -> 2^(edge configuration) map
// There is one entry for each possible cube configuration, and the output is a 12-bit vector enumerating all edges crossing the 0-level.
for(var i=0; i<256; ++i) {
var em = 0;
for(var j=0; j<24; j+=2) {
var a = !!(i & (1<<cube_edges[j]))
, b = !!(i & (1<<cube_edges[j+1]));
em |= a !== b ? (1 << (j >> 1)) : 0;
}
edge_table[i] = em;
}
})();
//Internal buffer, this may get resized at run time
var buffer = new Array(4096);
(function() {
for(var i=0; i<buffer.length; ++i) {
buffer[i] = 0;
}
})();
exports.surfaceNets = function(dims, potential, bounds) {
if(!bounds) {
bounds = [[0,0,0],dims];
}
var scale = [0,0,0];
var shift = [0,0,0];
for(var i=0; i<3; ++i) {
scale[i] = (bounds[1][i] - bounds[0][i]) / dims[i];
shift[i] = bounds[0][i];
}
var vertices = []
, faces = []
, n = 0
, x = [0, 0, 0]
, R = [1, (dims[0]+1), (dims[0]+1)*(dims[1]+1)]
, grid = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
, buf_no = 1;
//Resize buffer if necessary
if(R[2] * 2 > buffer.length) {
var ol = buffer.length;
buffer.length = R[2] * 2;
while(ol < buffer.length) {
buffer[ol++] = 0;
}
}
//March over the voxel grid
for(x[2]=0; x[2]<dims[2]-1; ++x[2], n+=dims[0], buf_no ^= 1, R[2]=-R[2]) {
//m is the pointer into the buffer we are going to use.
//This is slightly obtuse because javascript does not have good support for packed data structures, so we must use typed arrays :(
//The contents of the buffer will be the indices of the vertices on the previous x/y slice of the volume
var m = 1 + (dims[0]+1) * (1 + buf_no * (dims[1]+1));
for(x[1]=0; x[1]<dims[1]-1; ++x[1], ++n, m+=2)
for(x[0]=0; x[0]<dims[0]-1; ++x[0], ++n, ++m) {
//Read in 8 field values around this vertex and store them in an array
//Also calculate 8-bit mask, like in marching cubes, so we can speed up sign checks later
var mask = 0, g = 0;
for(var k=0; k<2; ++k)
for(var j=0; j<2; ++j)
for(var i=0; i<2; ++i, ++g) {
var p = potential(
scale[0]*(x[0]+i)+shift[0],
scale[1]*(x[1]+j)+shift[1],
scale[2]*(x[2]+k)+shift[2]);
grid[g] = p;
mask |= (p < 0) ? (1<<g) : 0;
}
//Check for early termination if cell does not intersect boundary
if(mask === 0 || mask === 0xff) {
continue;
}
//Sum up edge intersections
var edge_mask = edge_table[mask]
, v = [0.0,0.0,0.0]
, e_count = 0;
//For every edge of the cube...
for(var i=0; i<12; ++i) {
//Use edge mask to check if it is crossed
if(!(edge_mask & (1<<i))) {
continue;
}
//If it did, increment number of edge crossings
++e_count;
//Now find the point of intersection
var e0 = cube_edges[ i<<1 ] //Unpack vertices
, e1 = cube_edges[(i<<1)+1]
, g0 = grid[e0] //Unpack grid values
, g1 = grid[e1]
, t = g0 - g1; //Compute point of intersection
if(Math.abs(t) > 1e-6) {
t = g0 / t;
} else {
continue;
}
//Interpolate vertices and add up intersections (this can be done without multiplying)
for(var j=0, k=1; j<3; ++j, k<<=1) {
var a = e0 & k
, b = e1 & k;
if(a !== b) {
v[j] += a ? 1.0 - t : t;
} else {
v[j] += a ? 1.0 : 0;
}
}
}
//Now we just average the edge intersections and add them to coordinate
var s = 1.0 / e_count;
for(var i=0; i<3; ++i) {
v[i] = scale[i] * (x[i] + s * v[i]) + shift[i];
}
//Add vertex to buffer, store pointer to vertex index in buffer
buffer[m] = vertices.length;
vertices.push(v);
//Now we need to add faces together, to do this we just loop over 3 basis components
for(var i=0; i<3; ++i) {
//The first three entries of the edge_mask count the crossings along the edge
if(!(edge_mask & (1<<i)) ) {
continue;
}
// i = axes we are point along. iu, iv = orthogonal axes
var iu = (i+1)%3
, iv = (i+2)%3;
//If we are on a boundary, skip it
if(x[iu] === 0 || x[iv] === 0) {
continue;
}
//Otherwise, look up adjacent edges in buffer
var du = R[iu]
, dv = R[iv];
//Remember to flip orientation depending on the sign of the corner.
if(mask & 1) {
faces.push([buffer[m], buffer[m-du], buffer[m-dv]]);
faces.push([buffer[m-dv], buffer[m-du], buffer[m-du-dv]]);
} else {
faces.push([buffer[m], buffer[m-dv], buffer[m-du]]);
faces.push([buffer[m-du], buffer[m-dv], buffer[m-du-dv]]);
}
}
}
}
//All done! Return the result
return { positions: vertices, cells: faces };
};
================================================
FILE: package.json
================================================
{
"name": "isosurface",
"version": "1.0.0",
"description": "3D isosurface polygonizer",
"main": "index.js",
"scripts": {
},
"repository": {
"type": "git",
"url": "git://github.com/mikolalysenko/isosurface.git"
},
"keywords": [
"voxel",
"isosurface",
"level",
"set",
"0fps",
"surface",
"nets",
"marching",
"cubes",
"tetrahedra"
],
"author": "Mikola Lysenko",
"license": "MIT",
"readmeFilename": "README.md",
"gitHead": "20517b13d1db64cdbf0498eb9eee728265faee9b"
}
================================================
FILE: test/sphere.js
================================================
console.log(require("../index.js").surfaceNets([32,32,32],
function(x,y,z) {
return Math.sqrt(x*x+y*y+z*z) - 7;
}, [[-10,-10,-10],[10,10,10]]))
gitextract_ac15jcwx/
├── .gitignore
├── LICENSE
├── README.md
├── index.js
├── lib/
│ ├── marchingcubes.js
│ ├── marchingtetrahedra.js
│ └── surfacenets.js
├── package.json
└── test/
└── sphere.js
SYMBOL INDEX (1 symbols across 1 files)
FILE: lib/marchingtetrahedra.js
function interp (line 48) | function interp(i0, i1) {
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (30K chars).
[
{
"path": ".gitignore",
"chars": 84,
"preview": "lib-cov\n*.seed\n*.log\n*.csv\n*.dat\n*.out\n*.pid\n*.gz\n\npids\nlogs\nresults\n\nnpm-debug.log\n"
},
{
"path": "LICENSE",
"chars": 1082,
"preview": "\nThe MIT License (MIT)\n\nCopyright (c) 2013 Mikola Lysenko\n\nPermission is hereby granted, free of charge, to any person o"
},
{
"path": "README.md",
"chars": 1776,
"preview": "isosurface\n==========\n\nIsosurface polygonizer algorithms in JavaScript. For more details, see the following blog posts:"
},
{
"path": "index.js",
"chars": 243,
"preview": "exports.surfaceNets = require(\"./lib/surfacenets.js\").surfaceNets;\nexports.marchingCubes = require(\"./lib/"
},
{
"path": "lib/marchingcubes.js",
"chars": 14037,
"preview": "/**\n * Javascript Marching Cubes\n *\n * Based on Paul Bourke's classic implementation:\n * http://local.wasp.uwa.edu.au"
},
{
"path": "lib/marchingtetrahedra.js",
"chars": 4782,
"preview": "/**\n * Marching Tetrahedra in Javascript\n *\n * Based on Paul Bourke's implementation\n * http://local.wasp.uwa.edu.au/~p"
},
{
"path": "lib/surfacenets.js",
"chars": 5951,
"preview": "/**\n * SurfaceNets in JavaScript\n *\n * Written by Mikola Lysenko (C) 2012\n *\n * MIT License\n *\n * Based on: S.F. Gibson,"
},
{
"path": "package.json",
"chars": 539,
"preview": "{\n \"name\": \"isosurface\",\n \"version\": \"1.0.0\",\n \"description\": \"3D isosurface polygonizer\",\n \"main\": \"index.js\",\n \"s"
},
{
"path": "test/sphere.js",
"chars": 152,
"preview": "console.log(require(\"../index.js\").surfaceNets([32,32,32],\n function(x,y,z) {\n return Math.sqrt(x*x+y*y+z*z) - 7;\n "
}
]
About this extraction
This page contains the full source code of the mikolalysenko/isosurface GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (28.0 KB), approximately 14.8k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.