Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update JS bindings with CrossSection + reorganize #440

Merged
merged 41 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
69ebacd
Update JS bindings with CrossSection + reorganize
geoffder May 25, 2023
fdd6f56
ignore no-arg call of Module
geoffder May 25, 2023
47c674e
roughly group functions names by purpose
geoffder May 25, 2023
356c9bf
clang-format pass over js files
geoffder May 26, 2023
7c25583
Move debug setup below memory registry indirection
geoffder May 26, 2023
8a9b062
Re-reformat
geoffder May 26, 2023
623306b
Add back undefined check
geoffder May 26, 2023
39ed5d7
remove spurious newline
geoffder May 26, 2023
b06c89e
Move reserveIDs under Manifold
geoffder May 26, 2023
c6b89f5
Add center param to extrude
geoffder May 26, 2023
2908a20
Add missing this argument back to _Extrude
geoffder May 26, 2023
8423e6e
Fix wrong timeout key
geoffder May 27, 2023
2df7829
rebuild on interface modification (ensure copying)
geoffder May 27, 2023
bbd8ee1
Remove redundant checks in scale methods
geoffder May 27, 2023
618836c
Undo scale change (vararg2vec not redundant)
geoffder May 27, 2023
4301220
Fix bindings.cpp properties (js deps)
geoffder May 27, 2023
d8a9f18
Move reserveIDs into manifold intf as static
geoffder May 27, 2023
01820d7
Simplify memory registry closure
geoffder May 27, 2023
98408f3
Cleanup examples with local method opens
geoffder May 27, 2023
5690a3a
Update Manifold interface (TODO add CrossSection)
geoffder May 27, 2023
78d7509
Copy js interface files on mod without recompiling
geoffder May 27, 2023
0f3e52a
Add note to READMEs about Firefox fix
geoffder May 27, 2023
233e81f
Add CrossSection interface and associated types
geoffder May 27, 2023
b30cc25
Revert Polygons and fix signatures
geoffder May 29, 2023
55320c7
Fix instanceof for Manifold and CrossSection
geoffder May 29, 2023
f3dc805
Fix signatures of extrude and revolve
geoffder May 29, 2023
4d43bb6
Extend show and only to take CrossSections
geoffder May 29, 2023
7aba193
Copy ManifoldToplevel into editor.js (necessary?)
geoffder May 29, 2023
817544a
Fix enums in CrossSection constr and offset
geoffder May 29, 2023
4871d54
Doc comment fixes
geoffder May 29, 2023
8a389ca
allow scalar input to extrude's scaleTop parameter
geoffder May 30, 2023
2fa3f44
Use CrossSection a bit more in examples
geoffder May 30, 2023
97e4381
Remove std::string from enum handling
geoffder May 30, 2023
f0a518e
Undo flubbed bracelet change, update intro test
geoffder May 30, 2023
2dc2b21
organizational comments
geoffder May 30, 2023
11bc0c9
Revert show/only changes
geoffder May 30, 2023
5b05c42
Organizational comments
geoffder May 30, 2023
1612ff4
Fix vec to polygon conversion
geoffder May 30, 2023
507b844
add missing static to ofPolygons signature
geoffder May 30, 2023
0a3dfe1
Revert to old intro and drop unneeded decimal pts
geoffder Jun 1, 2023
b4f2605
missed intro example test reversion
geoffder Jun 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## Users

[OpenSCAD](https://openscad.org/), [IFCjs](https://ifcjs.github.io/info/), [Grid.Space](https://grid.space/), and [OCADml](https://github.com/OCADml/OManifold) have all integrated our Manifold geometry kernel! Why? Because its reliability is guaranteed and it's 1,000 times faster than other libraries. See our [usage](https://github.com/elalish/manifold/discussions/340) and [performance](https://github.com/elalish/manifold/discussions/383) discussions for all the latest and to add your own projects & analyses.
[OpenSCAD](https://openscad.org/), [IFCjs](https://ifcjs.github.io/info/), [Grid.Space](https://grid.space/), and [OCADml](https://github.com/OCADml/OManifold) have all integrated our Manifold geometry kernel! Why? Because its reliability is guaranteed and it's 1,000 times faster than other libraries. See our [usage](https://github.com/elalish/manifold/discussions/340) and [performance](https://github.com/elalish/manifold/discussions/383) discussions for all the latest and to add your own projects & analyses.

For example, here is a log-log plot of Manifold's performance vs. earlier OpenSCAD geometry backends:

Expand All @@ -15,23 +15,31 @@ If you like OpenSCAD / JSCAD, you might also like ManifoldCAD - our own solid mo

![A metallic Menger sponge](https://elalish.github.io/manifold/samples/models/mengerSponge3.webp "A metallic Menger sponge")

### Note for Firefox users

If you find the editor is stuck on **Loading...**, setting
`dom.workers.modules.enabled: true` in your `about:config`, as mentioned in the
discussion of the
[issue#328](https://github.com/elalish/manifold/issues/328#issuecomment-1473847102)
of this repository may solve the problem.

# Manifold

[**API Documentation**](https://elalish.github.io/manifold/docs/html/modules.html) | [**Algorithm Documentation**](https://github.com/elalish/manifold/wiki/Manifold-Library) | [**Blog Posts**](https://elalish.blogspot.com/search/label/Manifold) | [**Web Examples**](https://elalish.github.io/manifold/model-viewer.html)

[Manifold](https://github.com/elalish/manifold) is a geometry library dedicated to creating and operating on manifold triangle meshes. A [manifold mesh](https://github.com/elalish/manifold/wiki/Manifold-Library#manifoldness) is a mesh that represents a solid object, and so is very important in manufacturing, CAD, structural analysis, etc. Further information can be found on the [wiki](https://github.com/elalish/manifold/wiki/Manifold-Library).

This is a modern C++ library that Github's CI verifies builds and runs on a variety of platforms. Additionally, we build bindings for JavaScript ([manifold-3d](https://www.npmjs.com/package/manifold-3d) on npm), Python, and C to make this library more portable and easy to use.
This is a modern C++ library that Github's CI verifies builds and runs on a variety of platforms. Additionally, we build bindings for JavaScript ([manifold-3d](https://www.npmjs.com/package/manifold-3d) on npm), Python, and C to make this library more portable and easy to use.

We have four core dependencies, making use of submodules to ensure compatibility:
We have four core dependencies, making use of submodules to ensure compatibility:
- `graphlite`: connected components algorithm
- `Clipper2`: provides our 2D subsystem
- `GLM`: a compact vector library
- `Thrust`: Nvidia's parallel algorithms library (basically a superset of C++17 std::parallel_algorithms)

## What's here

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.
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 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.

Expand All @@ -41,7 +49,7 @@ Look in the [samples](https://github.com/elalish/manifold/tree/master/samples) d

## Building

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.
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):
```
Expand Down
28 changes: 13 additions & 15 deletions bindings/wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ project(wasm)

add_executable(manifoldjs bindings.cpp)

set(JS_DEPS
${CMAKE_CURRENT_SOURCE_DIR}/bindings.js
${CMAKE_CURRENT_SOURCE_DIR}/manifold.d.ts
${CMAKE_CURRENT_SOURCE_DIR}/manifold-encapsulated-types.d.ts)
# FIXME: can we rewrite the custom command to run after these are modified when building
# without recompiling bindings.cpp?
# make sure that we recompile the wasm when bindings.js is being modified
set_source_files_properties(bindings.cpp PROPERTIES OBJECT_DEPENDS ${JS_DEPS})
set_source_files_properties(bindings.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bindings.js)
target_link_libraries(manifoldjs manifold sdf cross_section polygon)
target_compile_options(manifoldjs PRIVATE ${MANIFOLD_FLAGS})
target_link_options(manifoldjs PUBLIC --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/bindings.js --bind -sALLOW_TABLE_GROWTH=1
Expand All @@ -34,15 +27,20 @@ set_target_properties(manifoldjs PROPERTIES OUTPUT_NAME "manifold")

file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples/built)

# ensure that interface files are copied over when modified
add_custom_target(js_deps ALL
geoffder marked this conversation as resolved.
Show resolved Hide resolved
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/manifold.*
${CMAKE_CURRENT_SOURCE_DIR}/manifold*.d.ts)

add_custom_command(
TARGET manifoldjs POST_BUILD
TARGET js_deps POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/manifold.*
${CMAKE_CURRENT_SOURCE_DIR}/manifold*.d.ts
${CMAKE_CURRENT_SOURCE_DIR}/examples/built/)
${CMAKE_CURRENT_BINARY_DIR}/manifold.*
${CMAKE_CURRENT_SOURCE_DIR}/manifold*.d.ts
${CMAKE_CURRENT_SOURCE_DIR}/examples/built/)

add_custom_command(
TARGET manifoldjs POST_BUILD
TARGET js_deps POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/manifold*.d.ts
${CMAKE_CURRENT_SOURCE_DIR}/examples/public/)
${CMAKE_CURRENT_SOURCE_DIR}/manifold*.d.ts
${CMAKE_CURRENT_SOURCE_DIR}/examples/public/)
5 changes: 2 additions & 3 deletions bindings/wasm/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ EMSCRIPTEN_BINDINGS(whatever) {
register_vector<glm::vec4>("Vector_vec4");

class_<CrossSection>("CrossSection")
.constructor<std::vector<std::vector<glm::vec2>>,
CrossSection::FillRule>()
.constructor(&cross_js::OfPolygons)
.function("_add", &cross_js::Union)
.function("_subtract", &cross_js::Difference)
.function("_intersect", &cross_js::Intersection)
Expand All @@ -122,7 +121,7 @@ EMSCRIPTEN_BINDINGS(whatever) {
.function("numContour", &CrossSection::NumContour)
.function("_Bounds", &CrossSection::Bounds)
.function("simplify", &CrossSection::Simplify)
.function("_Offset", &CrossSection::Offset)
.function("_Offset", &cross_js::Offset)
.function("_RectClip", &CrossSection::RectClip)
.function("_ToPolygons", &CrossSection::ToPolygons);

Expand Down
32 changes: 24 additions & 8 deletions bindings/wasm/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ Module.setup = function() {

const CrossSectionCtor = Module.CrossSection;

function cross(polygons, fillrule = 'Positive') {
function cross(polygons, fillRule = 'Positive') {
if (polygons instanceof CrossSectionCtor) {
return polygons;
} else {
const polygonsVec = polygons2vec(polygons);
const cs = new CrossSectionCtor(polygonsVec, fillrule = fillrule);
const cs = new CrossSectionCtor(polygonsVec, fillRule = fillRule);
geoffder marked this conversation as resolved.
Show resolved Hide resolved
disposePolygons(polygonsVec);
return cs;
}
Expand Down Expand Up @@ -148,8 +148,8 @@ Module.setup = function() {
};

Module.CrossSection.prototype.offset = function(
delta, jointype = 'Square', miterLimit = 2.0, arcTolerance = 0.) {
return this._Offset(delta, jointype, miterLimit, arcTolerance);
delta, joinType = 'Square', miterLimit = 2.0, arcTolerance = 0.) {
return this._Offset(delta, joinType, miterLimit, arcTolerance);
};

Module.CrossSection.prototype.rectClip = function(rect) {
Expand Down Expand Up @@ -436,15 +436,15 @@ Module.setup = function() {

// CrossSection Constructors

Module.CrossSection = function(polygons, fillrule = 'Positive') {
Module.CrossSection = function(polygons, fillRule = 'Positive') {
const polygonsVec = polygons2vec(polygons);
const cs = new CrossSectionCtor(polygonsVec, fillrule = fillrule);
const cs = new CrossSectionCtor(polygonsVec, fillRule = fillRule);
disposePolygons(polygonsVec);
return cs;
};

Module.CrossSection.ofPolygons = function(polygons, fillrule = 'Positive') {
return new Module.CrossSection(polygons, fillrule = fillrule);
Module.CrossSection.ofPolygons = function(polygons, fillRule = 'Positive') {
return new Module.CrossSection(polygons, fillRule = fillRule);
};

Module.CrossSection.square = function(...args) {
Expand Down Expand Up @@ -483,6 +483,14 @@ Module.setup = function() {

Module.CrossSection.prototype = Object.create(CrossSectionCtor.prototype);

// Because the constructor and prototype are being replaced, instanceof will
// not work as desired unless we refer back to the original like this
Object.defineProperty(Module.CrossSection, Symbol.hasInstance, {
get: () => (t) => {
return (t instanceof CrossSectionCtor);
}
});

// Manifold Constructors

const ManifoldCtor = Module.Manifold;
Expand Down Expand Up @@ -598,6 +606,14 @@ Module.setup = function() {

Module.Manifold.prototype = Object.create(ManifoldCtor.prototype);

// Because the constructor and prototype are being replaced, instanceof will
// not work as desired unless we refer back to the original like this
Object.defineProperty(Module.Manifold, Symbol.hasInstance, {
geoffder marked this conversation as resolved.
Show resolved Hide resolved
get: () => (t) => {
return (t instanceof ManifoldCtor);
}
});

// Top-level functions

Module.triangulate = function(polygons, precision = -1) {
geoffder marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
17 changes: 15 additions & 2 deletions bindings/wasm/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ npm install
npm test
```

To develop the manifoldCAD.org editor as well as our other example pages, run
To develop the manifoldCAD.org editor as well as our other example pages, run
```
npm run dev
```
Expand All @@ -23,4 +23,17 @@ See `package.json` for other useful scripts.

Note that the `emcmake` command automatically copies your WASM build into `built/`, (here, not just under the `buildWASM` directory) which is then packaged by Vite into `dist/assets/`.

When testing [ManifoldCAD.org](https://manifoldcad.org/) (either locally or the deployed version) note that it uses a service worker for faster loading. This means you need to open the page twice to see updates (the first time loads the old version and caches the new one, the second time loads the new version from cache). To see changes on each reload, open Chrome dev tools, go to the Application tab and check "update on reload".
When testing [ManifoldCAD.org](https://manifoldcad.org/) (either locally or the
deployed version) note that it uses a service worker for faster loading. This
means you need to open the page twice to see updates (the first time loads the
old version and caches the new one, the second time loads the new version from
cache). To see changes on each reload, open Chrome dev tools, go to the
Application tab and check "update on reload".

### Note for firefox users

To use the manifoldCAD.org editor (`npm run dev`), you'll likely have to set
`dom.workers.modules.enabled: true` in your `about:config`, as mentioned in the
discussion of the
[issue#328](https://github.com/elalish/manifold/issues/328#issuecomment-1473847102)
of this repository.
30 changes: 11 additions & 19 deletions bindings/wasm/examples/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,26 +231,18 @@ async function getManifoldDTS() {
return `
${global.replaceAll('export', '')}
${encapsulated.replace(/^import.*$/gm, '').replaceAll('export', 'declare')}
declare interface ManifoldStatic {
cube: typeof cube;
cylinder: typeof cylinder;
sphere: typeof sphere;
smooth: typeof smooth;
tetrahedron: typeof tetrahedron;
extrude: typeof extrude;
revolve: typeof revolve;
union: typeof union;
difference: typeof difference;
intersection: typeof intersection;
compose: typeof compose;
levelSet: typeof levelSet;
setMinCircularAngle: typeof setMinCircularAngle;
setMinCircularEdgeLength: typeof setMinCircularEdgeLength;
setCircularSegments: typeof setCircularSegments;
getCircularSegments: typeof getCircularSegments;
reserveIDs: typeof reserveIDs;
declare interface ManifoldToplevel {
CrossSection: typeof T.CrossSection;
Manifold: typeof T.Manifold;
Mesh: typeof T.Mesh;
triangulate: typeof T.triangulate;
setMinCircularAngle: typeof T.setMinCircularAngle;
setMinCircularEdgeLength: typeof T.setMinCircularEdgeLength;
setCircularSegments: typeof T.setCircularSegments;
getCircularSegments: typeof T.getCircularSegments;
setup: () => void;
}
declare const module: ManifoldStatic;
declare const module: ManifoldToplevel;
`;
}

Expand Down
19 changes: 10 additions & 9 deletions bindings/wasm/examples/public/editor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,24 @@ declare function setMaterial(
manifold: Manifold, material: GLTFMaterial): Manifold;

/**
* Wrap any object with this method to display it and any copies in transparent
* red. This is particularly useful for debugging subtract() as it will allow
* you find the object even if it doesn't currently intersect the result.
* Wrap any shape object with this method to display it and any copies in
* transparent red. This is particularly useful for debugging subtract() as it
* will allow you find the object even if it doesn't currently intersect the
* result.
*
* @param manifold The object to show - returned for chaining.
* @param shape The object to show - returned for chaining.
*/
declare function show(manifold: Manifold): Manifold;
declare function show(shape: CrossSection|Manifold): Manifold;

/**
* Wrap any object with this method to display it and any copies as the result,
* while ghosting out the final result in transparent gray. Helpful for
* Wrap any shape object with this method to display it and any copies as the
* result, while ghosting out the final result in transparent gray. Helpful for
* debugging as it allows you to see objects that may be hidden in the interior
* of the result. Multiple objects marked only() will all be shown.
*
* @param manifold The object to show - returned for chaining.
* @param shape The object to show - returned for chaining.
*/
declare function only(manifold: Manifold): Manifold;
declare function only(shape: CrossSection|Manifold): Manifold;

// Type definitions for gl-matrix 3.4.3 Project:
// https://github.com/toji/gl-matrix
Expand Down
30 changes: 20 additions & 10 deletions bindings/wasm/examples/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import Module from './built/manifold';
//@ts-ignore
import {setupIO, writeMesh} from './gltf-io';
import type {GLTFMaterial, Quat} from './public/editor';
import type {CrossSection, Manifold, ManifoldStatic, Mesh, Vec3} from './public/manifold';
import type {CrossSection, Manifold, ManifoldToplevel, Mesh, Vec3} from './public/manifold';

interface WorkerStatic extends ManifoldStatic {
interface WorkerStatic extends ManifoldToplevel {
GLTFNode: typeof GLTFNode;
show(manifold: Manifold): Manifold;
only(manifold: Manifold): Manifold;
show(shape: CrossSection|Manifold): Manifold;
only(shape: CrossSection|Manifold): Manifold;
setMaterial(manifold: Manifold, material: GLTFMaterial): void;
cleanup(): void;
}
Expand Down Expand Up @@ -184,19 +184,29 @@ module.setMaterial = (manifold: Manifold, material: GLTFMaterial): Manifold => {
return out;
};

function debug(manifold: Manifold, map: Map<number, Mesh>) {
const result = manifold.asOriginal();
function debug(shape: Manifold|CrossSection, map: Map<number, Mesh>) {
let manifold;
if (shape instanceof module.CrossSection) {
const box = shape.bounds();
const x = box.max[0] - box.min[0];
const y = box.max[1] - box.min[1];
const h = Math.max(x, y) / 100;
geoffder marked this conversation as resolved.
Show resolved Hide resolved
manifold = shape.extrude(h).translate([0, 0, -h / 2]);
} else {
manifold = shape;
}
let result = manifold.asOriginal();
geoffder marked this conversation as resolved.
Show resolved Hide resolved
map.set(result.originalID(), result.getMesh());
return result;
};

module.show = (manifold) => {
return debug(manifold, shown);
module.show = (shape) => {
return debug(shape, shown);
};

module.only = (manifold) => {
module.only = (shape) => {
ghost = true;
return debug(manifold, singles);
return debug(shape, singles);
};

// Setup complete
Expand Down
20 changes: 20 additions & 0 deletions bindings/wasm/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <vector>

#include "cross_section.h"

using namespace emscripten;
using namespace manifold;

Expand Down Expand Up @@ -104,6 +106,15 @@ Manifold Smooth(const val& mesh,
} // namespace js

namespace cross_js {
CrossSection OfPolygons(std::vector<std::vector<glm::vec2>> polygons,
std::string fill_rule) {
geoffder marked this conversation as resolved.
Show resolved Hide resolved
auto fr = fill_rule == "EvenOdd" ? CrossSection::FillRule::EvenOdd
: fill_rule == "NonZero" ? CrossSection::FillRule::NonZero
: fill_rule == "Positive" ? CrossSection::FillRule::Positive
: CrossSection::FillRule::Negative;
return CrossSection(polygons, fr);
}

CrossSection Union(const CrossSection& a, const CrossSection& b) {
return a + b;
}
Expand Down Expand Up @@ -140,6 +151,15 @@ CrossSection Warp(CrossSection& cross_section, uintptr_t funcPtr) {
void (*f)(glm::vec2&) = reinterpret_cast<void (*)(glm::vec2&)>(funcPtr);
return cross_section.Warp(f);
}

CrossSection Offset(CrossSection& cross_section, double delta,
std::string join_type, double miter_limit,
geoffder marked this conversation as resolved.
Show resolved Hide resolved
double arc_tolerance) {
auto jt = join_type == "Square" ? CrossSection::JoinType::Square
: join_type == "Round" ? CrossSection::JoinType::Round
: CrossSection::JoinType::Miter;
return cross_section.Offset(delta, jt, miter_limit, arc_tolerance);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do this in a separate PR, but I agree with @pca006132 that instead of arc_tolerance we should use our setMinCircularAngle etc. functions to define this.

}
} // namespace cross_js

namespace man_js {
Expand Down
Loading