From 0fb47693b3c8ab22bdf85e3e5ca55929fe4acbe6 Mon Sep 17 00:00:00 2001 From: Emmett Lalish Date: Fri, 21 Oct 2022 15:42:00 -0700 Subject: [PATCH] Fix web examples (#254) * fixed three.js examples * add link and fix spelling --- README.md | 22 ++++++++++++++++------ bindings/wasm/bindings.d.ts | 14 +++++++------- bindings/wasm/examples/examples.js | 4 ++-- bindings/wasm/examples/model-viewer.html | 14 +++++++------- bindings/wasm/examples/three.html | 22 +++++++++++----------- 5 files changed, 43 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 06f6ad9da..15901f5d8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ [![codecov](https://codecov.io/github/elalish/manifold/branch/master/graph/badge.svg?token=IIA8G5HVS7)](https://codecov.io/github/elalish/manifold) +## [ManifoldCAD.org](https://manifoldcad.org) + +If you like OpenSCAD / OpenJSCAD, you might also like ManifoldCAD - our own solid modelling web app. The operations are not GPU-accelerated, but it's still pretty fast and a good way to test out our Manifold library. + ![A metallic Menger sponge](https://elalish.github.io/manifold/samples/models/mengerSponge3.webp "A metallic Menger sponge") # Manifold @@ -14,7 +18,7 @@ This is a modern C++ library that Github's CI verifies builds and runs on a vari This library is fast with guaranteed manifold output. As such you need manifold meshes as input, which this library can create using constructors inspired by the OpenSCAD API, as well as more advanced features like smoothing and signed-distance function (SDF) level sets. You can also pass in your own mesh data, but you'll get an error status if the imported mesh isn't manifold. Various automated repair tools exist online for fixing non manifold models, usually for 3D printing. -The most significant contribution here is a guaranteed-manifold [mesh Boolean](https://github.com/elalish/manifold/wiki/Manifold-Library#mesh-boolean) algorithm, which I believe is the first of its kind. If you know of another, please open a discussion - a mesh Boolean alorithm robust to edge cases has been an open problem for many years. Likewise, if the Boolean here ever fails you, please submit an issue! This Boolean forms the basis of a CAD kernel, as it allows simple shapes to be combined into more complex ones. +The most significant contribution here is a guaranteed-manifold [mesh Boolean](https://github.com/elalish/manifold/wiki/Manifold-Library#mesh-boolean) algorithm, which I believe is the first of its kind. If you know of another, please open a discussion - a mesh Boolean algorithm robust to edge cases has been an open problem for many years. Likewise, if the Boolean here ever fails you, please submit an issue! This Boolean forms the basis of a CAD kernel, as it allows simple shapes to be combined into more complex ones. To aid in speed, this library makes extensive use of parallelization, generally through Nvidia's Thrust library. You can switch between the CUDA, OMP and serial C++ backends by setting a CMake flag. Not everything is so parallelizable, for instance a [polygon triangulation](https://github.com/elalish/manifold/wiki/Manifold-Library#polygon-triangulation) algorithm is included which is serial. Even if compiled for CUDA, the code will still run without a GPU, falling back to the serial version of the algorithms. The WASM build is serial-only for now, but still fast. @@ -22,7 +26,7 @@ Look in the [samples](https://github.com/elalish/manifold/tree/master/samples) d ## Building -Only CMake and a C++ compiler are required to be installed and set up to build this library (it has been tested with GCC, LLVM, MSVC). However, a variety of optional dependencies can bring in more functionality, see below. +Only CMake, a C++ compiler, and Python are required to be installed and set up to build this library (it has been tested with GCC, LLVM, MSVC). However, a variety of optional dependencies can bring in more functionality, see below. Build and test (Ubuntu or similar): ``` @@ -46,6 +50,13 @@ The build instructions used by our CI are in [manifold.yml](https://github.com/e ### WASM To build the JS WASM library, first install NodeJS and set up emscripten: + +(on Mac): +``` +brew install nodejs +brew install emscripten +``` +(on Linux): ``` sudo apt install nodejs git clone https://github.com/emscripten-core/emsdk.git @@ -57,11 +68,10 @@ source ./emsdk/emsdk_env.sh Then build: ``` cd manifold -mkdir build -cd build +mkdir buildWASM +cd buildWASM emcmake cmake -DCMAKE_BUILD_TYPE=Release .. && emmake make -cd build/test -node ./manifold_test.js +node test/manifold_test.js ``` ### Python diff --git a/bindings/wasm/bindings.d.ts b/bindings/wasm/bindings.d.ts index 0c9e31805..87c99f2ee 100644 --- a/bindings/wasm/bindings.d.ts +++ b/bindings/wasm/bindings.d.ts @@ -74,10 +74,10 @@ declare class Manifold { translate(v: Vec3): Manifold; /** - * Applys an Euler angle rotation to the manifold, first about the X axis, + * Applies an Euler angle rotation to the manifold, first about the X axis, * then Y, then Z, in degrees. We use degrees so that we can minimize rounding - * error, and elimiate it completely for any multiples of 90 degrees. - * Addtionally, more efficient code paths are used to update the manifold when + * error, and eliminate it completely for any multiples of 90 degrees. + * Additionally, more efficient code paths are used to update the manifold when * the transforms only rotate by multiples of 90 degrees. This operation can * be chained. Transforms are combined and applied lazily. * @@ -207,7 +207,7 @@ declare class Manifold { getMesh(): Mesh; /** - * Gets the relationship to the previous meshes, for the purpose of assinging + * Gets the relationship to the previous meshes, for the purpose of assigning * properties like texture coordinates. The triBary vector is the same length * as Mesh.triVerts: BaryRef.originalID indicates the source mesh and * BaryRef.tri is that mesh's triangle index to which these barycentric @@ -226,7 +226,7 @@ declare class Manifold { /** * If you copy a manifold, but you want this new copy to have new properties * (e.g. a different UV mapping), you can reset its meshIDs to a new original, - * meaning it will now be referenced by its descendents instead of the meshes + * meaning it will now be referenced by its descendants instead of the meshes * it was built from, allowing you to differentiate the copies when applying * your properties to the final result. * @@ -328,7 +328,7 @@ declare function tetrahedron(): Manifold; * @param crossSection A set of non-overlapping polygons to extrude. * @param height Z-extent of extrusion. * @param nDivisions Number of extra copies of the crossSection to insert into - * the shape vertically; especially useful in combnation with twistDegrees to + * the shape vertically; especially useful in combination with twistDegrees to * avoid interpolation artifacts. Default is none. * @param twistDegrees Amount to twist the top crossSection relative to the * bottom, interpolated linearly for the divisions in between. @@ -398,7 +398,7 @@ declare function levelSet( * default on construction. If circularSegments is specified, it takes * precedence. If it is zero, then instead the minimum is used of the segments * calculated based on edge length and angle, rounded up to the nearest - * multiple of four. To get numbers not divisible by four, circularSegements + * multiple of four. To get numbers not divisible by four, circularSegments * must be specified. */ ///@{ diff --git a/bindings/wasm/examples/examples.js b/bindings/wasm/examples/examples.js index 73b603338..99e099f87 100644 --- a/bindings/wasm/examples/examples.js +++ b/bindings/wasm/examples/examples.js @@ -94,7 +94,7 @@ const exampleFunctions = { Heart: function () { // Smooth, complex manifolds can be created using the warp() function. This - // example recreates the Expoitable Heart by Emmett Lalish: + // example recreates the Exploitable Heart by Emmett Lalish: // https://www.thingiverse.com/thing:6190 const func = (v) => { @@ -181,7 +181,7 @@ const exampleFunctions = { }, TorusKnot: function () { - // Creates a classic torus knot, defined as a string wrapping peroidically + // Creates a classic torus knot, defined as a string wrapping periodically // around the surface of an imaginary donut. If p and q have a common factor // then you will get multiple separate, interwoven knots. This is an example of // using the warp() method, thus avoiding any direct handling of triangles. diff --git a/bindings/wasm/examples/model-viewer.html b/bindings/wasm/examples/model-viewer.html index 2d237170f..1d8abf043 100644 --- a/bindings/wasm/examples/model-viewer.html +++ b/bindings/wasm/examples/model-viewer.html @@ -127,20 +127,20 @@ function mesh2geometry(mesh) { const geometry = new THREE.BufferGeometry(); - const numVert = mesh.vertPos.size(); + const numVert = mesh.vertPos.length; const vert = new Float32Array(3 * numVert); for (let i = 0; i < numVert; i++) { - const v = mesh.vertPos.get(i); + const v = mesh.vertPos[i]; const idx = 3 * i; - vert[idx] = v.x; - vert[idx + 1] = v.y; - vert[idx + 2] = v.z; + vert[idx] = v[0]; + vert[idx + 1] = v[1]; + vert[idx + 2] = v[2]; } - const numTri = mesh.triVerts.size(); + const numTri = mesh.triVerts.length; const tri = new Uint32Array(3 * numTri); for (let i = 0; i < numTri; i++) { - const v = mesh.triVerts.get(i); + const v = mesh.triVerts[i]; const idx = 3 * i; tri[idx] = v[0]; tri[idx + 1] = v[1]; diff --git a/bindings/wasm/examples/three.html b/bindings/wasm/examples/three.html index f718f37e7..d961b3591 100644 --- a/bindings/wasm/examples/three.html +++ b/bindings/wasm/examples/three.html @@ -122,25 +122,25 @@ function mesh2geometry(mesh) { const geometry = new THREE.BufferGeometry(); - const numVert = mesh.vertPos.size(); + const numVert = mesh.vertPos.length; const vert = new Float32Array(3 * numVert); const norm = new Float32Array(3 * numVert); for (let i = 0; i < numVert; i++) { - const v = mesh.vertPos.get(i); - const n = mesh.vertNormal.get(i); + const v = mesh.vertPos[i]; + const n = mesh.vertNormal[i]; const idx = 3 * i; - vert[idx] = v.x; - vert[idx + 1] = v.y; - vert[idx + 2] = v.z; - norm[idx] = n.x; - norm[idx + 1] = n.y; - norm[idx + 2] = n.z; + vert[idx] = v[0]; + vert[idx + 1] = v[1]; + vert[idx + 2] = v[2]; + norm[idx] = n[0]; + norm[idx + 1] = n[1]; + norm[idx + 2] = n[2]; } - const numTri = mesh.triVerts.size(); + const numTri = mesh.triVerts.length; const tri = new Uint32Array(3 * numTri); for (let i = 0; i < numTri; i++) { - const v = mesh.triVerts.get(i); + const v = mesh.triVerts[i]; const idx = 3 * i; tri[idx] = v[0]; tri[idx + 1] = v[1];