diff --git a/.github/workflows/workflow1.yml b/.github/workflows/workflow1.yml index 354393f..f2729cf 100644 --- a/.github/workflows/workflow1.yml +++ b/.github/workflows/workflow1.yml @@ -18,12 +18,7 @@ jobs: uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - - run: npm install -g pnpm@6 - - uses: actions/cache@v2 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-store - run: sudo apt-get install libocct-data-exchange-dev libocct-modeling-data-dev - - run: npm install -g pnpm@6 - - run: pnpm recursive install - - run: pnpm test + - run: npm install + - run: npm run build + - run: npm test diff --git a/.gitignore b/.gitignore index c06e0de..04d8e7e 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ npm-debug* occt-* bower_components +*.tsbuildinfo diff --git a/.mocharc.yml b/.mocharc.yml new file mode 100644 index 0000000..1c4b630 --- /dev/null +++ b/.mocharc.yml @@ -0,0 +1,7 @@ +require: + - ./node_modules/ts-node/register +extensions: + - js + - ts +recursive: true +enable-source-map: true diff --git a/.npmignore b/.npmignore index e8c6d4a..2176ae7 100644 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1,8 @@ package/ build*/ sample/ -dist/ +dist-test/ +test/ sample_angular2 oce/ occt-*/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..9845cb8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 80, + "useTabs": false, + "trailingComma": "none" +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 61c4e69..0000000 --- a/.travis.yml +++ /dev/null @@ -1,142 +0,0 @@ -language: cpp -# 18.04 -dist: bionic -# - focal - -os: - - linux - - osx -osx_image: xcode12 - -# we use travis container based infrastructure -# https://docs.travis-ci.com/user/installing-dependencies/#Installing-Packages-on-Container-Based-Infrastructure -# sudo: required - -env: - matrix: - # - TRAVIS_NODE_VERSION="6" - #- TRAVIS_NODE_VERSION="6" ARCH="x86" - # - TRAVIS_NODE_VERSION="7" - #- TRAVIS_NODE_VERSION="7" ARCH="x86" - #- TRAVIS_ELECTRON_VERSION="1.4.14" TRAVIS_NODE_VERSION="6" - - TRAVIS_NODE_VERSION="8" - - TRAVIS_NODE_VERSION="9" - - TRAVIS_NODE_VERSION="10" - - TRAVIS_NODE_VERSION="11" - - TRAVIS_NODE_VERSION="12" - - TRAVIS_NODE_VERSION="13" - - TRAVIS_NODE_VERSION="14" - -matrix: - exclude: - - os: osx - env: TRAVIS_NODE_VERSION="6" - - os: osx - env: TRAVIS_NODE_VERSION="6" ARCH="x86" - - os: osx - env: TRAVIS_NODE_VERSION="7" - - os: osx - env: TRAVIS_NODE_VERSION="8" - - os: osx - env: TRAVIS_NODE_VERSION="9" - #- os: osx - # env: TRAVIS_NODE_VERSION="7" ARCH="x86" - allow_failures: - - os: osx - -addons: - apt: - sources: - - sourceline: 'ppa:ubuntu-toolchain-r/test' - - sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' - key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - packages: - - g++ - - libtbb2 - - libtbb-dev - update: true - homebrew: - packages: - - tbb - - freetype - - opencascade - update: true - -before_install: -- > - if [[ $TRAVIS_OS_NAME == "linux" ]]; then - cat /etc/apt/sources.list - sudo add-apt-repository universe - sudo add-apt-repository multiverse - sudo apt-add-repository -y ppa:freecad-maintainers/freecad-daily - sudo apt-get update -qq - sudo apt-get install -y --no-install-recommends libocct-data-exchange-dev - fi - -# reinstall latest nvm -- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh -- nvm install $TRAVIS_NODE_VERSION -- PATH=$PATH:`pwd`/node_modules/.bin -- BASE_URL=$(node -p "'https://nodejs.org/dist/' + process.version") -- X86_FILE=$(node -p "'node-' + process.version + '-' + process.platform + '-x86'") -# download node if testing x86 architecture -- > - if [[ "$ARCH" == "x86" ]]; then - wget -q $BASE_URL/$X86_FILE.tar.gz - tar -xf $X86_FILE.tar.gz - export PATH=$X86_FILE/bin:$PATH - ls $X86_FILE/bin - echo " PATH =" $PATH - fi; - true; - -# print versions -- uname -a -- file `which node` -- node --version -- node -p 'process.platform + "@" + process.arch' -- npm --version - -# use g++ on linux -- if [[ $TRAVIS_OS_NAME == "linux" ]]; then export CXX=g++; fi -- $CXX --version -- npm install -g https://github.com/OpenWebCAD/node-pre-gyp-github.git node-pre-gyp - -# compile Node-OCC -- bash ./prepare_node.sh - -git: - submodules: false - -install: -- npm install --build-from-source - -script: -- > - if [[ -z $TRAVIS_ELECTRON_VERSION ]]; then - # export LD_LIBRARY_PATH=`pwd`/occt-7.2.0/lib - # export DYLD_LIBRARY_PATH=`pwd`/occt-7.2.0/lib - node ./ - npm test - else - electron test_electron - electron_mocha test - fi; - true; - -# if publishing, do it -# Figure out if we should publish -- PUBLISH_BINARY=false -# If we are building a tag then we need to publish a new binary package -- if [[ $TRAVIS_BRANCH == `git describe --tags --always HEAD` ]]; then PUBLISH_BINARY=true; fi; -# or if we put the string [publish binary] in the commit message -- if test "${COMMIT_MESSAGE#*'[publish binary]'}" != "$COMMIT_MESSAGE"; then PUBLISH_BINARY=true; fi; -- if [[ $PUBLISH_BINARY == true ]]; then node-pre-gyp package; fi; -- if [[ $PUBLISH_BINARY == true ]]; then node-pre-gyp-github publish --release; fi; - -# cleanup -- node-pre-gyp clean - -cache: - directories: - - build_oce diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ce00843..208e73c 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -9,7 +9,8 @@ "defines": [], "cStandard": "c17", "cppStandard": "c++14", - "intelliSenseMode": "linux-clang-x64" + "intelliSenseMode": "linux-clang-x64", + "configurationProvider": "ms-vscode.makefile-tools" } ], "version": 4 diff --git a/.vscode/settings.json b/.vscode/settings.json index c7a528c..3dc0597 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -51,6 +51,14 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "unordered_set": "cpp", + "valarray": "cpp", + "chrono": "cpp", + "complex": "cpp", + "ratio": "cpp", + "compare": "cpp", + "concepts": "cpp", + "ranges": "cpp" } } \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 4c67257..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = function (grunt) { - // Do grunt-related things in here - grunt.initConfig({ - pkg: grunt.file.readJSON("package.json"), - - mochacli: { - options: { - //reporter: "nyan" - reporter: "spec" - }, - all: ["test/**/*_test.js"] - - }, - - docco: { - debug: { - src: ["lib/*.js", "test/**/*.js"], - options: { - output: "docs/" - } - } - - } - }); - grunt.loadNpmTasks("grunt-mocha-cli"); - grunt.loadNpmTasks("grunt-docco"); - grunt.registerTask("doc", ["docco"]); - - grunt.registerTask("default", ["mochacli", "doc"]); -}; - diff --git a/History.md b/History.md deleted file mode 100644 index bfec38d..0000000 --- a/History.md +++ /dev/null @@ -1,7 +0,0 @@ - -0.0.1 (2013-02-10) -=================== - - * initial release - - \ No newline at end of file diff --git a/JasmineAdapter-1.1.2.js b/JasmineAdapter-1.1.2.js deleted file mode 100644 index 9733714..0000000 --- a/JasmineAdapter-1.1.2.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @fileoverview Jasmine JsTestDriver Adapter. - * @author misko@hevery.com (Misko Hevery) - * @author olmo.maldonado@gmail.com (Olmo Maldonado) - */ -(function() { - - - var Env = function(onTestDone, onComplete) { - jasmine.Env.call(this); - - this.specFilter = function(spec) { - if (!this.exclusive) return true; - var blocks = spec.queue.blocks, l = blocks.length; - for (var i = 0; i < l; i++) if (blocks[i].func.exclusive >= this.exclusive) return true; - return false; - }; - - this.reporter = new Reporter(onTestDone, onComplete); - }; - jasmine.util.inherit(Env, jasmine.Env); - -// Here we store: -// 0: everyone runs -// 1: run everything under ddescribe -// 2: run only iits (ignore ddescribe) - Env.prototype.exclusive = 0; - - - Env.prototype.execute = function() { - collectMode = false; - playback(); - jasmine.Env.prototype.execute.call(this); - }; - - - var Reporter = function(onTestDone, onComplete) { - this.onTestDone = onTestDone; - this.onComplete = onComplete; - this.reset(); - }; - jasmine.util.inherit(Reporter, jasmine.Reporter); - - - Reporter.formatStack = function(stack) { - var line, lines = (stack || '').split(/\r?\n/), l = lines.length, frames = []; - for (var i = 0; i < l; i++) { - line = lines[i]; - if (line.match(/\/jasmine[\.-]/)) continue; -frames.push(line.replace(/https?:\/\/\w+(:\d+)?\/test\//, '').replace(/^\s*/, ' ')); - } - return frames.join('\n'); - }; - - - Reporter.prototype.reset = function() { - this.specLog = jstestdriver.console.log_ = []; - }; - - - Reporter.prototype.log = function(str) { - this.specLog.push(str); - }; - - - Reporter.prototype.reportSpecStarting = function() { - this.reset(); - this.start = +new Date(); - }; - - - Reporter.prototype.reportSpecResults = function(spec) { - var elapsed = +new Date() - this.start, results = spec.results(); - - if (results.skipped) return; - - var item, state = 'passed', items = results.getItems(), l = items.length, messages = []; - for (var i = 0; i < l; i++) { - item = items[i]; - if (item.passed()) continue; - state = (item.message.indexOf('AssertionError:') != -1) ? 'error' : 'failed'; - messages.push( { -message: item + '', -name: item.trace.name, -stack: Reporter.formatStack(item.trace.stack) - }); - } - - this.onTestDone(new jstestdriver.TestResult( - spec.suite.getFullName(), - spec.description, - state, - jstestdriver.angular.toJson(messages), - this.specLog.join('\n'), - elapsed - )); - }; - - - Reporter.prototype.reportRunnerResults = function() { - this.onComplete(); - }; - - - var collectMode = true, intercepted = {}; - - describe = intercept('describe'); - beforeEach = intercept('beforeEach'); - afterEach = intercept('afterEach'); - - var JASMINE_TYPE = 'jasmine test case'; - TestCase('Jasmine Adapter Tests', null, JASMINE_TYPE); - - jstestdriver.pluginRegistrar.register( { - -name: 'jasmine', - -getTestRunsConfigurationFor: function(testCaseInfos, expressions, testRunsConfiguration) { - for (var i = 0; i < testCaseInfos.length; i++) { - if (testCaseInfos[i].getType() == JASMINE_TYPE) { - testRunsConfiguration.push(new jstestdriver.TestRunConfiguration(testCaseInfos[i], [])); - } - } - return false; // allow other TestCases to be collected. - }, - -runTestConfiguration: function(config, onTestDone, onComplete) { - if (config.getTestCaseInfo().getType() != JASMINE_TYPE) return false; - (jasmine.currentEnv_ = new Env(onTestDone, onComplete)).execute(); - return true; - }, - -onTestsFinish: function() { - jasmine.currentEnv_ = null; - collectMode = true; - } - - }); - - function intercept(method) { - var bucket = intercepted[method] = [], method = window[method]; - return function(desc, fn) { - if (collectMode) bucket.push(function() { - method(desc, fn); - }); - else method(desc, fn); - }; - } - - function playback() { - for (var method in intercepted) { - var bucket = intercepted[method]; - for (var i = 0, l = bucket.length; i < l; i++) bucket[i](); - } - } - -})(); - -var ddescribe = function(name, fn) { - var env = jasmine.getEnv(); - if (!env.exclusive) env.exclusive = 1; // run ddescribe only - describe(name, function() { - var oldIt = it; - it = function(name, fn) { - fn.exclusive = 1; // run anything under ddescribe - env.it(name, fn); - }; - - try { - fn.call(this); - } - finally { - it = oldIt; - }; - }); -}; - -var iit = function(name, fn) { - var env = jasmine.getEnv(); - env.exclusive = fn.exclusive = 2; // run only iits - env.it(name, fn); -}; - -// Patch Jasmine for proper stack traces -jasmine.Spec.prototype.fail = function (e) { - var result = new jasmine.ExpectationResult( { -passed: false, -message: e ? jasmine.util.formatException(e) : 'Exception' - }); - if(e) result.trace = e; - this.results_.addResult(result); -}; diff --git a/Makefile b/Makefile index 3a9a853..e27ed73 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,25 @@ -all: - node-pre-gyp configure - node-pre-gyp build - mocha +.PHONY: build + +all: build test + +build: + ./node_modules/.bin/node-pre-gyp configure + ./node_modules/.bin/node-pre-gyp build + +test: + mocha test/*.ts .PHONY: test test: - mocha + mocha test/*.ts clean: - node-pre-gyp clean - -packet: - npm install mocha@7 - npm install assert - npm install should - npm install node-pre-gyp - - + ./node_modules/.bin/node-pre-gyp clean copy: COPY D:\projet\oce-build\bin\Debug\*.dll build\Release + +## https://leimao.github.io/blog/Clang-Format-Quick-Tutorial/ format: - astyle --indent=spaces=4 src/* + clang-format -i src/*.h src/*.cc + npm run prettier diff --git a/README.md b/README.md index 508331d..89edf0e 100644 --- a/README.md +++ b/README.md @@ -59,14 +59,14 @@ $npm install node-occ ```bash # installing nodejs and gyp utility to build extensions sudo apt-get install nodejs npm -sudo npm install node-pre-gyp -g -sudo npm install mocha@7 -g +sudo npm install @mapbox/node-pre-gyp -g +sudo npm install mocha -g #installing cmake sudo apt-get install cmake cmake-curses-gui g++ build-essential libtbb2 # ------------------------------------ -git clone --recursive https://github.com/erossignon/node-occ.git +git clone --recursive https://github.com/OpenWebCAD/node-occ.git cd node-occ # download prebuild OpenCascade Library and header files diff --git a/appveyor.yml b/appveyor.yml index bd79259..b8328bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,48 +21,16 @@ environment: VisualStudioVersion: "12" matrix: - - electron_version: "7.3.2" - nodejs_version: 12 - platform: x64 - - # - electron_version: "8.5.0" // not working yet =< GetBackingStore missing - # nodejs_version: 12 - # platform: x64 - - # - electron_version: "9.2.0" - # nodejs_version: 12 - # platform: x64 + #- electron_version: "7.3.2" + # nodejs_version: 12 + # platform: x64 - - nodejs_version: 8 - platform: x64 - - - nodejs_version: 10 + - nodejs_version: 16 platform: x64 - - nodejs_version: 12 - platform: x64 - - - nodejs_version: 14 + - nodejs_version: 18 platform: x64 - # - electron_version: "1.4.14" - # nodejs_version: 6 - # platform: x86 - - # - electron_version: "1.4.14" - # nodejs_version: 6 - # platform: x64 - - # - electron_version: "1.6.10" - # nodejs_version: 6 - # platform: x86 - - # - electron_version: "1.6.10" - # nodejs_version: 6 - # platform: x64 - - - # clone directory clone_folder: c:\projects\node-occ @@ -100,6 +68,7 @@ install: - cmd: npm install mocha@7 https://github.com/OpenWebCAD/node-pre-gyp-github.git -g - cmd: setenv.bat 64 - cmd: build.bat %PLATFORM% +- cmd: npm run build build_script: @@ -118,12 +87,12 @@ test_script: - IF NOT DEFINED electron_version (npm test) after_test: - - IF %PUBLISH_BINARY% == 1 (node-pre-gyp package 2>&1) - - # IF %PUBLISH_BINARY% == 1 (node-pre-gyp publish 2>&1) - - # IF %PUBLISH_BINARY% == 1 (node-pre-gyp-github publish --release 2>&1) - - IF %PUBLISH_BINARY% == 1 (node-pre-gyp-github publish) - - # IF %PUBLISH_BINARY% == 1 (node-pre-gyp-github publish 2>&1) - - IF %PUBLISH_BINARY% == 1 (node-pre-gyp clean) + - IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp package 2>&1) + - # IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp publish 2>&1) + - # IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp-github publish --release 2>&1) + - IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp-github publish) + - # IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp-github publish 2>&1) + - IF %PUBLISH_BINARY% == 1 (./node_modules/.bin/node-pre-gyp clean) - IF %PUBLISH_BINARY% == 1 (npm install --fallback-to-build=false) deploy: off diff --git a/bin/STEPtoBREP.js b/bin/STEPtoBREP.js index a07e21b..38d5905 100644 --- a/bin/STEPtoBREP.js +++ b/bin/STEPtoBREP.js @@ -1,4 +1,4 @@ -const occ = require("../lib/occ"); +import { occ } from ".."; const pace = require("pace")(1000); diff --git a/binding.gyp b/binding.gyp index 239e541..064bee5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -164,7 +164,10 @@ "-lTKFillet<(dbg)", "-lTKFeat<(dbg)", "-lTKXSBase<(dbg)", + "-lTKXCAF<(dbg)", "-lTKSTL<(dbg)", + "-lTKRWMesh<(dbg)", + "-lTKLCAF<(dbg)" ], "other_libraries": [ "-lTKTObj<(dbg)", diff --git a/build_oce.bat b/build_oce.bat index 222745b..be158e2 100644 --- a/build_oce.bat +++ b/build_oce.bat @@ -105,7 +105,7 @@ CALL git submodule update --init --recursive ECHO NODE-PRE-GYP -@call node-pre-gyp --version +@call .\node_modules\.bin\node-pre-gyp --version @call cl @call msbuild diff --git a/dist-test/helpers.d.ts b/dist-test/helpers.d.ts new file mode 100644 index 0000000..f819a90 --- /dev/null +++ b/dist-test/helpers.d.ts @@ -0,0 +1,5 @@ +export declare function getTemporaryFilePath({ prefix, suffix }: { + prefix?: string; + suffix: string; +}): string; +export declare function removeFile(filename: string): void; diff --git a/dist-test/helpers.js b/dist-test/helpers.js new file mode 100644 index 0000000..3249b9d --- /dev/null +++ b/dist-test/helpers.js @@ -0,0 +1,26 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.removeFile = exports.getTemporaryFilePath = void 0; +const node_fs_1 = __importDefault(require("node:fs")); +const node_os_1 = __importDefault(require("node:os")); +const node_crypto_1 = __importDefault(require("node:crypto")); +const node_path_1 = __importDefault(require("node:path")); +function getTemporaryFilePath({ prefix, suffix }) { + const name = node_crypto_1.default.randomUUID(); + return node_path_1.default.join(node_os_1.default.tmpdir(), (prefix || "") + name + suffix); +} +exports.getTemporaryFilePath = getTemporaryFilePath; +; +function removeFile(filename) { + if (node_fs_1.default.existsSync(filename)) { + node_fs_1.default.unlinkSync(filename); + } + else { + //Show in red + console.log("File " + filename + " not found, so not deleting."); + } +} +exports.removeFile = removeFile; diff --git a/dist-test/test_BREP.d.ts b/dist-test/test_BREP.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_BREP.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_BREP.js b/dist-test/test_BREP.js similarity index 54% rename from test/test_BREP.js rename to dist-test/test_BREP.js index cd2242d..13cd1fe 100644 --- a/test/test_BREP.js +++ b/dist-test/test_BREP.js @@ -1,114 +1,90 @@ -const assert = require("assert"); -const should = require("should"); -const shape_factory = require("../lib/shapeFactory"); -const occ = require("../lib/occ"); -const fs = require("fs"); - - -const getTemporaryFilePath = require("./helpers").getTemporaryFilePath; -const remove_file = require("./helpers").remove_file; - - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); +const __2 = require(".."); +const helpers_1 = require("./helpers"); +const assert_1 = __importDefault(require("assert")); describe("testing BREP input output ", function () { - - let b1_brep, b2_brep, b3_brep; + let b1_brep; + let b2_brep; + let b3_brep; let b1_volume = 0; let b1_area = 0; - before(function () { - - b1_brep = getTemporaryFilePath({prefix: "b1_", suffix: ".brep"}); - b2_brep = getTemporaryFilePath({prefix: "b2_", suffix: ".brep"}); - b3_brep = getTemporaryFilePath({prefix: "b3_", suffix: ".brep"}); - + before(() => { + b1_brep = (0, helpers_1.getTemporaryFilePath)({ prefix: "b1_", suffix: ".brep" }); + b2_brep = (0, helpers_1.getTemporaryFilePath)({ prefix: "b2_", suffix: ".brep" }); + b3_brep = (0, helpers_1.getTemporaryFilePath)({ prefix: "b3_", suffix: ".brep" }); create_shapes(); - }); - after(function (done) { - remove_file(b1_brep); - remove_file(b2_brep); - remove_file(b3_brep); + after((done) => { + (0, helpers_1.removeFile)(b1_brep); + (0, helpers_1.removeFile)(b2_brep); + (0, helpers_1.removeFile)(b3_brep); done(); }); - function create_shapes() { - - let box = occ.makeBox([0, 0, 0], [100, 200, 300]); - let b1_result = occ.writeBREP(b1_brep, box); + let box = __2.occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1_result = __2.occ.writeBREP(b1_brep, box); b1_volume = box.volume; b1_area = box.area; - - let cyl = occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); - let b2_result = occ.writeBREP(b2_brep, cyl); - - let b3_result = occ.writeBREP(b3_brep, [box, cyl]); - + let cyl = __2.occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); + let b2_result = __2.occ.writeBREP(b2_brep, cyl); + let b3_result = __2.occ.writeBREP(b3_brep, [box, cyl]); b1_result.should.eql(true); b2_result.should.eql(true); b3_result.should.eql(true); - } - it("should write a simple shape", function () { create_shapes(); }); - describe(" readBREP ", function () { - it("ZZ1 - should throw an error if used with no argument", function () { - - should(function () { - occ.readBREP(null, function (err, shapes) { + (0, should_1.default)(function () { + __2.occ.readBREP(null, (err) => { err.message.should.match(/expecting a filename/); }); }).throwError(); }); - - it("ZZ2 - should call the callback method with an error if used with an invalid arguments", function (done) { - - occ.readBREP("||this is a invalid filename||", (err, shapes) => { + it("ZZ2 - should call the callback method with an error if used with an invalid arguments", (done) => { + __2.occ.readBREP("||this is a invalid filename||", (err, _shapes) => { err.message.should.match(/cannot read/); done(); }); }); - - it("ZZ3 - should call the callback with an error if the file doesn't exist", function (done) { - occ.readBREP("invalid file name", function (err, shapes) { + it("ZZ3 - should call the callback with an error if the file doesn't exist", (done) => { + __2.occ.readBREP("invalid file name", (err, _shapes) => { console.log(" intercepting error ", err); - assert(err !== undefined); + (0, assert_1.default)(err !== undefined); done(); }); }); - - it("ZZ4 - should read the shape back", function (done) { - - occ.readBREP(b1_brep, (err, shapes) => { - - should(err).eql(null); - + it("ZZ4 - should read the shape back", (done) => { + __2.occ.readBREP(b1_brep, (err, shapes) => { + (0, should_1.default)(err).eql(null); if (!err) { shapes.length.should.equal(1); shapes[0].numFaces.should.equal(6); - shapes[0].volume.should.equal(b1_volume); shapes[0].area.should.equal(b1_area); } done(err); }); }); - - it("ZZ5 - should read the shape back", function (done) { - - occ.readBREP(b2_brep, function (err, shapes) { + it("ZZ5 - should read the shape back", (done) => { + __2.occ.readBREP(b2_brep, (err, shapes) => { if (!err) { shapes.length.should.equal(1); shapes[0].numFaces.should.equal(3); } done(err); }); - }); - it("ZZ6 - should read the shape back", function (done) { - occ.readBREP(b3_brep, function (err, shapes) { + it("ZZ6 - should read the shape back", (done) => { + __2.occ.readBREP(b3_brep, function (err, shapes) { if (!err) { shapes.length.should.equal(2); shapes[0].numFaces.should.equal(6); @@ -119,20 +95,16 @@ describe("testing BREP input output ", function () { }); }); }); - function build_large_part() { - - let lego_filename = getTemporaryFilePath({prefix: "legoPlate3x2_2x2", suffix: ""}); - - let legoPlate = shape_factory.makeLegoBrick(occ, 3, 2, "thin"); + let lego_filename = (0, helpers_1.getTemporaryFilePath)({ prefix: "legoPlate3x2_2x2", suffix: "" }); + let legoPlate = (0, __1.makeLegoBrick)(__2.occ, 3, 2, "thin"); let solids = []; for (let x = 0; x < 100; x += 50) { for (let y = 0; y < 100; y += 50) { solids.push(legoPlate.translate([x, y, 0])); } } - occ.writeBREP(lego_filename + ".brep", solids); - + __2.occ.writeBREP(lego_filename + ".brep", solids); /* occ.writeSTL(lego_filename + ".stl", solids); @@ -150,28 +122,17 @@ function build_large_part() { */ return lego_filename; } - describe("it should write and read a large brep file", function () { - this.timeout(15000); - let filename = build_large_part(); - - it("should read a large BREP file quickly", function (done) { - + it("should read a large BREP file quickly", (done) => { console.log(" lego file ", filename); - - occ.readBREP(filename + ".brep", function (err, solids) { - + __2.occ.readBREP(filename + ".brep", (err, solids) => { console.log(" read !!!"); - if (!err) { console.log(" num Faces = ", solids[0].numFaces); } done(err); }); - }); - - }); diff --git a/dist-test/test_BoundingBox.d.ts b/dist-test/test_BoundingBox.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_BoundingBox.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/dist-test/test_BoundingBox.js b/dist-test/test_BoundingBox.js new file mode 100644 index 0000000..1dbbbfb --- /dev/null +++ b/dist-test/test_BoundingBox.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +require("should"); +describe("testing bounding box", function () { + describe("an empty BoundingBox", function () { + let bbox; + before(function () { + bbox = new __1.BoundingBox(); + }); + it("should be void", function () { + bbox.isVoid.should.equal(true); + }); + }); + describe("an BoundingBox built with a single point in constructor", function () { + let bbox; + before(function () { + bbox = new __1.BoundingBox([10, 20, 30]); + }); + it("should not be void", function () { + bbox.isVoid.should.equal(false); + }); + it("should have nearPt to be correct", function () { + bbox.nearPt.x.should.equal(10); + bbox.nearPt.y.should.equal(20); + bbox.nearPt.z.should.equal(30); + }); + it("should have farPt to be correct", function () { + bbox.farPt.x.should.equal(10); + bbox.farPt.y.should.equal(20); + bbox.farPt.z.should.equal(30); + }); + }); + describe("adding a single point to an empty bounding box", function () { + let bbox; + before(function () { + bbox = new __1.BoundingBox(); + bbox.addPoint([10, 20, 30]); + }); + it("should not be void", function () { + bbox.isVoid.should.equal(false); + }); + it("should have nearPt to be correct", function () { + bbox.nearPt.x.should.equal(10); + bbox.nearPt.y.should.equal(20); + bbox.nearPt.z.should.equal(30); + }); + it("should have farPt to be correct", function () { + bbox.farPt.x.should.equal(10); + bbox.farPt.y.should.equal(20); + bbox.farPt.z.should.equal(30); + }); + }); + describe("checking calling isOut on a empty box", function () { + it("should return isOut = true for any point ", function () { + let bbox = new __1.BoundingBox(); + bbox.isOut([10, 20, 30]).should.equal(true); + }); + }); + describe("checking calling isOut this box [-10,-10,-10],[5,5,5]", function () { + let bbox = new __1.BoundingBox([-10, -10, -10], [5, 5, 5]); + it("should return isOut = true for [10,20,30] ", function () { + bbox.isOut([10, 20, 30]).should.equal(true); + }); + it("should return isOut = false for [1,2,3] ", function () { + bbox.isOut([1, 2, 3]).should.equal(false); + }); + }); +}); diff --git a/dist-test/test_ReadWriteSTEP.d.ts b/dist-test/test_ReadWriteSTEP.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_ReadWriteSTEP.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/dist-test/test_ReadWriteSTEP.js b/dist-test/test_ReadWriteSTEP.js new file mode 100644 index 0000000..3611812 --- /dev/null +++ b/dist-test/test_ReadWriteSTEP.js @@ -0,0 +1,103 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/*eslint-env node mocha*/ +/*global require*/ +// test_STEP +const assert_1 = __importDefault(require("assert")); +require("should"); +const __1 = require(".."); +const helpers_1 = require("./helpers"); +describe("testing STEP input output ", function () { + let b1_step; + let b2_step; + let b3_step; + before(function () { + b1_step = (0, helpers_1. + mporaryFilePath)({ prefix: "b1_", suffix: ".step" }); + b2_step = (0, helpers_1.getTemporaryFilePath)({ prefix: "b2_", suffix: ".step" }); + b3_step = (0, helpers_1.getTemporaryFilePath)({ prefix: "b3_", suffix: ".step" }); + let box = __1.occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1 = __1.occ.writeSTEP(b1_step, box); + let cyl = __1.occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); + let b2 = __1.occ.writeSTEP(b2_step, cyl); + let b3 = __1.occ.writeSTEP(b3_step, [box, cyl]); + b1.should.eql(true); + b2.should.eql(true); + b3.should.eql(true); + }); + after(function () { + (0, helpers_1.removeFile)(b1_step); + (0, helpers_1.removeFile)(b2_step); + (0, helpers_1.removeFile)(b3_step); + }); + it("AZ0 - should write a simple shape", function (done) { + let box = __1.occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1 = __1.occ.writeSTEP(b1_step, box); + done(); + }); + it("AZ1 - readSTEP with callback ", function (done) { + __1.occ.readSTEP(b3_step, (err, shapes) => { + console.log(err, shapes); + shapes.length.should.equal(2); + shapes[0].numFaces.should.equal(6); + shapes[1].numFaces.should.equal(3); + done(); + }); + }); + it("AZ2 - should raise an exception with invalid arguments", function () { + (function () { + __1.occ.readSTEP(); + }).should.throwError(); + (function () { + __1.occ.readSTEP("filename"); + }).should.throwError(); + }); + it("AZ3 - should call the callback with an error if the file doesn't exist", function (done) { + __1.occ.readSTEP("invalid file name", function (err, shapes) { + if (err) { + err.message.should.match(/invalid file name/); + } + else { + return done(new Error("Expecting Error")); + } + done(); + }); + }); + it("AZ4 - should read file one", function (done) { + __1.occ.readSTEP(b1_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + (0, assert_1.default)(!err); + shapes.length.should.equal(1); + shapes[0].numFaces.should.equal(6); + done(); + }); + }); + it("AZ5 - should read file two", function (done) { + __1.occ.readSTEP(b2_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + (0, assert_1.default)(!err); + shapes.length.should.equal(1); + shapes[0].numFaces.should.equal(3); + done(); + }); + }); + it("AZ6 - should read file three", function (done) { + __1.occ.readSTEP(b3_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + (0, assert_1.default)(!err); + shapes.length.should.equal(2); + shapes[0].numFaces.should.equal(6); + shapes[1].numFaces.should.equal(3); + done(); + }); + }); +}); diff --git a/dist-test/test_applyTransform.d.ts b/dist-test/test_applyTransform.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_applyTransform.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/dist-test/test_applyTransform.js b/dist-test/test_applyTransform.js new file mode 100644 index 0000000..c913614 --- /dev/null +++ b/dist-test/test_applyTransform.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +require("should"); +describe("testing various transformation", function () { + function getVerticeData(box) { + let vert = box.getVertices(); + const triplets = vert.map((v) => [v.x, v.y, v.z]); + triplets.length.should.eql(8); + return triplets; + } + function add(v1, v2) { + return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]]; + } + it("#applyTransform", function () { + let box = __1.occ.makeBox([0, 0, 0], [100, 200, 300]); + let trsf = new __1.Transformation(); + trsf.makeTranslation([10, 20, 30]); + let vert = getVerticeData(box); + vert[1].should.eql([0, 0, 0]); + box.applyTransform(trsf); + let vert_after = getVerticeData(box); + // translate vertex + vert = vert.map((v) => add(v, [10, 20, 30])); + vert_after.should.eql(vert); + }); +}); diff --git a/dist-test/test_edge.d.ts b/dist-test/test_edge.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_edge.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist-test/test_edge.js b/dist-test/test_edge.js new file mode 100644 index 0000000..5eae69e --- /dev/null +++ b/dist-test/test_edge.js @@ -0,0 +1,137 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); +const { makeLine } = __1.occ; +describe("testing Edges ", function () { + describe("EDGE0 - constructing an empty Edge", function () { + let edge; + before(function () { + edge = new __1.Edge(); + should_1.default.exist(edge); + }); + it("should be valid", function () { + edge.isNull.should.equal(true); + }); + it("should have a zero length", function () { + edge.length.should.equal(0); + }); + it("should have a zero vertices", function () { + edge.numVertices.should.equal(0); + }); + it("should be degenerated", function () { + edge.isDegenerated.should.equal(true); + }); + it("shouldn't be closed", function () { + edge.isClosed.should.equal(false); + }); + it("should provide a bounding box", function () { + edge.getBoundingBox().should.be.instanceOf(__1.BoundingBox); + edge.getBoundingBox().isVoid.should.eql(true); + }); + }); + describe("Wire1 - an Wire constructed as as a linear Segment between (10,20,30) and (-30,20,30) ", function () { + let wire; + before(function () { + let v1 = new __1.Vertex(10, 20, 30); + let v2 = new __1.Vertex(-30, 20, 30); + wire = makeLine(v1, v2); + wire.should.be.instanceOf(__1.Edge); + }); + it("should have a length of 40.0 ", function () { + wire.length.should.equal(40.0); + }); + it("should have two vertices ", function () { + wire.numVertices.should.equal(2.0); + }); + it("shouldn't be closed", function () { + wire.isClosed.should.equal(false); + }); + it("shouldn't be degenerated", function () { + wire.isDegenerated.should.equal(false); + }); + it("should provide a bounding box", function () { + wire.getBoundingBox().should.be.instanceOf(__1.BoundingBox); + wire.getBoundingBox().isVoid.should.eql(false); + wire.getBoundingBox().nearPt.equals(new __1.Point(-30, 20, 30)).should.eql(true); + wire.getBoundingBox().nearPt.equals([-30, 20, 30]).should.eql(true); + wire.getBoundingBox().farPt.equals([10, 20, 30]).should.eql(true); + let extra = 0.000000000001; + wire.getBoundingBox().farPt.asArray().should.eql([10 + extra, 20 + extra, 30 + extra]); + }); + it("should polygonize a segment with two points", function () { + console.log("polyligonize"); + let polyline = wire.polygonize(); + console.log("polyligonize2"); + polyline.length.should.eql(3 * 2); + [polyline[0], polyline[1], polyline[2]].should.eql([10, 20, 30]); + let l = polyline.length; + (l % 3).should.eql(0); + [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([-30, 20, 30]); + }); + }); + describe("EDGE2 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) and translated by [1,2,3]", function () { + let wire; + before(function () { + let v1 = __1.occ.makeVertex(10, 20, 30); + let v2 = __1.occ.makeVertex(-30, 20, 30); + wire = __1.occ.makeLine(v1, v2); + wire = wire.translate([1, 2, 3]); + }); + it("should have a length of 40.0 ", function () { + wire.length.should.equal(40.0); + }); + it("should provide a bounding box", function () { + wire.getBoundingBox().nearPt.equals([-29, 22, 33]).should.eql(true); + wire.getBoundingBox().farPt.equals([11, 22, 33]).should.eql(true); + }); + it("should polygonize a segment with two points", function () { + let polyline = wire.polygonize(); + polyline.length.should.eql(3 * 2); + [polyline[0], polyline[1], polyline[2]].should.eql([11, 22, 33]); + let l = polyline.length; + (l % 3).should.eql(0); + [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([-29, 22, 33]); + }); + }); + describe("Wire - an Wire constructed as a Circle on the Z+ plan with a radius of 20", function () { + let wire; + before(function () { + wire = __1.occ.makeCircle([10, 10, 10], [0, 0, 1], 20); + }); + it("should have a length of 2*PI*20.0 ", function () { + let epsilon = 1E-2; + let PI = 3.1415; + wire.length.should.be.within(2 * PI * 20.0 - epsilon, 2 * PI * 20.0 + epsilon); + }); + it("should have a unique vertex ", function () { + wire.numVertices.should.equal(1); + }); + it("should be closed", function () { + wire.isClosed.should.equal(true); + }); + it("shouldn't be degenerated", function () { + wire.isDegenerated.should.equal(false); + }); + it("should provide a bounding box", function () { + wire.getBoundingBox().should.be.instanceOf(__1.BoundingBox); + wire.getBoundingBox().isVoid.should.eql(false); + //xx console.log(JSON.stringify(edge.getBoundingBox()));//.toString()); + wire.getBoundingBox().nearPt.equals([-11.647844, -11.647844, 10]); + wire.getBoundingBox().farPt.equals([31.647844, 31.647844, 10]); + }); + it("should polygonize a edge", function () { + let a = wire.polygonize(); + [a[0], a[1], a[2]].should.eql([30, 10, 10]); + let l = a.length; + (l % 3).should.eql(0); + [a[l - 3], a[l - 2], a[l - 1]].should.eql([30, 10, 10]); + //xx console.log(a); + }); + }); + describe("EDGE4 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) ", function () { + }); +}); diff --git a/dist-test/test_extrudeFace.d.ts b/dist-test/test_extrudeFace.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_extrudeFace.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/dist-test/test_extrudeFace.js b/dist-test/test_extrudeFace.js new file mode 100644 index 0000000..580bbd1 --- /dev/null +++ b/dist-test/test_extrudeFace.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +require("should"); +describe("demonstrate how to extrude a face", function () { + it("extrudeFace", function () { + // create a planar wire close line. + const aPnt1 = [0, 0.0, 0]; + const aPnt2 = [10, 1.0, 0]; + const aPnt3 = [10, 9.0, 0]; + const aPnt4 = [0, 10.0, 0]; + const aSegment1 = __1.occ.makeLine(aPnt1, aPnt2); + const aSegment2 = __1.occ.makeLine(aPnt2, aPnt3); + const aSegment3 = __1.occ.makeLine(aPnt3, aPnt4); + const aSegment4 = __1.occ.makeLine(aPnt4, aPnt1); + const aWire = __1.occ.makeWire(aSegment1, aSegment2, aSegment3, aSegment4); + aWire.isClosed.should.equal(true); + aWire.numEdges.should.equal(4); + aWire.numVertices.should.equal(4); + // the vector to extrude the face along. + const aVector = [-2, -2.0, 10]; + const aFace = __1.occ.makeFace(aWire); + const myBody = __1.occ.makePrism(aFace, aVector); + __1.occ.writeSTEP("extrudedFace.step", [myBody]); + }); +}); diff --git a/dist-test/test_face.d.ts b/dist-test/test_face.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_face.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_face.js b/dist-test/test_face.js similarity index 70% rename from test/test_face.js rename to dist-test/test_face.js index 57aa92a..aeca65e 100644 --- a/test/test_face.js +++ b/dist-test/test_face.js @@ -1,66 +1,46 @@ -const assert = require("assert"); -const should = require("should"); - -const occ = require("../lib/occ"); - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); // see https://npmjs.org/package/should - -describe("testing face mesh ",function() { - +describe("testing face mesh ", function () { it("Face#mesh - should not have a mesh unless the parent solid has been meshed", function () { - // given a box solid - let solid = occ.makeBox([0,0,0],[10,10,10]); - + let solid = __1.occ.makeBox([0, 0, 0], [10, 10, 10]); solid.faces.should.have.property("top"); - let topFace = solid.faces.top; - should.exist(topFace); - + should_1.default.exist(topFace); topFace.area.should.be.within(99.99, 100.0, "face area shall be 100.00"); - topFace.hasMesh.should.equal(false); - // now mesh the solid let m = solid.mesh; m.vertices.length.should.eql(8 * 3, "expecting 8 vertices (made of 3 floats) in solid mesh"); m.edgeIndices.length.should.eql(24); m.triangles.length.should.eql(36); - //xx console.log(m.toJSON()); - // meshing the solid should cause each of its faces to be meshed topFace.hasMesh.should.equal(true, "Face must have a mesh when parent solid is meshed"); - //xx m.normals.length.should.eql(72); //xx console.log(topFace.mesh.toJSON()); let faceMesh = topFace.mesh; - faceMesh.vertices.length.should.eql(3 * 4, "we expect 4 points "); //xx faceMesh.normals.length.should.eql(3 * 4); faceMesh.edgeIndices.length.should.eql(2 * 4); faceMesh.triangles.length.should.eql(2 * 3); - }); }); - describe("testing face#getWire ", function () { - - it("Face#getWire", function () { - - let solid = occ.makeBox([0, 0, 0], [10, 10, 10]); + let solid = __1.occ.makeBox([0, 0, 0], [10, 10, 10]); solid.faces.should.have.property("top"); let topFace = solid.faces.top; - should.exist(topFace); - + should_1.default.exist(topFace); let wires = topFace.getWires(); wires.length.should.eql(1); - wires[0].getEdges().length.should.eql(4); - - wires[0].getEdges()[0].getVertices()[0].should.eql(new occ.Vertex({x: 0, y: 10, z: 10})); - - + wires[0].getEdges()[0].getVertices()[0].should.eql(new __1.Vertex({ x: 0, y: 10, z: 10 })); }); }); diff --git a/dist-test/test_fastbuilder.d.ts b/dist-test/test_fastbuilder.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_fastbuilder.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/test/test_fastbuilder.js b/dist-test/test_fastbuilder.js similarity index 53% rename from test/test_fastbuilder.js rename to dist-test/test_fastbuilder.js index 2defae3..927af31 100644 --- a/test/test_fastbuilder.js +++ b/dist-test/test_fastbuilder.js @@ -1,119 +1,90 @@ -const fastBuilder_ = require("../lib/fastbuilder"); -const fast_occ = fastBuilder_.occ; -const fastBuilder = fastBuilder_.fastBuilder; - +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +require("should"); +const fast_occ = __1.occ; function makeShape() { let e = 20; let s1 = fast_occ.makeBox([10, e, 30], [110, 120, 130]); let s2 = fast_occ.makeBox(100, 200, 300); let s3 = fast_occ.fuse(s1, s2); - s3 = s3.translate([0,20,30]); - s3= s3.translate([0,20,30]); + s3 = s3.translate([0, 20, 30]); + s3 = s3.translate([0, 20, 30]); return s3; } - function startChronometer() { return process.hrtime(); } function stopChronometer(time1) { - let diff1 = process.hrtime(time1); - diff1 = (diff1[0]*1E9+diff1[1]); // in nanoseconds - diff1 /= 1000.0; // in microseconds - diff1 /= 1000.0; // in miliseconds - diff1 /= 1000.0; // in seconds + let diff0 = process.hrtime(time1); + let diff1 = (diff0[0] * 1E9 + diff0[1]); // in nanoseconds + diff1 /= 1000.0; // in microseconds + diff1 /= 1000.0; // in miliseconds + diff1 /= 1000.0; // in seconds return diff1; } - - - -describe("testing geometry builder",function(){ - - before(function(){ - fastBuilder.resetCache(); +describe("testing geometry builder", function () { + before(function () { + __1.fastBuilder.resetCache(); }); - it("should create a bottle faster the second time ", function() { - - fastBuilder.mapQueryCount.should.equal(0); - fastBuilder.mapHit.should.equal(0); - + it("should create a bottle faster the second time ", function () { + __1.fastBuilder.mapQueryCount.should.equal(0); + __1.fastBuilder.mapHit.should.equal(0); let c1 = startChronometer(); makeShape(); let diff1 = stopChronometer(c1); - - fastBuilder.mapQueryCount.should.equal(5); - fastBuilder.mapHit.should.equal(0); - + __1.fastBuilder.mapQueryCount.should.equal(5); + __1.fastBuilder.mapHit.should.equal(0); let c2 = startChronometer(); makeShape(); let diff2 = stopChronometer(c2); - - - fastBuilder.mapQueryCount.should.equal(10); - fastBuilder.mapHit.should.equal(5); - - console.log(" time to compute first box = ", diff1 ," seconds"); - console.log(" time to compute second box = ", diff2 ," seconds" ); - console.log(" speed up = ", Math.round( (diff1-diff2)/diff2*100,2) ,"%" ); - + __1.fastBuilder.mapQueryCount.should.equal(10); + __1.fastBuilder.mapHit.should.equal(5); + console.log(" time to compute first box = ", diff1, " seconds"); + console.log(" time to compute second box = ", diff2, " seconds"); + console.log(" speed up = ", Math.round((diff1 - diff2) / diff2 * 100), "%"); diff1.should.be.greaterThan(diff2); - }); }); - - -describe("testing calculateOperationHash",function(){ - +describe("testing calculateOperationHash", function () { let fastbuilder = require("../lib/fastbuilder"); - let calculateOperationHash = function () { - return fastbuilder.calculateOperationHash("myFunc",arguments); + let calculateOperationHash = function (...args) { + return fastbuilder.calculateOperationHash("myFunc", arguments); }; - - before(function(){ - + before(function () { }); - it("should calculate the hash of [10,20,30]",function(){ + it("should calculate the hash of [10,20,30]", function () { calculateOperationHash([10, 20, 30])[1].should.equal("myFunc([10,20,30])"); }); }); - - -describe("testing fast builder with array of shape",function(){ - - before(function(){ - fastBuilder.resetCache(); +describe("testing fast builder with array of shape", function () { + before(function () { + __1.fastBuilder.resetCache(); }); - it("should create a bottle faster the second time ", function() { - - fastBuilder.mapQueryCount.should.equal(0); - fastBuilder.mapHit.should.equal(0); + it("should create a bottle faster the second time ", function () { + __1.fastBuilder.mapQueryCount.should.equal(0); + __1.fastBuilder.mapHit.should.equal(0); let a = []; a.push(makeShape()); - a.push(makeShape().translate(10,20,30)); - a.push(makeShape().translate(30,20,30)); - + a.push(makeShape().translate(10, 20, 30)); + a.push(makeShape().translate(30, 20, 30)); let compound = fast_occ.compound(a); - }); }); - -describe("testing fast builder with makeThickSolid" , function() { +describe("testing fast builder with makeThickSolid", function () { let s1; let s2; - before(function(){ - s1 = fast_occ.makeBox([10,20,30],[110,120,130]); - s1 = fast_occ.makeThickSolid(s1,s1.faces.top,6); - + before(function () { + s1 = fast_occ.makeBox([10, 20, 30], [110, 120, 130]); + s1 = fast_occ.makeThickSolid(s1, s1.faces.top, 6); let occ = require("../lib/occ"); - s2 = occ.makeBox([10,20,30],[110,120,130]); - s2 = occ.makeThickSolid(s2,s2.faces.top,6); - + s2 = occ.makeBox([10, 20, 30], [110, 120, 130]); + s2 = occ.makeThickSolid(s2, s2.faces.top, 6); }); - it(" should construct the same object as if using 'occ' ",function(){ + it(" should construct the same object as if using 'occ' ", function () { s1.numFaces.should.equal(s2.numFaces); }); }); - - let factory = require("../lib/shapeFactory.js"); describe("testing fast builder with some built-in shapes", function () { let fastbuilder = require("../lib/fastbuilder"); @@ -122,22 +93,16 @@ describe("testing fast builder with some built-in shapes", function () { s1.numFaces.should.be.greaterThan(16); }); }); - describe("testing fast builder with some shapes", function () { - it("should create the piston..", function () { let fastbuilder = require("../lib/fastbuilder"); let s1 = factory.makePiston(fastbuilder.occ); s1.numFaces.should.be.greaterThan(7); }); }); - - - -describe("testing fast builder get Common Edge" , function() { +describe("testing fast builder get Common Edge", function () { let solid1; let solid2; - function buildFilletOnTopLeftEdge() { let s1 = fast_occ.makeBox([10, 20, 30], [110, 120, 130]); let edges = s1.getCommonEdges(s1.faces.front, s1.faces.left); @@ -145,7 +110,6 @@ describe("testing fast builder get Common Edge" , function() { s1 = fast_occ.makeDraftAngle(s1, s1.faces["mleft:0"], 0.1, s1.faces["mbottom:0"]); return s1; } - before(function () { solid1 = buildFilletOnTopLeftEdge(); solid2 = buildFilletOnTopLeftEdge(); @@ -155,64 +119,47 @@ describe("testing fast builder get Common Edge" , function() { solid2.numFaces.should.be.equal(7); }); }); - - -describe("testing fast-builder with impossible cone" , function () { - let solid1 = 0; +describe("testing fast-builder with impossible cone", function () { + let solid1; before(function () { // this cone cannot be built : it has PI/2 for half-angle ! }); - it("should have no solid",function(){ - (function() { - solid1 = fast_occ.makeCone( [0,0,0] , [0,0,1] , 1.5707963267948966 , 10); + it("should have no solid", function () { + (function () { + solid1 = fast_occ.makeCone([0, 0, 0], [0, 0, 1], 1.5707963267948966, 10); }).should.throwError(); }); }); - -describe("testing fast-builder with LEGO brick" , function () { - +describe("testing fast-builder with LEGO brick", function () { this.timeout(10000); - - it("should produce a LEGO brick",function(){ - + it("should produce a LEGO brick", function () { let factory = require("../lib/shapeFactory.js"); - function buildBrick() { - let nx = 3; let ny = 6; let brick24 = factory.makeLegoBrick(fast_occ, nx, ny, "thick"); - brick24.numFaces.should.be.greaterThan(40); - // now check with bounding box let bbox = brick24.getBoundingBox(); - let eps = 0.01; - bbox.nearPt.x.should.be.within(0-eps,0+eps); - bbox.nearPt.y.should.be.within(0-eps,0+eps); - bbox.nearPt.z.should.be.within(0-eps,0+eps); - + bbox.nearPt.x.should.be.within(0 - eps, 0 + eps); + bbox.nearPt.y.should.be.within(0 - eps, 0 + eps); + bbox.nearPt.z.should.be.within(0 - eps, 0 + eps); bbox.farPt.x.should.be.within(nx * 8 - eps, nx * 8 + eps); bbox.farPt.y.should.be.within(ny * 8 - eps, ny * 8 + eps); - bbox.farPt.z.should.be.within(11.2-eps,11.2+eps); + bbox.farPt.z.should.be.within(11.2 - eps, 11.2 + eps); } - let c1 = startChronometer(); buildBrick(); let diff1 = stopChronometer(c1); - let c2 = startChronometer(); buildBrick(); let diff2 = stopChronometer(c2); - - console.log(" time to compute first box = ", diff1 ," seconds" ); - console.log(" time to compute second box = ", diff2 ," seconds"); - let speedup = Math.round( (diff1-diff2)/diff2*100,2); - console.log(" speed up = ", speedup ,"%" ); - + console.log(" time to compute first box = ", diff1, " seconds"); + console.log(" time to compute second box = ", diff2, " seconds"); + let speedup = Math.round((diff1 - diff2) / diff2 * 100); + console.log(" speed up = ", speedup, "%"); diff1.should.be.greaterThan(diff2); speedup.should.be.greaterThan(100); //"%" - }); }); diff --git a/dist-test/test_geometry.d.ts b/dist-test/test_geometry.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_geometry.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist-test/test_geometry.js b/dist-test/test_geometry.js new file mode 100644 index 0000000..8bc9d6c --- /dev/null +++ b/dist-test/test_geometry.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +const helpers_1 = require("./helpers"); +const __2 = require(".."); +describe("testing geometry builder", function () { + it("should create a bottle", function () { + let bottle_brep = (0, helpers_1.getTemporaryFilePath)({ prefix: "bottle", suffix: ".brep" }); + let bottle = (0, __2.makeBottle)(__1.occ, { height: 100, filletRadius: 2 }); + __1.occ.writeBREP(bottle_brep, bottle); + }); +}); diff --git a/dist-test/test_issue17_mesh_not_invalidated_when_face_moved.d.ts b/dist-test/test_issue17_mesh_not_invalidated_when_face_moved.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_issue17_mesh_not_invalidated_when_face_moved.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/test/test_issue17_mesh_not_invalidated_when_face_moved.js b/dist-test/test_issue17_mesh_not_invalidated_when_face_moved.js similarity index 82% rename from test/test_issue17_mesh_not_invalidated_when_face_moved.js rename to dist-test/test_issue17_mesh_not_invalidated_when_face_moved.js index 17e1223..4633b5e 100644 --- a/test/test_issue17_mesh_not_invalidated_when_face_moved.js +++ b/dist-test/test_issue17_mesh_not_invalidated_when_face_moved.js @@ -1,90 +1,65 @@ "use strict"; -const occ = require("../lib/occ"); -const should = require("should"); - +Object.defineProperty(exports, "__esModule", { value: true }); +const __1 = require(".."); +require("should"); const doDebug = false; -function debugLog() { +function debugLog(...args) { if (doDebug) { - console.log.apply(console, arguments); + console.log.apply(console, args); } } describe("issue#17 testing that mesh get invalidated ", function () { - - function constructFaceWithWire() { const aPnt1 = [0, 0.0, 0]; const aPnt2 = [10, 1.0, 0]; const aPnt3 = [10, 9.0, 0]; const aPnt4 = [0, 10.0, 0]; - const segment1 = new occ.makeLine(aPnt1, aPnt2); - const segment2 = new occ.makeLine(aPnt2, aPnt3); - const segment3 = new occ.makeLine(aPnt3, aPnt4); - const segment4 = new occ.makeLine(aPnt4, aPnt1); - - const wire = new occ.Wire(segment1, segment2, segment3, segment4); + const segment1 = __1.occ.makeLine(aPnt1, aPnt2); + const segment2 = __1.occ.makeLine(aPnt2, aPnt3); + const segment3 = __1.occ.makeLine(aPnt3, aPnt4); + const segment4 = __1.occ.makeLine(aPnt4, aPnt1); + const wire = __1.occ.makeWire(segment1, segment2, segment3, segment4); wire.isClosed.should.equal(true); wire.numEdges.should.equal(4); wire.numVertices.should.equal(4); - // the vector to extrude the face along. - const face = new occ.Face(wire); - + const face = __1.occ.makeFace(wire); face.getWires().length.should.eql(1); - face.getWires()[0].getVertices().length.should.eql(4); return face; } - it("should translate a face", function (done) { let face = constructFaceWithWire(); - const vertices_before = face.getWires()[0].getVertices(); - face = face.translate([20, 30, 40]); const vertices_after = face.getWires()[0].getVertices(); - vertices_after[0].x.should.eql(vertices_before[0].x + 20); vertices_after[0].y.should.eql(vertices_before[0].y + 30); vertices_after[0].z.should.eql(vertices_before[0].z + 40); - vertices_after[1].x.should.eql(vertices_before[1].x + 20); vertices_after[1].y.should.eql(vertices_before[1].y + 30); vertices_after[1].z.should.eql(vertices_before[1].z + 40); - vertices_after[2].x.should.eql(vertices_before[2].x + 20); vertices_after[2].y.should.eql(vertices_before[2].y + 30); vertices_after[2].z.should.eql(vertices_before[2].z + 40); - vertices_after[3].x.should.eql(vertices_before[3].x + 20); vertices_after[3].y.should.eql(vertices_before[3].y + 30); vertices_after[3].z.should.eql(vertices_before[3].z + 40); - done(); }); - it("#17-B should provide a translated mesh when face is translated", function (done) { - let face = constructFaceWithWire(); face.hasMesh.should.equal(false); - // now mesh the faces face.createMesh(0.1); face.hasMesh.should.equal(true); - debugLog("face mesh vertices =", face.mesh.vertices.toString()); - - const vertices_before = face.mesh.vertices; face = face.translate([20, 30, 40]); - debugLog("face mesh vertices =", face.mesh.vertices.toString()); - const vertices_after = face.mesh.vertices; - vertices_before.toString().should.eql("0,0,0,10,1,0,10,9,0,0,10,0"); vertices_after.toString().should.eql("20,30,40,30,31,40,30,39,40,20,40,40"); done(); }); }); - - diff --git a/dist-test/test_meshSolid.d.ts b/dist-test/test_meshSolid.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_meshSolid.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/test/test_meshSolid.js b/dist-test/test_meshSolid.js similarity index 90% rename from test/test_meshSolid.js rename to dist-test/test_meshSolid.js index 640de46..d58f3b6 100644 --- a/test/test_meshSolid.js +++ b/dist-test/test_meshSolid.js @@ -1,20 +1,22 @@ -const assert = require("assert"); -const should = require("should"); - -const nodeocc = require(".."); -const occ = nodeocc.occ; +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +require("should"); +const __1 = require(".."); +const __2 = __importDefault(require("..")); const doDebug = false; - -function debugLog() { +function debugLog(...args) { arguments; /* implement me*/ } - describe("TBugLinux- testing mesh on a simple cone shape with radius2 = 0 returns 2 Faces (latteral+bottom)", function () { // cf. https://github.com/antonymarion/node-occ-csg-editor-display/runs/1517044830?check_suite_focus=true - let shape, mesh; + let shape; + let mesh; before(function () { - shape = occ.makeCone([0, 0, 0], 2, [0, 0, 2], 0); + shape = __1.occ.makeCone([0, 0, 0], 2, [0, 0, 2], 0); mesh = shape.createMesh(0.1); }); it("solid should have 2 faces", function () { @@ -22,7 +24,6 @@ describe("TBugLinux- testing mesh on a simple cone shape with radius2 = 0 return console.log("shape", shape); console.log("cone Faces", myFaces); myFaces.length.should.eql(2); - // meshing should work on Linux ! (was not working w/ Linux pre compiled occ.node) shape .hasMesh.should.be.eql(true); @@ -32,15 +33,13 @@ describe("TBugLinux- testing mesh on a simple cone shape with radius2 = 0 return shape.faces["bottom"] .hasMesh .should.be.eql(true); - }); }); - describe("T1- testing mesh on a simple box shape", function () { - - let shape, mesh; + let shape; + let mesh; before(function () { - shape = occ.makeBox(10, 40, 100); + shape = __1.occ.makeBox(10, 40, 100); mesh = shape.createMesh(0.1); }); it("solid should have 6 faces", function () { @@ -49,27 +48,21 @@ describe("T1- testing mesh on a simple box shape", function () { it("Mesh#vertices - mesh should provide a vertex array", function () { // ----------------------------------- testing vertices mesh.vertices.length.should.eql(3 * 8); - mesh.vertices[0].should.eql(0.0); mesh.vertices[1].should.eql(0.0); mesh.vertices[2].should.eql(0.0); - mesh.vertices[3].should.eql(0.0); mesh.vertices[4].should.eql(0.0); mesh.vertices[5].should.eql(100.0); - mesh.vertices[6].should.eql(0.0); mesh.vertices[7].should.eql(40.0); mesh.vertices[8].should.eql(0.0); - mesh.vertices[9].should.eql(0.0); mesh.vertices[10].should.eql(40.0); mesh.vertices[11].should.eql(100.0); - mesh.vertices[12].should.eql(10.0); mesh.vertices[13].should.eql(0.0); mesh.vertices[14].should.eql(0.0); - }); it("Mesh#triangle - mesh should provide triangles indexes", function () { // --------------------------------------- triangles @@ -78,28 +71,22 @@ describe("T1- testing mesh on a simple box shape", function () { it("Mesh#faceRanges - mesh should provide a mechanism to easily identify triangle faces", function () { mesh.faceRanges.length.should.eql(6 * 2, "it should 6 pairs of index ( 6 faces, 2 values per face)"); mesh.edgeRanges.length.should.eql(12 * 2, "it should 12 pairs of index ( 12 edges, 2 values per face)"); - // --------------------------------------- faces // testing face 1 mesh.faceRanges[0].should.eql(0); // start in triangle index mesh.faceRanges[1].should.eql(2); // nb of triangles - // testing face 2 mesh.faceRanges[2].should.eql(2); // start in triangle index mesh.faceRanges[3].should.eql(2); // nb of triangles - // testing face 3 mesh.faceRanges[4].should.eql(4); // start in triangle index mesh.faceRanges[5].should.eql(2); // nb of triangles - // testing face 4 mesh.faceRanges[6].should.eql(6); // start in triangle index mesh.faceRanges[7].should.eql(2); // nb of triangles - // testing face 5 mesh.faceRanges[8].should.eql(8); // start in triangle index mesh.faceRanges[9].should.eql(2); // nb of triangles - // testing face 6 mesh.faceRanges[10].should.eql(10); // start in triangle index mesh.faceRanges[11].should.eql(2); // nb of triangles @@ -108,7 +95,6 @@ describe("T1- testing mesh on a simple box shape", function () { // --------------------------------------- face accessor let arr = mesh.getFaceTriangles(shape.getFaces()[0]); arr.should.eql(new Uint8Array([0, 1, 2, 2, 1, 3])); - arr = mesh.getFaceTriangles(shape.getFaces()[1]); arr.should.eql(new Uint8Array([5, 4, 6, 5, 6, 7])); // etc... @@ -119,61 +105,46 @@ describe("T1- testing mesh on a simple box shape", function () { // testing edge 1 mesh.edgeRanges[0].should.eql(0); // start in triangle index mesh.edgeRanges[1].should.eql(2); // nb of triangles - // testing edge 2 mesh.edgeRanges[2].should.eql(2); // start in triangle index mesh.edgeRanges[3].should.eql(2); // nb of triangles - // testing edge 3 mesh.edgeRanges[4].should.eql(4); // start in triangle index mesh.edgeRanges[5].should.eql(2); // nb of triangles - // testing edge 4 mesh.edgeRanges[6].should.eql(6); // start in triangle index mesh.edgeRanges[7].should.eql(2); // nb of triangles - // testing edge 5 mesh.edgeRanges[8].should.eql(8); // start in triangle index mesh.edgeRanges[9].should.eql(2); // nb of triangles - // testing edge 6 mesh.edgeRanges[10].should.eql(10); // start in triangle index mesh.edgeRanges[11].should.eql(2); // nb of triangles - // testing edge 7 mesh.edgeRanges[12].should.eql(12); // start in triangle index mesh.edgeRanges[13].should.eql(2); // nb of triangles - // testing edge 8 mesh.edgeRanges[14].should.eql(14); // start in triangle index mesh.edgeRanges[15].should.eql(2); // nb of triangles - // testing edge 9 mesh.edgeRanges[16].should.eql(16); // start in triangle index mesh.edgeRanges[17].should.eql(2); // nb of triangles - // testing edge 10 mesh.edgeRanges[18].should.eql(18); // start in triangle index mesh.edgeRanges[19].should.eql(2); // nb of triangles - // testing edge 11 mesh.edgeRanges[20].should.eql(20); // start in triangle index mesh.edgeRanges[21].should.eql(2); // nb of triangles - // testing edge 12 mesh.edgeRanges[22].should.eql(22); // start in triangle index mesh.edgeRanges[23].should.eql(2); // nb of triangles - }); - it("Mesh#getEdgeIndices - mesh should provide a mechanism to extract the Polygon of a given edge", function () { //xx console.log(mesh); const arr = mesh.getEdgeIndices(shape.getEdges()[0]); arr.should.eql(new Uint8Array([0, 1])); - }); it("Mesh#triangleNormals - mesh should provide ", function () { - // face 0 - triangle 0 mesh.triangleNormals[0].should.eql(0); mesh.triangleNormals[1].should.eql(0); @@ -182,7 +153,6 @@ describe("T1- testing mesh on a simple box shape", function () { mesh.triangleNormals[3].should.eql(0); mesh.triangleNormals[4].should.eql(0); mesh.triangleNormals[5].should.eql(0); - // face 1 - triangle 0 mesh.triangleNormals[6].should.eql(1); mesh.triangleNormals[7].should.eql(1); @@ -191,7 +161,6 @@ describe("T1- testing mesh on a simple box shape", function () { mesh.triangleNormals[9].should.eql(1); mesh.triangleNormals[10].should.eql(1); mesh.triangleNormals[11].should.eql(1); - // face 2 - triangle 0= mesh.triangleNormals[12].should.eql(2); mesh.triangleNormals[13].should.eql(2); @@ -200,7 +169,6 @@ describe("T1- testing mesh on a simple box shape", function () { mesh.triangleNormals[15].should.eql(2); mesh.triangleNormals[16].should.eql(2); mesh.triangleNormals[17].should.eql(2); - // face 3 - triangle 0= mesh.triangleNormals[18].should.eql(3); mesh.triangleNormals[19].should.eql(3); @@ -209,120 +177,92 @@ describe("T1- testing mesh on a simple box shape", function () { mesh.triangleNormals[21].should.eql(3); mesh.triangleNormals[22].should.eql(3); mesh.triangleNormals[23].should.eql(3); - // etc... }); it("Mesh#normals - mesh should provide a normal array", function () { // in the case of a simple box we expect to have 6 different normals mesh.normals.length.should.eql(3 * 6); - // first normal mesh.normals[0].should.eql(-1); mesh.normals[1].should.eql(0); mesh.normals[2].should.eql(0); - mesh.normals[3].should.eql(1); mesh.normals[4].should.eql(0); mesh.normals[5].should.eql(0); - mesh.normals[6].should.eql(0); mesh.normals[7].should.eql(-1); mesh.normals[8].should.eql(0); - mesh.normals[9].should.eql(0); mesh.normals[10].should.eql(1); mesh.normals[11].should.eql(0); - mesh.normals[12].should.eql(0); mesh.normals[13].should.eql(0); mesh.normals[14].should.eql(-1); - mesh.normals[15].should.eql(0); mesh.normals[16].should.eql(0); mesh.normals[17].should.eql(1); }); - }); - describe("testing performance of meshing algorithms with various parameters", function () { - - this.timeout(30000); - function makeUnitBox() { - return occ.makeBox([0, 0, 0], [100, 100, 100]); + return __1.occ.makeBox([0, 0, 0], [100, 100, 100]); } - function makeSphere() { - return occ.makeSphere([0, 0, 0], 100); + return __1.occ.makeSphere([0, 0, 0], 100); } - function makeLegoBrick() { - return nodeocc.shapeFactory.makeLegoBrick(occ, 4, 2, "thin"); + return __2.default.makeLegoBrick(__1.occ, 4, 2, "thin"); } - - function installFor(makeShape) { - + function installFor(name, makeShape) { let shape2; beforeEach(function () { shape2 = makeShape(); }); - function test_with(tol, angle) { - it(makeShape.name + " testing with parameter : deflection : " + tol + " angle :" + angle, function () { + it(name + " testing with parameter : deflection : " + tol + " angle :" + angle, function () { const mesh1 = shape2.createMesh(tol, angle); debugLog(" vertices = ", mesh1.vertices.length); debugLog(" triangles = ", mesh1.triangles.length); }); } - test_with(0.01, 0.5); test_with(0.01, 5); test_with(0.01, 10); - test_with(0.1, 0.5); test_with(0.1, 1); test_with(0.1, 5); test_with(0.1, 10); test_with(0.1, 20); - test_with(1, 0.5); test_with(1, 1); test_with(1, 5); test_with(1, 10); test_with(1, 20); - test_with(2, 0.5); test_with(2, 1); test_with(2, 5); test_with(2, 10); test_with(2, 20); - - describe(makeShape.name + " : comparing JSON ", function () { - + describe(name + " : comparing JSON ", function () { let shape2; beforeEach(function () { shape2 = makeUnitBox(); }); it("should create default JSON file with acceptable size", function () { shape2.name = "shape2"; - const obj1 = occ.buildSolidMesh(shape2); + const obj1 = __1.occ.buildSolidMesh(shape2); debugLog("json json1", JSON.stringify(obj1, null, "\t")); debugLog("json json1", JSON.stringify(obj1).length); - }); it("should create default JSON file with acceptable size", function () { shape2.name = "shape2"; - const obj2 = occ.buildSolidMeshNew(shape2); + const obj2 = __1.occ.buildSolidMeshNew(shape2); debugLog("json json1", JSON.stringify(obj2, null, "\t")); debugLog("json json2", JSON.stringify(obj2).length); - }); }); - } - - installFor(makeLegoBrick); - installFor(makeSphere); - + installFor("makeLegoBrick", makeLegoBrick); + installFor("makeSphere", makeSphere); }); diff --git a/dist-test/test_named_faces.d.ts b/dist-test/test_named_faces.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_named_faces.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_named_faces.js b/dist-test/test_named_faces.js similarity index 61% rename from test/test_named_faces.js rename to dist-test/test_named_faces.js index f69e28e..acacc1c 100644 --- a/test/test_named_faces.js +++ b/dist-test/test_named_faces.js @@ -1,52 +1,66 @@ -const assert = require("assert"); -const should = require("should"); - -const occ = require("../lib/occ"); - +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should = __importStar(require("should")); +const __1 = require(".."); const doDebug = false; function dumpSolid(b) { if (doDebug) { - console.log(" faces = ", b.getFaces().map(function (e) { - return b.getShapeName(e); - }).join(", ")); - console.log(" edges = ", b.getEdges().map(function (e) { - return b.getShapeName(e); - }).join(", ")); - console.log(" vertices = ", b.getVertices().map(function (e) { - return b.getShapeName(e); - }).join(", ")); + console.log(" faces = ", b.getFaces().map((e) => b.getShapeName(e)).join(", ")); + console.log(" edges = ", b.getEdges().map((e) => b.getShapeName(e)).join(", ")); + console.log(" vertices = ", b.getVertices().map((e) => b.getShapeName(e)).join(", ")); } } // see https://npmjs.org/package/should - -describe("testing face naming on simple box", function () { - +describe("testing face naming on simple box", () => { let solid; - before(function () { - solid = occ.makeBox([0, 0, 0], [10, 20, 30]); + before(() => { + solid = __1.occ.makeBox([0, 0, 0], [10, 20, 30]); }); - it("should have only six named faces", function () { + it("should have only six named faces", () => { Object.keys(solid.faces).length.should.equal(6); }); - it("should have a face called 'top'", function () { + it("should have a face called 'top'", () => { solid.faces.should.have.property("top"); }); - it("should have a face called 'bottom'", function () { + it("should have a face called 'bottom'", () => { solid.faces.should.have.property("bottom"); }); - it("should have a face called 'front'", function () { + it("should have a face called 'front'", () => { solid.faces.should.have.property("front"); }); - it("should have a face called 'back'", function () { + it("should have a face called 'back'", () => { solid.faces.should.have.property("back"); }); - it("should have a face called 'left'", function () { + it("should have a face called 'left'", () => { solid.faces.should.have.property("left"); }); - it("should have a face called 'right'", function () { + it("should have a face called 'right'", () => { solid.faces.should.have.property("right"); }); - it("should provide a service to retrieve the name of its shapes", function () { + it("should provide a service to retrieve the name of its shapes", () => { solid.getShapeName(solid.faces.top).should.equal("top"); solid.getShapeName(solid.faces.bottom).should.equal("bottom"); solid.getShapeName(solid.faces.back).should.equal("back"); @@ -54,180 +68,172 @@ describe("testing face naming on simple box", function () { solid.getShapeName(solid.faces.left).should.equal("left"); solid.getShapeName(solid.faces.right).should.equal("right"); }); - it("should return undefined when shape cannot be found", function () { - const solid2 = occ.makeBox(10, 20, 30); + it("should return undefined when shape cannot be found", () => { + const solid2 = __1.occ.makeBox(10, 20, 30); should.exist(solid.getShapeName(solid.faces.right)); should.not.exist(solid.getShapeName(solid2.faces.right)); - }); - - it("should have 'top' face planar and at z=30", function () { + it("should have 'top' face planar and at z=30", () => { solid.faces.top.isPlanar.should.equal(true); solid.faces.top.centreOfMass.z.should.equal(30); - solid.faces.top.centreOfMass.x.should.equal(5); solid.faces.top.centreOfMass.y.should.equal(10); }); - it("should have 'bottom' face planar and at z=0", function () { + it("should have 'bottom' face planar and at z=0", () => { solid.faces.bottom.isPlanar.should.equal(true); solid.faces.bottom.centreOfMass.z.should.equal(0); - solid.faces.bottom.centreOfMass.x.should.equal(5); solid.faces.bottom.centreOfMass.y.should.equal(10); }); - it("should have 'right' face planar and at y=20", function () { + it("should have 'right' face planar and at y=20", () => { solid.faces.right.isPlanar.should.equal(true); solid.faces.right.centreOfMass.y.should.equal(20); - solid.faces.right.centreOfMass.z.should.equal(15); solid.faces.right.centreOfMass.x.should.equal(5); }); - it("should have 'left' face planar and at y=0", function () { + it("should have 'left' face planar and at y=0", () => { solid.faces.left.isPlanar.should.equal(true); solid.faces.left.centreOfMass.y.should.equal(0); - solid.faces.left.centreOfMass.z.should.equal(15); solid.faces.left.centreOfMass.x.should.equal(5); }); - it("should have 'front' face planar and at x=10", function () { + it("should have 'front' face planar and at x=10", () => { solid.faces.front.isPlanar.should.equal(true); solid.faces.front.centreOfMass.x.should.equal(10); - solid.faces.front.centreOfMass.y.should.equal(10); solid.faces.front.centreOfMass.z.should.equal(15); }); - it("should have 'back' face planar and at x=0", function () { + it("should have 'back' face planar and at x=0", () => { solid.faces.back.isPlanar.should.equal(true); solid.faces.back.centreOfMass.x.should.equal(0); - solid.faces.back.centreOfMass.y.should.equal(10); solid.faces.back.centreOfMass.z.should.equal(15); }); - it("should have named edges", function () { - - const test = solid.getEdges().map(function (e) { + it("should have named edges", () => { + const test = solid.getEdges().map((e) => { return solid.getShapeName(e); }); test.sort().join(" ").should.equal("EXY EXZ EXy EXz EYZ EYz ExY ExZ Exy Exz EyZ Eyz"); }); - - it("should have named vertex", function () { - const test = solid.getVertices().map(function (e) { + it("should have named vertex", () => { + const test = solid.getVertices().map((e) => { return solid.getShapeName(e); }); test.sort().join(" ").should.equal("VXYZ VXYz VXyZ VXyz VxYZ VxYz VxyZ Vxyz"); }); - }); -describe("testing face naming on simple sphere", function () { +describe("testing face naming on simple sphere", () => { let solid; - before(function () { - solid = occ.makeSphere([0, 0, 0], 30); + before(() => { + solid = __1.occ.makeSphere([0, 0, 0], 30); }); - it("should have only one named face", function () { + it("should have only one named face", () => { Object.keys(solid.faces).length.should.equal(1); }); - it("should have a face called 'lateral'", function () { + it("should have a face called 'lateral'", () => { solid.faces.should.have.property("lateral"); solid.getShapeName(solid.faces.lateral).should.equal("lateral"); }); - it("should have not have a face called 'top' ", function () { + it("should have not have a face called 'top' ", () => { solid.faces.should.not.have.property("top"); }); }); -describe("testing face naming on combined boxes", function () { - let solid, box1, box2; - before(function () { - box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); - box2 = occ.makeBox([5, 5, 5], [15, 15, 15]); - solid = occ.fuse(box1, box2); +describe("testing face naming on combined boxes", () => { + let solid; + let box1; + let box2; + before(() => { + box1 = __1.occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = __1.occ.makeBox([5, 5, 5], [15, 15, 15]); + solid = __1.occ.fuse(box1, box2); dumpSolid(solid); - }); - it(" should expose 12 named faces", function () { + it(" should expose 12 named faces", () => { Object.keys(solid.faces).length.should.equal(12); }); - it("should preserve bottom/left/back faces of solid1", function () { + it("should preserve bottom/left/back faces of solid1", () => { should.exist(solid.getShapeName(box1.faces.bottom)); should.exist(solid.getShapeName(box1.faces.left)); should.exist(solid.getShapeName(box1.faces.back)); }); - it("should replace top/right/front faces of solid1", function () { + it("should replace top/right/front faces of solid1", () => { should.not.exist(solid.getShapeName(box1.faces.top)); should.not.exist(solid.getShapeName(box1.faces.right)); should.not.exist(solid.getShapeName(box1.faces.front)); }); - it("should replace bottom/left/back faces of solid2", function () { + it("should replace bottom/left/back faces of solid2", () => { should.not.exist(solid.getShapeName(box2.faces.bottom)); should.not.exist(solid.getShapeName(box2.faces.left)); should.not.exist(solid.getShapeName(box2.faces.back)); }); - it("should preserve top/right/front faces of solid2", function () { + it("should preserve top/right/front faces of solid2", () => { should.exist(solid.getShapeName(box2.faces.top)); should.exist(solid.getShapeName(box2.faces.right)); should.exist(solid.getShapeName(box2.faces.front)); }); }); -describe("testing face naming on a box whose top/right/front corner is carved with a other box", function () { - let solid, box1, box2; - before(function () { - box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); - box2 = occ.makeBox([5, 5, 5], [15, 15, 15]); - solid = occ.cut(box1, box2); - }); - it(" should expose 9 named faces", function () { +describe("testing face naming on a box whose top/right/front corner is carved with a other box", () => { + let solid; + let box1; + let box2; + before(() => { + box1 = __1.occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = __1.occ.makeBox([5, 5, 5], [15, 15, 15]); + solid = __1.occ.cut(box1, box2); + }); + it(" should expose 9 named faces", () => { Object.keys(solid.faces).length.should.equal(9); }); - it("should preserve bottom/left/back faces of original box", function () { + it("should preserve bottom/left/back faces of original box", () => { should.exist(solid.getShapeName(box1.faces.bottom)); should.exist(solid.getShapeName(box1.faces.left)); should.exist(solid.getShapeName(box1.faces.back)); }); - it("should replace top/right/front faces of original box", function () { + it("should replace top/right/front faces of original box", () => { should.not.exist(solid.getShapeName(box1.faces.top)); should.not.exist(solid.getShapeName(box1.faces.right)); should.not.exist(solid.getShapeName(box1.faces.front)); }); - it("should replace bottom/left/back faces of cutting box", function () { + it("should replace bottom/left/back faces of cutting box", () => { should.not.exist(solid.getShapeName(box2.faces.bottom)); should.not.exist(solid.getShapeName(box2.faces.left)); should.not.exist(solid.getShapeName(box2.faces.back)); }); - it("should delete top/right/front faces of cutting box", function () { + it("should delete top/right/front faces of cutting box", () => { should.not.exist(solid.getShapeName(box2.faces.top)); should.not.exist(solid.getShapeName(box2.faces.right)); should.not.exist(solid.getShapeName(box2.faces.front)); }); }); -describe("testing face naming on a box with a split face ('top' face)", function () { - let solid, block, cutting_solid; - before(function () { - block = occ.makeBox([0, 0, 0], [100, 100, 25]); - cutting_solid = occ.makeBox([40, -10, 10], [60, 110, 50]); - solid = occ.cut(block, cutting_solid); - }); - it(" should expose 10 named faces", function () { +describe("testing face naming on a box with a split face ('top' face)", () => { + let solid; + let block; + let cutting_solid; + before(() => { + block = __1.occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid = __1.occ.makeBox([40, -10, 10], [60, 110, 50]); + solid = __1.occ.cut(block, cutting_solid); + }); + it(" should expose 10 named faces", () => { Object.keys(solid.faces).length.should.equal(10); solid.getFaces().length.should.equal(10); }); - it("should have a preserved front/bottom/back faces ", function () { + it("should have a preserved front/bottom/back faces ", () => { should.exist(solid.getShapeName(block.faces.front)); should.exist(solid.getShapeName(block.faces.bottom)); should.exist(solid.getShapeName(block.faces.back)); }); - it("should have modified right/top/left faces ", function () { + it("should have modified right/top/left faces ", () => { should.not.exist(solid.getShapeName(block.faces.right)); should.not.exist(solid.getShapeName(block.faces.top)); should.not.exist(solid.getShapeName(block.faces.left)); }); - - }); -describe("testing face naming on a box fused with a box that have a common face , leading to 4 merging faces", function () { +describe("testing face naming on a box fused with a box that have a common face , leading to 4 merging faces", () => { let box1; let box2; let solid; - before(function () { + before(() => { // +------+ +------+ // |`. `. |\ \ // | `+------+ | +------+ @@ -236,11 +242,11 @@ describe("testing face naming on a box fused with a box that have a common face // `. | | \| | // `+------+ +------+ // - box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); - box2 = occ.makeBox([10, 0, 0], [20, 10, 10]); // box2 back face is same as box1.front frace - solid = occ.fuse(box1, box2); + box1 = __1.occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = __1.occ.makeBox([10, 0, 0], [20, 10, 10]); // box2 back face is same as box1.front frace + solid = __1.occ.fuse(box1, box2); }); - it("should expose 10 faces", function () { + it("should expose 10 faces", () => { // // +----++----+ +----++----+ // | || | | | @@ -251,7 +257,7 @@ describe("testing face naming on a box fused with a box that have a common face // Object.keys(solid.faces).length.should.equal(10); solid.getFaces().length.should.equal(10); - occ.gc(); + __1.occ.gc(); const faces = solid.getFaces(); faces.forEach((face, i) => { const bbox = face.getBoundingBox(); @@ -259,79 +265,72 @@ describe("testing face naming on a box fused with a box that have a common face }); }); }); -describe("testing face naming on a box with a top face split twice leading to 4 isolated corners)", function () { +describe("testing face naming on a box with a top face split twice leading to 4 isolated corners)", () => { // // // in this sample, the top face of the block will be split in two pieces // during the first cut operation.Then each part will be split in two pieces again // during the second cut operation. // let solid, block, cutting_solid1, cutting_solid2; - before(function () { - block = occ.makeBox([0, 0, 0], [100, 100, 25]); - cutting_solid1 = occ.makeBox([40, -10, 10], [60, 110, 50]); - cutting_solid2 = occ.makeBox([-10, 40, 10], [110, 60, 50]); - solid = occ.cut(block, cutting_solid1); - solid = occ.cut(solid, cutting_solid2); - }); - it("should expose 22 named faces", function () { + before(() => { + block = __1.occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid1 = __1.occ.makeBox([40, -10, 10], [60, 110, 50]); + cutting_solid2 = __1.occ.makeBox([-10, 40, 10], [110, 60, 50]); + solid = __1.occ.cut(block, cutting_solid1); + solid = __1.occ.cut(solid, cutting_solid2); + }); + it("should expose 22 named faces", () => { Object.keys(solid.faces).length.should.equal(22); solid.getFaces().length.should.equal(22); }); - it("should have a preserved bottom face", function () { + it("should have a preserved bottom face", () => { should.exist(solid.getShapeName(block.faces.bottom)); }); - it("should have modified front/back/right/top/left faces ", function () { + it("should have modified front/back/right/top/left faces ", () => { should.not.exist(solid.getShapeName(block.faces.front)); should.not.exist(solid.getShapeName(block.faces.back)); should.not.exist(solid.getShapeName(block.faces.right)); should.not.exist(solid.getShapeName(block.faces.top)); should.not.exist(solid.getShapeName(block.faces.left)); }); - - }); -describe("testing face naming on a box with a top face split by a cross shape leading to 4 isolated corners", function () { +describe("testing face naming on a box with a top face split by a cross shape leading to 4 isolated corners", () => { // // in this sample, the top face of the block will be split in 4 pieces // during the single cut operation // let solid, block, cutting_solid1, cutting_solid2, cutting_solid; - before(function () { - block = occ.makeBox([0, 0, 0], [100, 100, 25]); - cutting_solid1 = occ.makeBox([40, -10, 10], [60, 110, 50]); - cutting_solid2 = occ.makeBox([-10, 40, 10], [110, 60, 50]); - cutting_solid = occ.fuse(cutting_solid1, cutting_solid2); - solid = occ.cut(block, cutting_solid); - }); - it("should expose 22 named faces", function () { + before(() => { + block = __1.occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid1 = __1.occ.makeBox([40, -10, 10], [60, 110, 50]); + cutting_solid2 = __1.occ.makeBox([-10, 40, 10], [110, 60, 50]); + cutting_solid = __1.occ.fuse(cutting_solid1, cutting_solid2); + solid = __1.occ.cut(block, cutting_solid); + }); + it("should expose 22 named faces", () => { Object.keys(solid.faces).length.should.equal(22); solid.getFaces().length.should.equal(22); }); - it("should have a preserved bottom face", function () { + it("should have a preserved bottom face", () => { should.exist(solid.getShapeName(block.faces.bottom)); }); - it("should have modified front/back/right/top/left faces ", function () { + it("should have modified front/back/right/top/left faces ", () => { should.not.exist(solid.getShapeName(block.faces.front)); should.not.exist(solid.getShapeName(block.faces.back)); should.not.exist(solid.getShapeName(block.faces.right)); should.not.exist(solid.getShapeName(block.faces.top)); should.not.exist(solid.getShapeName(block.faces.left)); - solid.faces.should.have.property("m1:" + "front" + ":0"); solid.faces.should.have.property("m1:" + "back" + ":0"); solid.faces.should.have.property("m1:" + "top" + ":0"); solid.faces.should.have.property("m1:" + "left" + ":0"); - solid.faces.should.not.have.property("m1:" + "front" + ":1"); solid.faces.should.not.have.property("m1:" + "back" + ":1"); solid.faces.should.not.have.property("m1:" + "left" + ":1"); - }); - - it("should have 4 (and only 4) faces that have been generated from the top face of the original block", function () { + it("should have 4 (and only 4) faces that have been generated from the top face of the original block", () => { // this could be tested using face names const name = block.getShapeName(block.faces.top); - solid.faces.should.have.property("m1:" + name + ":0"); solid.faces.should.have.property("m1:" + name + ":1"); solid.faces.should.have.property("m1:" + name + ":2"); @@ -339,23 +338,17 @@ describe("testing face naming on a box with a top face split by a cross shape le solid.faces.should.not.have.property("m1:" + name + ":4"); }); }); - -describe("testing naming with makeFillet operation", function () { - - +describe("testing naming with makeFillet operation", () => { let solid; - before(function () { - solid = occ.makeBox([10, 20, 30], [100, 200, 300]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [100, 200, 300]); dumpSolid(solid); - const edges = solid.getCommonEdges(solid.faces.front, solid.faces.left); - assert(edges instanceof Array); - - solid = occ.makeFillet(solid, edges[0], 10); + edges.should.be.instanceOf(Array); + solid = __1.occ.makeFillet(solid, edges[0], 10); dumpSolid(solid); - }); - it("should have numFaces with expected number of faces", function () { + it("should have numFaces with expected number of faces", () => { //xx console.log(Object.keys(solid.faces).join(", ")); Object.keys(solid.faces).length.should.equal(solid.numFaces); }); diff --git a/dist-test/test_relativePerformanceBREPSTEP.d.ts b/dist-test/test_relativePerformanceBREPSTEP.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_relativePerformanceBREPSTEP.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/test/test_relativePerformanceBREPSTEP.js b/dist-test/test_relativePerformanceBREPSTEP.js similarity index 54% rename from test/test_relativePerformanceBREPSTEP.js rename to dist-test/test_relativePerformanceBREPSTEP.js index b614247..e1c6461 100644 --- a/test/test_relativePerformanceBREPSTEP.js +++ b/dist-test/test_relativePerformanceBREPSTEP.js @@ -1,29 +1,49 @@ -const occ = require("../lib/occ"); -const should = require("should"); -const async = require("async"); -const path = require("path"); - +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __importStar(require("async")); +const path_1 = __importDefault(require("path")); +require("should"); +const __1 = require(".."); const ProgressBar = require("progress"); const remove_file = require("./helpers").remove_file; - function myReadStep(filename, done) { - - - let brep_filename = require("./helpers").getTemporaryFilePath({suffix: ".brep"}); - + let brep_filename = require("./helpers").getTemporaryFilePath({ suffix: ".brep" }); let bar = new ProgressBar("reading file [:bar] :percent elapsed :elapseds ETA :etas", { complete: "=", incomplete: "-", width: 100, total: 1000 }); - let solids = []; - function progressFunc(percent) { bar.tick(percent); } - function performMesh(solids) { let bar = new ProgressBar("meshing solids [:bar] :percent elapsed :elapseds ETA :etas", { complete: "=", @@ -31,100 +51,80 @@ function myReadStep(filename, done) { width: 100, total: solids.length }); - for (let i in solids) { + for (let i in solids) { bar.tick(); let solid = solids[i]; solid.numFaces.should.be.greaterThan(1); - solid.name = "solid_" + i; try { - occ.buildSolidMesh(solid); + __1.occ.buildSolidMesh(solid); let mesh = solid.mesh; solid.mesh.numVertices.should.be.greaterThan(3); } catch (err) { - } } console.log("\n"); } - - function chrono(async_func, message, callback) { - - let t1, t2, elapsed; + let t1; + let t2; + let elapsed; t1 = new Date(); - - async_func(function (err) { - + async_func((err) => { t2 = new Date(); - elapsed = Math.round((t2 - t1) / 10) / 100; - + elapsed = Math.round((t2.getTime() - t1.getTime()) / 10) / 100; console.log("\ndone " + message + " in ", elapsed, " seconds"); callback(err); }); } - - function read_original_step_file(callback) { - - - t1 = new Date(); - occ.readSTEP(filename, function (err, _solids) { - solids = _solids; + let t1 = new Date(); + __1.occ.readSTEP(filename, (err, _solids) => { + let solids = _solids; if (err) { - return callback(new Error(" readStep returned error = " + err.message + " while reading " + filename + " _solids =", _solids.length)); - } else { + return callback(new Error(" readStep returned error = " + err.message + " while reading " + filename)); + } + else { console.log(" read ", solids.length, " solids"); } callback(err); - }, progressFunc); - + }); } - function perform_mesh_on_solids(callback) { - - // make sure we have a mesh, so it can be saved in the BREP file performMesh(solids); callback(); } - function write_solids_to_brep(callback) { - occ.writeBREP(brep_filename, solids); + __1.occ.writeBREP(brep_filename, solids); callback(); } - function read_brep_file_again(callback) { - occ.readBREP(brep_filename, function (err, _solids) { + __1.occ.readBREP(brep_filename, (err, _solids) => { if (!err) { - solids = _solids; + let solids = _solids; console.log(" nb solids = ", solids.length); } return callback(err); - }, progressFunc); + }); } - async.series([ - chrono.bind(null, read_original_step_file, "read_original_step_file"), chrono.bind(null, perform_mesh_on_solids, "perform_mesh_on_solids"), chrono.bind(null, write_solids_to_brep, "write_solids_to_brep"), chrono.bind(null, read_brep_file_again, "read_brep_file_again"), chrono.bind(null, perform_mesh_on_solids, "perform_mesh_on_solids"), - - function (callback) { - remove_file(brep_filename, callback); + (err) => { + remove_file(brep_filename, err); } ], done); - } - // myReadStep("test/kuka.stp"); describe("testing relative performance of BREP and STEP I/O", function () { this.timeout(40000); - it("should read kuka robot", function (done) { - let filename = path.join(__dirname, "kuka.stp"); + it("should read kuka robot", (done) => { + let filename = path_1.default.join(__dirname, "kuka.stp"); myReadStep(filename, done); }); }); diff --git a/dist-test/test_scriptrunner.d.ts b/dist-test/test_scriptrunner.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_scriptrunner.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist-test/test_scriptrunner.js b/dist-test/test_scriptrunner.js new file mode 100644 index 0000000..b283e23 --- /dev/null +++ b/dist-test/test_scriptrunner.js @@ -0,0 +1,46 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); +describe("Script Runner", function () { + let scriptRunner; + let myEnv = { foo: "bar" }; + before(function () { + scriptRunner = new __1.ScriptRunner(myEnv); + }); + it("should not be possible load external module with require", function (done) { + scriptRunner.run("let fs= require('fs');", function () { + should_1.default.fail(false, "done callback"); + done(new Error("test has failed: 'require' call hasn't been intercepted")); + }, function error_callback(err) { + should_1.default.exist(err); + err.message.should.equal("require is forbidden"); + done(null); // + }); + }); + it("should not be possible to use eval", function (done) { + scriptRunner.run("eval('a=10');", function () { + should_1.default.fail(false, "done callback"); + done(new Error("test has failed: 'eval' call hasn't been intercepted")); + }, function error_callback(err) { + should_1.default.exist(err); + err.message.should.equal("eval is forbidden"); + done(null); // + }); + }); + it("should expose environment provided by the caller", function (done) { + scriptRunner.env.logs = []; // purge log + scriptRunner.env.logs.length.should.equal(0); + scriptRunner.env.foo.should.equal("bar"); + scriptRunner.run("console.log(foo); foo='baz'", function () { + scriptRunner.env.foo.should.equal("baz"); + scriptRunner.env.logs.length.should.equal(1); + done(); + }, function error_callback(err) { + done(err); // should not fail + }); + }); +}); diff --git a/dist-test/test_solid.d.ts b/dist-test/test_solid.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_solid.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_solid.js b/dist-test/test_solid.js similarity index 59% rename from test/test_solid.js rename to dist-test/test_solid.js index 21c5a94..336273e 100644 --- a/test/test_solid.js +++ b/dist-test/test_solid.js @@ -1,74 +1,69 @@ -const should = require("should"); - -const occ = require("../lib/occ"); - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); const DEG2RAD = Math.PI / 180; - // see https://npmjs.org/package/should - -describe("testing solid construction", function () { - - - describe("empty solid", function () { +describe("testing solid construction", () => { + describe("empty solid", () => { let solid; - before(function () { - solid = new occ.Solid(); + before(() => { + solid = new __1.Solid(); }); - it("should have no faces", function () { + it("should have no faces", () => { solid.numFaces.should.equal(0); Object.keys(solid.faces).length.should.equal(0); }); - it("should have no solid", function () { + it("should have no solid", () => { solid.numSolids.should.equal(0); }); - it("should have no shell", function () { + it("should have no shell", () => { solid.numShells.should.equal(0); }); - it("should have no outerShell", function () { - should.not.exist(solid.outerShell); + it("should have no outerShell", () => { + should_1.default.not.exist(solid.outerShell); }); }); - describe("makeBox with 2 points", function () { + describe("makeBox with 2 points", () => { let solid; - before(function () { - solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [20, 40, 60]); }); - it("should be a SOLID", function () { + it("should be a SOLID", () => { solid.shapeType.should.equal("SOLID"); }); - it("should have 1 solid", function () { + it("should have 1 solid", () => { solid.numSolids.should.equal(1); }); - it("should have 1 shell", function () { + it("should have 1 shell", () => { solid.numShells.should.equal(1); }); - it("should have 6 faces", function () { + it("should have 6 faces", () => { solid.numFaces.should.equal(6); Object.keys(solid.faces).length.should.equal(6); }); - it("should have an outerShell with 6 faces", function () { - should.exist(solid.getOuterShell()); + it("should have an outerShell with 6 faces", () => { + should_1.default.exist(solid.getOuterShell()); solid.getOuterShell().numFaces.should.equal(6); // Object.keys(solid.getOuterShell().faces).length.should.equal(6); }); - it("should have an outerShell with a forward orientation", function () { + it("should have an outerShell with a forward orientation", () => { solid.getOuterShell().orientation.should.equal("FORWARD"); }); - it("should have (20-10)*(40-20)*(60-30) as a volume", function () { + it("should have (20-10)*(40-20)*(60-30) as a volume", () => { solid.volume.should.equal((20 - 10) * (40 - 20) * (60 - 30)); }); - - it("should have ~ 2*((20-10)*(40-20)+(20-10)*(60-30)+(40-20)*(60-30)) as a area", function () { + it("should have ~ 2*((20-10)*(40-20)+(20-10)*(60-30)+(40-20)*(60-30)) as a area", () => { let expectedArea = 2 * ((20 - 10) * (40 - 20) + (20 - 10) * (60 - 30) + (40 - 20) * (60 - 30)); let eps = 0.001; solid.area.should.be.within(expectedArea - eps, expectedArea + eps); }); - - it("should have the sum(face area) === area of solid ", function () { - + it("should have the sum(face area) === area of solid ", () => { let epsilon = 1E-3; - - let shapeIt = new occ.ShapeIterator(solid, "FACE"); + let shapeIt = new __1.ShapeIterator(solid, "FACE"); let cumulated_face_area = 0; while (shapeIt.more) { cumulated_face_area += shapeIt.next().area; @@ -77,44 +72,43 @@ describe("testing solid construction", function () { cumulated_face_area.should.be.within(expectedArea - epsilon, expectedArea + epsilon); }); }); - describe("makeBox with invalid arguments", function () { - - it("should raise an exception when invalid arguments are passed to makeBox", function () { + describe("makeBox with invalid arguments", () => { + it("should raise an exception when invalid arguments are passed to makeBox", () => { (function failing_func() { - let solid = occ.makeBox([10, 20, 30], 10, 10, 10); + let solid = __1.occ.makeBox([10, 20, 30], 10, 10, 10); }).should.throwError(); }); }); - describe("fuse 2 overlapping boxes", function () { + describe("fuse 2 overlapping boxes", () => { let solid1; let solid2; - before(function () { - solid1 = occ.makeBox([10, 20, 30], [20, 40, 60]); - solid2 = occ.makeBox([15, 25, 35], [-20, -40, -60]); - solid1 = occ.fuse(solid1, solid2); + before(() => { + solid1 = __1.occ.makeBox([10, 20, 30], [20, 40, 60]); + solid2 = __1.occ.makeBox([15, 25, 35], [-20, -40, -60]); + solid1 = __1.occ.fuse(solid1, solid2); }); - it("should be a SOLID", function () { + it("should be a SOLID", () => { solid1.shapeType.should.equal("SOLID"); }); - it("should have 1 solid", function () { + it("should have 1 solid", () => { solid1.numSolids.should.equal(1); }); - it("should have 1 shell", function () { + it("should have 1 shell", () => { solid1.numShells.should.equal(1); }); - it("should have 12 faces", function () { + it("should have 12 faces", () => { solid1.numFaces.should.equal(12); Object.keys(solid1.faces).length.should.equal(12); }); - it("should have an outerShell with 12 faces", function () { - should.exist(solid1.getOuterShell()); + it("should have an outerShell with 12 faces", () => { + should_1.default.exist(solid1.getOuterShell()); solid1.getOuterShell().numFaces.should.equal(12); }); }); - describe("cut a corner of a box", function () { + describe("cut a corner of a box", () => { let solid1; let solid2; - before(function () { + before(() => { // // +------+ // +-----|`. `. +------+ @@ -124,65 +118,57 @@ describe("testing solid construction", function () { // + | ` +------+ + `+-`+ | // `. | | `. | | // `+------+ `+------+ - solid1 = occ.makeBox([10, 20, 30], [20, 40, 60]); - solid2 = occ.makeBox([15, 25, 35], [-20, -40, -60]); - solid1 = occ.cut(solid1, solid2); + solid1 = __1.occ.makeBox([10, 20, 30], [20, 40, 60]); + solid2 = __1.occ.makeBox([15, 25, 35], [-20, -40, -60]); + solid1 = __1.occ.cut(solid1, solid2); }); - it("should be a SOLID", function () { + it("should be a SOLID", () => { solid1.shapeType.should.equal("SOLID"); }); - it("should have 9 faces", function () { + it("should have 9 faces", () => { solid1.numFaces.should.equal(9); Object.keys(solid1.faces).length.should.equal(9); }); - it("should have 1 solid", function () { + it("should have 1 solid", () => { solid1.numSolids.should.equal(1); }); - it("should have 1 shell", function () { + it("should have 1 shell", () => { solid1.numShells.should.equal(1); }); - - }); - describe("Hollow box ( 1 solid with 2 shells )", function () { + describe("Hollow box ( 1 solid with 2 shells )", () => { let solid1; let solid2; - before(function () { - solid1 = occ.makeBox([0, 0, 0], [20, 20, 20]); - solid2 = occ.makeBox([10, 10, 10], [15, 15, 15]); - - solid1 = occ.cut(solid1, solid2); - - }); - it("should be a SOLID", function () { + before(() => { + solid1 = __1.occ.makeBox([0, 0, 0], [20, 20, 20]); + solid2 = __1.occ.makeBox([10, 10, 10], [15, 15, 15]); + solid1 = __1.occ.cut(solid1, solid2); + }); + it("should be a SOLID", () => { solid1.shapeType.should.equal("SOLID"); }); - it("should have 12 faces", function () { + it("should have 12 faces", () => { solid1.numFaces.should.equal(12); Object.keys(solid1.faces).length.should.equal(12); - }); - it("should have 1 solid", function () { + it("should have 1 solid", () => { solid1.numSolids.should.equal(1); }); - it("should have 2 shells", function () { + it("should have 2 shells", () => { solid1.numShells.should.equal(2); }); - it("should have an outer shell with 6 faces", function () { + it("should have an outer shell with 6 faces", () => { let outerShell = solid1.getOuterShell(); outerShell.numFaces.should.equal(6); }); - it("should have an outer shell with 6 faces", function () { + it("should have an outer shell with 6 faces", () => { let outerShell = solid1.getOuterShell(); outerShell.orientation.should.equal("FORWARD"); }); - it("should expose 2 shells (getOuterShell)", function () { - + it("should expose 2 shells (getOuterShell)", () => { let shells = solid1.getShells(); - let outerShell = solid1.getOuterShell(); - should.exist(outerShell); - + should_1.default.exist(outerShell); shells.length.should.equal(2); for (let i in shells) { let shell = shells[i]; @@ -192,300 +178,272 @@ describe("testing solid construction", function () { } }); }); - describe("split boxes", function () { - + describe("split boxes", () => { let solid1; let solid2; let splitBoxes; - before(function () { + before(() => { // cutting a square box in 2 boxes - solid1 = occ.makeBox([0, 0, 0], [20, 20, 20]); - solid2 = occ.makeBox([-100, -100, 10], [100, 100, 15]); - - splitBoxes = occ.cut(solid1, solid2); - + solid1 = __1.occ.makeBox([0, 0, 0], [20, 20, 20]); + solid2 = __1.occ.makeBox([-100, -100, 10], [100, 100, 15]); + splitBoxes = __1.occ.cut(solid1, solid2); }); - it("should be a COMPOUND", function () { + it("should be a COMPOUND", () => { splitBoxes.shapeType.should.equal("COMPOUND"); }); - it("should have 12 faces", function () { + it("should have 12 faces", () => { //console.log( splitBoxes.faces); splitBoxes.numFaces.should.equal(12); Object.keys(splitBoxes.faces).length.should.equal(12); }); - it("should have 2 solids", function () { + it("should have 2 solids", () => { splitBoxes.numSolids.should.equal(2); }); - it("should have 2 shells", function () { + it("should have 2 shells", () => { splitBoxes.numShells.should.equal(2); }); - it("should have an outer shell with 6 faces", function () { + it("should have an outer shell with 6 faces", () => { let solids = splitBoxes.getSolids(); - let outerShell1 = solids[0].getOuterShell(); outerShell1.numFaces.should.equal(6); - let outerShell2 = solids[1].getOuterShell(); outerShell2.numFaces.should.equal(6); - }); - }); - - describe("creating a compound", function () { + describe("creating a compound", () => { let compound; - before(function () { + before(() => { let solids = []; - let solid1 = occ.makeBox(10, 20, 30); + let solid1 = __1.occ.makeBox(10, 20, 30); for (let i = 0; i < 10; i++) { let s = solid1.rotate([0, 0, 0], [0, 0, 1], i * 15); s.numFaces.should.equal(6); solids.push(s); } - compound = occ.compound(solids); + compound = __1.occ.compound(solids); }); - - it("should be a compound", function () { + it("should be a compound", () => { compound.shapeType.should.equal("COMPOUND"); }); - it("should have 10 solids", function () { + it("should have 10 solids", () => { console.log(compound); compound.numSolids.should.equal(10); }); }); - - describe("Meshing a simple solid", function () { - describe("Meshing a box", function () { + describe("Meshing a simple solid", () => { + describe("Meshing a box", () => { let solid; - before(function () { - solid = occ.makeBox([10, 20, 30], [20, 30, 40]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [20, 30, 40]); }); - it("should have a mesh with 8 vertices", function () { + it("should have a mesh with 8 vertices", () => { solid.mesh.numVertices.should.equal(8); }); - it("should have a mesh with 4+4+4=12 edges", function () { + it("should have a mesh with 4+4+4=12 edges", () => { solid.mesh.numEdges.should.equal(12); }); - it("should have a mesh with 2*6 triangles", function () { + it("should have a mesh with 2*6 triangles", () => { solid.mesh.numTriangles.should.equal(12); }); }); }); - describe("Testing Shape __prototype", function () { + describe("Testing Shape __prototype", () => { let solid; - before(function () { - solid = occ.makeBox([10, 20, 30], [20, 30, 40]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [20, 30, 40]); }); - it("should expose the expected properties ", function () { + it("should expose the expected properties ", () => { let expected = ["shapeType", "numFaces", "isNull", "isValid"]; let actual = []; - for (let j in occ.Solid.prototype) { + for (let j in __1.Solid.prototype) { actual.push(j.toString()); } let missing = []; - for (j in expected) { - if (actual.indexOf(expected[j]) == -1) { - missing.push(expected[j]); + for (const e of expected) { + if (actual.indexOf(e) == -1) { + missing.push(e); } } missing.should.have.lengthOf(0); - }); }); - describe("exporting a solid to STEP ", function () { - + describe("exporting a solid to STEP ", () => { let step_filename1 = "toto1.step"; let step_filename2 = "toto2.step"; let solid1, solid2; - before(function () { - solid1 = occ.makeBox([10, 20, 30], [20, 30, 40]); - solid1 = occ.makeBox([20, 30, 50], [110, 40, 0]); + before(() => { + solid1 = __1.occ.makeBox([10, 20, 30], [20, 30, 40]); + solid1 = __1.occ.makeBox([20, 30, 50], [110, 40, 0]); }); - it("should export a single solid to STEP", function () { - occ.writeSTEP(step_filename1, solid1); + it("should export a single solid to STEP", () => { + __1.occ.writeSTEP(step_filename1, solid1); }); - it("should export many solids to STEP", function () { - occ.writeSTEP(step_filename2, solid1, solid2); + it("should export many solids to STEP", () => { + __1.occ.writeSTEP(step_filename2, solid1, solid2); }); }); - describe("testing ShapeIterator on solid", function () { + describe("testing ShapeIterator on solid", () => { let solid; let shapeIt; - before(function () { - solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [20, 40, 60]); }); - it("should iterate on 6 faces", function () { - - shapeIt = new occ.ShapeIterator(solid, "FACE"); + it("should iterate on 6 faces", () => { + shapeIt = new __1.ShapeIterator(solid, "FACE"); shapeIt.more.should.be.equal(true); - should.not.exist(shapeIt.current); + should_1.default.not.exist(shapeIt.current); let counter = 0; while (shapeIt.more) { shapeIt.more.should.be.equal(true); shapeIt.next(); - should.exists(shapeIt.current); + should_1.default.exists(shapeIt.current); counter += 1; } counter.should.equal(6); shapeIt.more.should.be.equal(false); - should.exists(shapeIt.current); - + should_1.default.exists(shapeIt.current); }); - it("should iterate on 24 edges ( 4 on each of the 6 faces", function () { - shapeIt = new occ.ShapeIterator(solid, "EDGE"); + it("should iterate on 24 edges ( 4 on each of the 6 faces", () => { + shapeIt = new __1.ShapeIterator(solid, "EDGE"); shapeIt.more.should.be.equal(true); - should.not.exist(shapeIt.current); + should_1.default.not.exist(shapeIt.current); let counter = 0; while (shapeIt.more) { shapeIt.more.should.be.equal(true); shapeIt.next(); - should.exists(shapeIt.current); + should_1.default.exists(shapeIt.current); counter += 1; } counter.should.equal(24); shapeIt.more.should.be.equal(false); - should.exists(shapeIt.current); - + should_1.default.exists(shapeIt.current); }); - }); - describe("testing fillet on a box..", function () { - + describe("testing fillet on a box..", () => { let solid; - - before(function () { - solid = occ.makeBox([10, 20, 30], [30, 40, 50]); + before(() => { + solid = __1.occ.makeBox([10, 20, 30], [30, 40, 50]); solid.numFaces.should.equal(6); - - solid = occ.makeFillet(solid, solid.getEdges(), 2.0); - + solid = __1.occ.makeFillet(solid, solid.getEdges(), 2.0); }); - it("should be possible to round the corner...", function () { - + it("should be possible to round the corner...", () => { // 6 flat surfaces -> 6*4 edges // + 12 rounded corners -> shared // + 8 corners -> 8*3 edges //==> 26 faces solid.numFaces.should.be.equal(26); solid.getEdges().length.should.be.equal(6 * 4 + 8 * 3); - }); - }); - describe("makeCylinder (variation 1)", function () { + describe("makeCylinder (variation 1)", () => { let solid; - before(function () { + before(() => { let radius = 50; let height = 100; - solid = occ.makeCylinder(radius, height); + solid = __1.occ.makeCylinder(radius, height); }); - it("should have 3 faces", function () { + it("should have 3 faces", () => { solid.numFaces.should.equal(3); }); }); - - describe("makeCylinder (variation 2)", function () { + describe("makeCylinder (variation 2)", () => { let solid; - before(function () { + before(() => { let position = [[0, 0, 1], [0, 1, 0]]; let radius = 50; let height = 100; - solid = occ.makeCylinder(position, radius, height); + solid = __1.occ.makeCylinder(position, radius, height); }); - it("should have 3 faces", function () { + it("should have 3 faces", () => { solid.numFaces.should.equal(3); }); }); - describe("makeCylinder (variation 3 : with 2 points and a radius)", function () { + describe("makeCylinder (variation 3 : with 2 points and a radius)", () => { let solid; let bbox; - before(function () { + before(() => { let startPoint = [-100, 20, 40]; let endPoint = [100, 20, 40]; let radius = 20; - solid = occ.makeCylinder(startPoint, endPoint, radius); + solid = __1.occ.makeCylinder(startPoint, endPoint, radius); bbox = solid.getBoundingBox(); - }); - it("should have 3 faces", function () { + it("should have 3 faces", () => { solid.numFaces.should.equal(3); }); - it("should have a bounding box that includes X=-100,20,40", function () { + it("should have a bounding box that includes X=-100,20,40", () => { bbox.nearPt.y.should.be.within(-2, 0); bbox.farPt.y.should.be.within(40, 42); - bbox.nearPt.x.should.be.within(-101, -100); bbox.farPt.x.should.be.within(100, 101); }); }); - describe("makeCone - variation 1", function () { + describe("makeCone - variation 1", () => { let solid; - before(function () { + before(() => { let radius1 = 50; let radius2 = 70; let height = 30; - solid = occ.makeCone(radius1, radius2, height); + solid = __1.occ.makeCone(radius1, radius2, height); }); - it("should have 3 faces", function () { + it("should have 3 faces", () => { solid.numFaces.should.equal(3); }); }); - describe("makeCone - variation 2 ( point,R1, point, R2 )", function () { + describe("makeCone - variation 2 ( point,R1, point, R2 )", () => { let solid; let radius1 = 50; let radius2 = 70; - before(function () { + before(() => { let height = 30; - solid = occ.makeCone([0, 0, 0], radius1, [0, 0, height], radius2); + solid = __1.occ.makeCone([0, 0, 0], radius1, [0, 0, height], radius2); }); - it("should have 3 faces", function () { + it("should have 3 faces", () => { solid.numFaces.should.equal(3); - should.exist(solid.faces.top); - should.exist(solid.faces.lateral); - should.exist(solid.faces.bottom); + should_1.default.exist(solid.faces.top); + should_1.default.exist(solid.faces.lateral); + should_1.default.exist(solid.faces.bottom); }); - it("top face should have a area of radius**2*pi", function () { + it("top face should have a area of radius**2*pi", () => { let expectedArea = radius2 * radius2 * Math.PI; let eps = 1.0; solid.faces.top.area.should.be.within(expectedArea - eps, expectedArea + eps); }); - it("bottom face should have a area of radius**2*pi", function () { + it("bottom face should have a area of radius**2*pi", () => { let expectedArea = radius1 * radius1 * Math.PI; let eps = 1.0; solid.faces.bottom.area.should.be.within(expectedArea - eps, expectedArea + eps); }); }); - describe("makeCone - variation 3 ( axpex,dir, half_angle, height )", function () { + describe("makeCone - variation 3 ( axpex,dir, half_angle, height )", () => { let solid; let radius = 50; let height = 30; - before(function () { + before(() => { let angle = Math.atan(radius / height); - solid = occ.makeCone([0, 0, 0], [0, 0, 1], angle, height); + solid = __1.occ.makeCone([0, 0, 0], [0, 0, 1], angle, height); }); - it("should have 2 faces", function () { + it("should have 2 faces", () => { solid.numFaces.should.equal(2); - should.exist(solid.faces.top); - should.exist(solid.faces.lateral); - should.not.exist(solid.faces.bottom); + should_1.default.exist(solid.faces.top); + should_1.default.exist(solid.faces.lateral); + should_1.default.not.exist(solid.faces.bottom); }); - it("top face should have a area of radius**2*pi", function () { + it("top face should have a area of radius**2*pi", () => { let expectedArea = radius * radius * Math.PI; let eps = 1.0; solid.faces.top.area.should.be.within(expectedArea - eps, expectedArea + eps); }); - }); - - describe("makeSphere", function () { + describe("makeSphere", () => { let solid; let radius = 10; let epsilon = radius * 1E-1; - before(function () { + before(() => { let center = [10, 20, 30]; - solid = occ.makeSphere(center, radius); + solid = __1.occ.makeSphere(center, radius); }); - it("should have 1 face and one egde", function () { + it("should have 1 face and one egde", () => { solid.numFaces.should.equal(1); solid.getEdges().length.should.equal(1); let edges = solid.getEdges(); @@ -493,183 +451,139 @@ describe("testing solid construction", function () { // todo : do some investigation } }); - it("should have a area of 4*Pi*R", function () { + it("should have a area of 4*Pi*R", () => { let expected_area = 4 * 3.14159265 * radius * radius; solid.area.should.be.within(expected_area - epsilon, expected_area + epsilon); }); - it("should have a volume of 4/3*Pi*R*2", function () { - + it("should have a volume of 4/3*Pi*R*2", () => { let expected_volume = 4.0 / 3.0 * 3.14159265 * radius * radius * radius; solid.volume.should.be.within(expected_volume - epsilon, expected_volume + epsilon); - }); }); - describe("makeTorus", function () { + describe("makeTorus", () => { let solid; - before(function () { - solid = occ.makeTorus([0, 0, 0], [0, 0, 1], 100, 10); + before(() => { + solid = __1.occ.makeTorus([0, 0, 0], [0, 0, 1], 100, 10); }); - it("should have one single face", function () { + it("should have one single face", () => { //console.log(solid.faces); solid.numFaces.should.equal(1); - should.exist(solid.faces.lateral); + should_1.default.exist(solid.faces.lateral); }); - }); - describe("makeTorus with invalid arguments", function () { - - it("should not crash if torus is created with invalid arguments", function () { - should(function () { - const solid = occ.makeTorus([0, 0, 0], [0, 0, 0], 10, 100); + describe("makeTorus with invalid arguments", () => { + it("should not crash if torus is created with invalid arguments", () => { + (0, should_1.default)(() => { + const solid = __1.occ.makeTorus([0, 0, 0], [0, 0, 0], 10, 100); }).throwError(); }); }); - describe("makeCylinder with invalid arguments", function () { - - it("should not crash if Cylinder is created with invalid arguments", function () { - should(function () { - const solid = occ.makeCylinder([0, 0, 0], [0, 0, 0], 10); + describe("makeCylinder with invalid arguments", () => { + it("should not crash if Cylinder is created with invalid arguments", () => { + (0, should_1.default)(() => { + const solid = __1.occ.makeCylinder([0, 0, 0], [0, 0, 0], 10); }).throwError(); }); }); - - describe("makeCone with invalid arguments", function () { - - it("should not crash if Cone is created with invalid arguments", function () { - should(function () { - const solid = occ.makeCone([0, 0, 0], 0 [0, 0, 0], 10); + describe("makeCone with invalid arguments", () => { + it("should not crash if Cone is created with invalid arguments", () => { + (0, should_1.default)(() => { + const solid = __1.occ.makeCone([0, 0, 0], [0, 0, 0], 10); }).throwError(); - - should(function () { - const solid = occ.makeCone([0, 0, 0], 0 [0, 0, 0], 0); + (0, should_1.default)(() => { + const solid = __1.occ.makeCone([0, 0, 0], [0, 0, 0], 0); }).throwError(); }); }); - - - describe("rotate apply on a solid", function () { + describe("rotate apply on a solid", () => { let solid; - before(function () { - solid = occ.makeBox([10, 10, 0], [20, 20, 10]); - + before(() => { + solid = __1.occ.makeBox([10, 10, 0], [20, 20, 10]); }); - it("should expose a rotated box", function () { - + it("should expose a rotated box", () => { let epsilon = 0.1; let bbox = solid.getBoundingBox(); bbox.farPt.x.should.be.lessThan(20.0 + epsilon); bbox.farPt.y.should.be.lessThan(20.0 + epsilon); bbox.nearPt.x.should.be.greaterThan(10.0 - epsilon); bbox.nearPt.y.should.be.greaterThan(10.0 - epsilon); - solid = solid.rotate([0, 0, 0], [0, 0, 1], 90); - bbox = solid.getBoundingBox(); bbox.farPt.x.should.be.within(-10.0 - epsilon, -10 + epsilon); bbox.farPt.y.should.be.within(20.0 - epsilon, 20 + epsilon); bbox.nearPt.x.should.be.within(-20.0 - epsilon, -20 + epsilon); bbox.nearPt.y.should.be.within(10.0 - epsilon, 10 + epsilon); - }); }); - describe(" making a illegal solid ( with bad arguments) shall raise exception", function () { - it("should raise exception when trying to build a box with illegal arguments", function () { - (function () { - let solid = makebox("illegal"); + describe(" making a illegal solid ( with bad arguments) shall raise exception", () => { + it("should raise exception when trying to build a box with illegal arguments", () => { + (() => { + let solid = __1.occ.makeBox("illegal"); }).should.throwError(); - }); }); - describe("test adjacent faces", function () { + describe("test adjacent faces", () => { let solid; - before(function () { - solid = occ.makeBox([0, 0, 0], [100, 100, 100]); + before(() => { + solid = __1.occ.makeBox([0, 0, 0], [100, 100, 100]); }); - it("should have back/front/left/right faces adjacent to face 'top'", function () { + it("should have back/front/left/right faces adjacent to face 'top'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.top); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("back/front/left/right"); - }); - it("should have back/front/left/right faces adjacent to face 'bottom'", function () { - + it("should have back/front/left/right faces adjacent to face 'bottom'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.bottom); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("back/front/left/right"); }); - - it("should have bottom/left/right/top faces adjacent to face 'back'", function () { - + it("should have bottom/left/right/top faces adjacent to face 'back'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.back); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("bottom/left/right/top"); }); - - it("should have bottom/left/right/top faces adjacent to face 'front'", function () { - + it("should have bottom/left/right/top faces adjacent to face 'front'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.front); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("bottom/left/right/top"); }); - it("should have back/bottom/front/top faces adjacent to face 'left'", function () { - + it("should have back/bottom/front/top faces adjacent to face 'left'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.left); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("back/bottom/front/top"); }); - - it("should have back/bottom/front/top faces adjacent to face 'right'", function () { - + it("should have back/bottom/front/top faces adjacent to face 'right'", () => { let adjFaces = solid.getAdjacentFaces(solid.faces.right); - adjFaces.length.should.equal(4); - let names = adjFaces.map(function (f) { return solid.getShapeName(f); }).sort(); - names.join("/").should.equal("back/bottom/front/top"); }); }); - - describe("makeThickSolid (external ) on box", function () { + describe("makeThickSolid (external ) on box", () => { let initialBox; let thickSolid; - before(function () { - initialBox = occ.makeBox(100, 200, 300); - thickSolid = occ.makeThickSolid(initialBox, initialBox.faces.top, 10); + before(() => { + initialBox = __1.occ.makeBox(100, 200, 300); + thickSolid = __1.occ.makeThickSolid(initialBox, initialBox.faces.top, 10); }); - it("should have 23 (6 + 4 vertical faces + 4 vertical fillets + 1 horizontal face + 4 horizontal fillets + 4 rounded corners) faces", function () { + it("should have 23 (6 + 4 vertical faces + 4 vertical fillets + 1 horizontal face + 4 horizontal fillets + 4 rounded corners) faces", () => { console.log(Object.keys(thickSolid.getFaces().map(function (el) { return thickSolid.getShapeName(el); })).join(" ")); @@ -678,14 +592,14 @@ describe("testing solid construction", function () { thickSolid.numFaces.should.equal(23); }); }); - describe("makeThickSolid (internal) on box", function () { + describe("makeThickSolid (internal) on box", () => { let initialBox; let thickSolid; - before(function () { - initialBox = occ.makeBox(100, 200, 300); - thickSolid = occ.makeThickSolid(initialBox, initialBox.faces.top, -10); + before(() => { + initialBox = __1.occ.makeBox(100, 200, 300); + thickSolid = __1.occ.makeThickSolid(initialBox, initialBox.faces.top, -10); }); - it("should have 1 (1 top face modified + 5 old + 5 new) faces", function () { + it("should have 1 (1 top face modified + 5 old + 5 new) faces", () => { console.log(Object.keys(thickSolid.getFaces().map(function (el) { return thickSolid.getShapeName(el); })).join(" ")); @@ -694,64 +608,56 @@ describe("testing solid construction", function () { thickSolid.numFaces.should.equal(11); }); }); - describe("finding common edge of 2 faces", function () { + describe("finding common edge of 2 faces", () => { let box; - before(function () { - box = occ.makeBox(100, 200, 300); + before(() => { + box = __1.occ.makeBox(100, 200, 300); }); - it("should find a common edge between 'top' face and 'left' face", function () { + it("should find a common edge between 'top' face and 'left' face", () => { let edges = box.getCommonEdges(box.faces.top, box.faces.left); edges.length.should.be.equal(1); - }); - it("should not find a common edge between 'top' face and 'bottom' face", function () { + it("should not find a common edge between 'top' face and 'bottom' face", () => { let edges = box.getCommonEdges(box.faces.top, box.faces.bottom); edges.length.should.be.equal(0); }); }); - describe("makeDraftAngle", function () { + describe("makeDraftAngle", () => { let box; let boxWithDraftFace; - before(function () { - box = occ.makeBox(100, 200, 300); - boxWithDraftFace = occ.makeDraftAngle(box, box.faces.right, 20 * DEG2RAD, box.faces.bottom); + before(() => { + box = __1.occ.makeBox(100, 200, 300); + boxWithDraftFace = __1.occ.makeDraftAngle(box, box.faces.right, 20 * DEG2RAD, box.faces.bottom); }); - it("should have 6 faces", function () { + it("should have 6 faces", () => { boxWithDraftFace.numFaces.should.equal(6); }); - it("should have a smaller volume", function () { + it("should have a smaller volume", () => { boxWithDraftFace.volume.should.be.lessThan(box.volume); - }); }); - - describe("makeDraftAngle on a box with a rounded corner", function () { + describe("makeDraftAngle on a box with a rounded corner", () => { let box; let boxWithDraftFace; - before(function () { - box = occ.makeBox(100, 200, 300); + before(() => { + box = __1.occ.makeBox(100, 200, 300); let edges = box.getCommonEdges(box.faces.left, box.faces.front)[0]; // console.log("edge = ",edges); - box = occ.makeFillet(box, edges, 10); - + box = __1.occ.makeFillet(box, edges, 10); // note: left , front , top and bottom faces have been modified by the fillet // operation.; - let faceToDraft = box.faces["mleft:0"]; let neutralFace = box.faces["mbottom:0"]; - console.log(Object.keys(box.faces).join(" ")); - should.exist(faceToDraft); - should.exist(neutralFace); - boxWithDraftFace = occ.makeDraftAngle(box, faceToDraft, 5 * DEG2RAD, neutralFace); - + should_1.default.exist(faceToDraft); + should_1.default.exist(neutralFace); + boxWithDraftFace = __1.occ.makeDraftAngle(box, faceToDraft, 5 * DEG2RAD, neutralFace); }); - it("should have 7 faces", function () { + it("should have 7 faces", () => { boxWithDraftFace.numFaces.should.equal(7); }); - it("should have a smaller volume", function () { + it("should have a smaller volume", () => { boxWithDraftFace.volume.should.be.lessThan(box.volume); - }); }); }); diff --git a/dist-test/test_transform.d.ts b/dist-test/test_transform.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_transform.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_transform.js b/dist-test/test_transform.js similarity index 74% rename from test/test_transform.js rename to dist-test/test_transform.js index 2a408f2..a040a20 100644 --- a/test/test_transform.js +++ b/dist-test/test_transform.js @@ -1,13 +1,15 @@ -const should = require("should"); -const occ = require("../lib/occ"); - - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); describe("testing transformation object", function () { - let trsf; before(function () { - trsf = new occ.Transformation(); - should.exist(trsf); + trsf = new __1.Transformation(); + should_1.default.exist(trsf); }); describe("a empty transformation", function () { it("should have a scale factor of 1.0", function () { @@ -17,7 +19,6 @@ describe("testing transformation object", function () { trsf.scaleFactor.should.equal(1.0); }); }); - describe("testing translation [10,20,30]", function () { before(function () { trsf.makeTranslation([10, 20, 30]); @@ -39,23 +40,17 @@ describe("testing transformation object", function () { */ }); describe("testing planeMirror o=[10,20,30] dir=[0,0,1", function () { - before(function () { - - occ.ZDir.should.eql([0, 0, 1]); - - trsf.makePlaneMirror([10, 20, 30], occ.ZDir); - + __1.ZDir.should.eql([0, 0, 1]); + trsf.makePlaneMirror([10, 20, 30], __1.ZDir); }); - it("should have a scale factor of -1.0", function () { trsf.scaleFactor.should.eql(-1); }); - it("should flip coord on the Z axis", function () { - let v = occ.makeVertex(10, 10, 40); + let v = __1.occ.makeVertex(10, 10, 40); let v2 = v.transformed(trsf); v2.x.should.eql(v.x); - }) + }); }); }); diff --git a/dist-test/test_vertex.d.ts b/dist-test/test_vertex.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist-test/test_vertex.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/test_vertex.js b/dist-test/test_vertex.js similarity index 70% rename from test/test_vertex.js rename to dist-test/test_vertex.js index c9fd9c8..6ce6f08 100644 --- a/test/test_vertex.js +++ b/dist-test/test_vertex.js @@ -1,18 +1,17 @@ -/* eslint: no-console: off */ -const assert = require("assert"); -const should = require("should"); - -const occ = require("../lib/occ"); - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const should_1 = __importDefault(require("should")); +const __1 = require(".."); +const __2 = require(".."); const doDebug = false; - - describe("testing Vertex ", function () { - describe("constructing a empty vertex ", function () { let vertex; before(function () { - vertex = new occ.Vertex(); + vertex = __1.occ.makeVertex(); }); it("should be (0,0,0)", function () { vertex.x.should.equal(0); @@ -23,7 +22,7 @@ describe("testing Vertex ", function () { describe("constructing a vertex with a {x:..., y..,z: ...}", function () { let vertex; before(function () { - vertex = new occ.Vertex({x: 10, y: 20, z: 30}); + vertex = __1.occ.makeVertex({ x: 10, y: 20, z: 30 }); }); it("should be (10,20,30)", function () { vertex.x.should.equal(10); @@ -34,7 +33,7 @@ describe("testing Vertex ", function () { describe("constructing a vertex with {x:..., y..,z: ...} (property in random order)", function () { let vertex; before(function () { - vertex = new occ.Vertex({a: 10, y: 20, z: 30, x: 10}); + vertex = __1.occ.makeVertex({ a: 10, y: 20, z: 30, x: 10 }); }); it("should be (10,20,30)", function () { vertex.x.should.equal(10); @@ -42,23 +41,21 @@ describe("testing Vertex ", function () { vertex.z.should.equal(30); }); }); - describe("constructing a vertex build by passing x,y,z coordinates to constructor", function () { let vertex; before(function () { - vertex = new occ.Vertex(10, 20, 30); + vertex = __1.occ.makeVertex(10, 20, 30); }); it("should be (10,20,30)", function () { vertex.x.should.equal(10); vertex.y.should.equal(20); vertex.z.should.equal(30); }); - }); describe("constructing a vertex build by passing [x,y,z] coordinates to constructor", function () { let vertex; before(function () { - vertex = new occ.Vertex([10, 20, 30]); + vertex = __1.occ.makeVertex([10, 20, 30]); }); it("should be (10,20,30)", function () { vertex.x.should.equal(10); @@ -69,112 +66,92 @@ describe("testing Vertex ", function () { vertex.isValid.should.equal(true); }); }); - describe("constructing a vertex and applying a translation", function () { let vertex_org; before(function () { - vertex_org = new occ.Vertex([10, 20, 30]); + vertex_org = __1.occ.makeVertex([10, 20, 30]); }); - it("should be translated", function () { let vertex; vertex = vertex_org.translate([10, 20, 30]); - vertex_org.x.should.equal(10); vertex_org.y.should.equal(20); vertex_org.z.should.equal(30); - vertex.x.should.equal(20); vertex.y.should.equal(40); vertex.z.should.equal(60); }); it("should be translated - second form ", function () { let vertex; - vertex = vertex_org.translate(/*[*/10, 20, 30/*]*/); - + vertex = vertex_org.translate(/*[*/ 10, 20, 30 /*]*/); vertex_org.x.should.equal(10); vertex_org.y.should.equal(20); vertex_org.z.should.equal(30); - vertex.x.should.equal(20); vertex.y.should.equal(40); vertex.z.should.equal(60); }); it("should be mirrored", function () { - - const trsf = occ.makePlaneMirror([0, 0, 0], [0, 1, 0]); - + const trsf = __1.occ.makePlaneMirror([0, 0, 0], [0, 1, 0]); const vertex_dest = vertex_org.transformed(trsf); vertex_org.x.should.equal(10); vertex_org.y.should.equal(20); vertex_org.z.should.equal(30); - vertex_dest.x.should.equal(10); vertex_dest.y.should.equal(-20); vertex_dest.z.should.equal(30); - - }) + }); }); - - describe("edge cases: bad use of constructor shall not cause software to crash ", function () { - it("Edge#constructor - should not crash if new is omitted", function () { - should(function () { - const tmp = /* new */ occ.Edge(); + (0, should_1.default)(function () { + const tmp = /* new */ __2.Edge(); tmp; }).throwError(" use new occ.Edge() to construct a Edge"); }); it("Vertex#constructor - should not crash if new is omitted", function () { - should(function () { - const tmp = /* new */ occ.Vertex(10, 20, 30); + (0, should_1.default)(function () { + const tmp = /* new */ __2.Vertex(10, 20, 30); tmp; - }).throwError(" use new occ.Vertex() to construct a Vertex"); + }).throwError(" use occ.makeVertex() to construct a Vertex"); }); it("Wire#constructor - should not crash if new is omitted", function () { - should(function () { - const tmp = /* new */ occ.Wire(); + (0, should_1.default)(function () { + const tmp = /* new */ __2.Wire(); tmp; }).throwError(" use new occ.Wire() to construct a Wire"); }); it("Solid#constructor - should not crash if new is omitted", function () { - should(function () { - const tmp = /* new */ occ.Solid(); + (0, should_1.default)(function () { + const tmp = /* new */ __2.Solid(); tmp; }).throwError(" use new occ.Solid() to construct a Solid"); }); it("BoundingBox#constructor - should not crash if new is omitted", function () { - should(function () { - const tmp = /* new */ occ.BoundingBox(10, 20, 30); + (0, should_1.default)(function () { + const tmp = /* new */ __2.BoundingBox(10, 20, 30); tmp; }).throwError(" use new occ.BoundingBox() to construct a BoundingBox"); }); - it("Vertex#constructor should not crash if wrong argument are provided", function () { - const tmp = new occ.Vertex({x: 10, y: 20, z: 30}); + const tmp = __1.occ.makeVertex({ x: 10, y: 20, z: 30 }); tmp; }); }); - - describe("should provide a way to compare vertex", function () { it("should compare 2 vertices with same coordinates", function () { - const vertex1 = new occ.Vertex(10, 20, 30); - const vertex2 = new occ.Vertex(10, 20, 30); - should(vertex1).eql(vertex2); + const vertex1 = __1.occ.makeVertex(10, 20, 30); + const vertex2 = __1.occ.makeVertex(10, 20, 30); + (0, should_1.default)(vertex1).eql(vertex2); if (doDebug) { console.log("vertex1 ", vertex1); } - should(vertex1).containEql({x: 10, y: 20, z: 30}); - + (0, should_1.default)(vertex1).containEql({ x: 10, y: 20, z: 30 }); }); it("should compare 2 vertices with different coordinates", function () { - const vertex1 = new occ.Vertex(10, 20, 30); - const vertex2 = new occ.Vertex(110, 220, 330); - should(vertex1).not.eql(vertex2); + const vertex1 = __1.occ.makeVertex(10, 20, 30); + const vertex2 = __1.occ.makeVertex(110, 220, 330); + (0, should_1.default)(vertex1).not.eql(vertex2); }); - }); - - }); diff --git a/dist-test/test_wire.d.ts b/dist-test/test_wire.d.ts new file mode 100644 index 0000000..3161617 --- /dev/null +++ b/dist-test/test_wire.d.ts @@ -0,0 +1 @@ +import "should"; diff --git a/dist-test/test_wire.js b/dist-test/test_wire.js new file mode 100644 index 0000000..7d15b98 --- /dev/null +++ b/dist-test/test_wire.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +require("should"); +const __1 = require(".."); +describe("testing Wire ", function () { + describe("empty wire", function () { + let wire; + before(function () { + wire = __1.occ.makeWire(); + }); + it("should have no edges", function () { + wire.numEdges.should.equal(0); + }); + it("should have no vertex", function () { + wire.numVertices.should.equal(0); + }); + it("should not be closed", function () { + wire.isClosed.should.equal(false); + }); + }); + describe("wire with three segments", function () { + let wire1, wire2, wire3; + let wire; + before(function () { + let v1 = __1.occ.makeVertex(0, 0, 0); + let v2 = __1.occ.makeVertex(10, 10, 0); + let v3 = __1.occ.makeVertex(20, 0, 0); + wire1 = __1.occ.makeLine(v1, v2); + wire2 = __1.occ.makeLine(v2, v3); + wire3 = __1.occ.makeLine(v3, v1); + wire = __1.occ.makeWire(wire1, wire2, wire3); + }); + it("should have three edges", function () { + wire.numEdges.should.equal(3); + }); + it("should have three vertive", function () { + wire.numVertices.should.equal(3); + }); + it("should be closed", function () { + wire.isClosed.should.equal(true); + }); + }); +}); diff --git a/index.js b/index.js deleted file mode 100644 index 7c92c80..0000000 --- a/index.js +++ /dev/null @@ -1,8 +0,0 @@ - - -module.exports.occ = require("./lib/occ"); -module.exports.shapeFactory = require("./lib/shapeFactory"); -module.exports.scriptRunner = require("./lib/scriptrunner"); -module.exports.fastBuilder = require("./lib/fastbuilder"); - - diff --git a/jasmine-1.1.0.js b/jasmine-1.1.0.js deleted file mode 100644 index c3d2dc7..0000000 --- a/jasmine-1.1.0.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/lib/bindings.js b/lib/bindings.js index 06ec49f..668f6ca 100644 --- a/lib/bindings.js +++ b/lib/bindings.js @@ -1,4 +1,4 @@ -const binary = require("node-pre-gyp"); +const binary = require("@mapbox/node-pre-gyp"); const path = require("path"); const bindingPath = binary.find(path.resolve(path.join(__dirname, "../package.json"))); const binding = require(bindingPath); diff --git a/lib/fastbuilder.js b/lib/fastbuilder.js deleted file mode 100644 index feefbd2..0000000 --- a/lib/fastbuilder.js +++ /dev/null @@ -1,322 +0,0 @@ -"use strict"; -const crypto = require("crypto"); -const occ = require("./occ"); -const shapeFactory = require("../lib/shapeFactory"); -const assert = require("assert"); - -function debugLog() { - /* implement me*/ -} - -class Cache { - - constructor() { - - this.resetCache(); - - } - - resetCache() { - - this.mapHit = 0; - this.mapQueryCount = 0; - this.mapObject = {}; - - } - - replaceObjectMethod(obj, _methodName) { - - const _originalMethod = obj[_methodName]; - assert(isFunction(_originalMethod)); - // create closure variable - const that = this; - const methodName = _methodName; - const originalMethod = _originalMethod; - - function performOperation() { - - return that.__performedCachedOperation(this, originalMethod, `${methodName}#${this.uuid}`, arguments); - - } - - Object.defineProperty(obj, methodName, {value: performOperation, enumerable: false}); - - // xx obj[methodName] = performOperation;= - - } - - - installProxyMethods(obj) { - - // xx console.log("xxx in installProxyMethods on",obj.constructor.name); - assert(!!obj); - - const prototype = obj.constructor.prototype; - - const functionToOverride = Object.keys(prototype).filter(n => typeof prototype[n] === "function"); - - // ---------------- old - const that = this; - functionToOverride.forEach((funcName) => { - - if (funcName === "toString") { - return; - } - // xx console.log("xxx in installProxyMethods replaceObjectMethod",func_name); - that.replaceObjectMethod(obj, funcName); - - }); - - - } - - prepareObject(obj, cmd, uuid, index) { - - if (obj === undefined) { - - return; - - } - if (typeof obj === "string") { - - return; - - } - - assert(!obj.hasOwnProperty("cmd"), ` object should not have been inserted already ( old cmd : ${obj.cmd})`); - assert(!obj.hasOwnProperty("uuid"), ` object should not have been inserted already ( old uuid : ${obj.uuid})`); - - // store the resulting object in cache - obj.cmd = cmd; - obj.uuid = uuid; - if (index) { - - obj.uuid = hash(`${uuid}[${index}]`); - obj.uuid_index = index; - - } - debugLog(" adding object to cache ", uuid, "cmd =", cmd, " index = ", index); - - this.mapObject[obj.uuid] = obj; - - // prepare the resulting object - this.installProxyMethods(obj); - - } - - __performedCachedOperation(originalObject, originalMethod, methodName, theArguments, callAsConstructor) { - - assert(theArguments.hasOwnProperty("length")); - - const h = calculateOperationHash(methodName, theArguments, callAsConstructor); - const uuid = h[0]; - const cmd = h[1]; - - debugLog(" executing method ", cmd, uuid); - - // check if object is already known - this.mapQueryCount++; - if (this.mapObject.hasOwnProperty(uuid)) { - - const obj = this.mapObject[uuid]; - assert(obj.uuid === uuid, " checking object uuid consistency"); - debugLog(" using object from cache ", obj.uuid, obj.cmd); - - this.mapHit++; - return obj; - - } - - // otherwise perform the "costly" original operation - let result; - try { - - if (callAsConstructor) { - - // New object must be unique.... - assert(false); - const args = [null].concat(Object.keys(theArguments).map(f => theArguments[f])); - const FactoryFunction = originalMethod.bind(...args); - result = new FactoryFunction(); - - } else { - - const args = Object.keys(theArguments).map(f => theArguments[f]); - result = originalMethod.apply(originalObject, args); - - } - - } catch (err) { - - debugLog(` FAILING to call ${methodName}(`, `${Object.keys(theArguments).map(e => JSON.stringify(theArguments[e])).join(" , ")})`); - - throw err; // re-throw execption above - - } - - const _this = this; - - if (result instanceof Array) { - - debugLog("result is an array with ", result.length, " elements"); - - - result.forEach((el, index) => { - - _this.prepareObject(el, cmd, uuid, index); - - }); - - _this.prepareObject(result, cmd, uuid); - - } else { - - // xx console.log("xxx resylt ) ",methodName,result.constructor.name,result); - _this.prepareObject(result, cmd, uuid); - - } - - return result; - - } - - __proxy(originalObject, methodName, theArguments, callAsConstructor) { - - return this.__performedCachedOperation(originalObject, originalObject[methodName], methodName, theArguments, callAsConstructor); - - } -} - -function hash(args) { - - const shasum = crypto.createHash("sha1"); - shasum.update(args); - return shasum.digest("hex"); - -} - -/** - * - */ -function replaceObjectsByGUUID(arg) { - - const toUUID = el => el.uuid; - - if (!arg) { - return null; - } - if (arg.hasOwnProperty("uuid")) { - return toUUID(arg); - } else if ((arg.length > 0 && typeof arg[0] === "number") || (typeof arg === "number")) { - return arg; - } else if (arg.length > 0 && (arg[0] instanceof Object) && arg[0].hasOwnProperty("uuid")) { - debugLog(" Found an array of object with guiid", (`arg ${arg.map(el => el.uuid)}`)); - return arg.map(replaceObjectsByGUUID); - - } else { - if (arg.hashCode) { - return hash(`---${arg.hashCode}`); - } - // we can"t use cache yet - const tmp = arg; - // .map(toUUID); - debugLog(" ERROR : Cannot use cache with object ", typeof arg, JSON.stringify(tmp)); - - return tmp; - } -} - -function calculateOperationHash(methodName, theArguments) { - - - // build the signature of the function + arguments - - let key; - const args = []; - for (key in theArguments) { - - if (theArguments.hasOwnProperty(key)) { - - args.push(replaceObjectsByGUUID(theArguments[key])); - - } - - } - const argStr = JSON.stringify(args); - const cmd = `${methodName}(${argStr.substr(1, argStr.length - 2)})`; - const uuid = hash(cmd); - - return [uuid, cmd]; - -} - -function isFunction(a) { - - return typeof a === "function"; - -} - -const cache = new Cache(); - -function replaceFunc(proxyObj, Obj, methodName) { - - assert(proxyObj); - debugLog(` installing proxy method ${methodName}`); - - if (isFunction(Obj[methodName])) { - - assert(isFunction(Obj[methodName]), `methodName = ${methodName} ${typeof Obj[methodName]}`); - const fn = function () { - - // http://stackoverflow.com/questions/367768/how-to-detect-if-a-function-is-called-as-constructor - // Xx console.log(this.constructor.name == methodName, (this.constructor === fn), this.constructor.name); - return cache.__proxy(Obj, methodName, arguments, (this.constructor === fn)); - - }; - proxyObj[methodName] = fn; - // http://stackoverflow.com/questions/5871040/how-to-dynamically-set-a-function-object-name-in-javascript-as-it-is-displayed-i - Object.defineProperty(fn, "name", {value: methodName}); - - } - -} - -occ.makeBottle = shapeFactory.makeBottle; - -function createProxyObject(originalObject) { - - const proxyObject = {}; - const properties = Object.keys(originalObject); - properties.forEach((funcName) => { - - replaceFunc(proxyObject, originalObject, funcName); - - }); - return proxyObject; - -} - -/* - * [ - * "makeBox", "makeCylinder", "makeCone", "makeSphere", - * "makeTorus", "makeThickSolid", "makeDraftAngle", - * "makeFillet", - * "fuse", "cut", "common", "compound", - * "makeVertex", "makeEdge", "makeWire", - * // constructors - * "Vertex", "Edge", "Wire", "Transformation","BoundingBox" - * - * ].forEach(function (funcName) { - * replaceFunc(ProxyOCC, occ, funcName); - * }); - * - * ["makeBottle"].forEach(function (funcName) { - * replaceFunc(ProxyOCC, shapeFactory, funcName); - * }); - */ -exports.fastBuilder = cache; - -exports.occ = createProxyObject(occ); -exports.occ.buildSolidMesh = occ.buildSolidMesh; - -exports.calculateOperationHash = calculateOperationHash; diff --git a/lib/fastbuilder.ts b/lib/fastbuilder.ts new file mode 100644 index 0000000..a62c058 --- /dev/null +++ b/lib/fastbuilder.ts @@ -0,0 +1,353 @@ +"use strict"; +import crypto from "crypto"; +import assert from "assert"; + +import { OCC } from "./interfaces"; + +function debugLog(this: any, ...args: any[]) { + /* implement me*/ + // console.log.apply(this, args); +} + +type IObject = any; + +type ObjectMethod = (this: any, ...args: any[]) => any; + +class Cache { + public mapObject: Record = {}; + public mapQueryCount = 0; + public mapHit = 0; + constructor() { + this.resetCache(); + } + + resetCache() { + this.mapObject = {}; + this.mapQueryCount = 0; + this.mapHit = 0; + } + + replaceObjectMethod(obj: IObject, _methodName: string) { + const _originalMethod = obj[_methodName]; + assert(isFunction(_originalMethod)); + // create closure variable + const that = this; + const methodName = _methodName; + const originalMethod = _originalMethod; + function performOperation(this: IObject, ...args: any[]) { + return that.__performedCachedOperation( + this, + originalMethod, + `${methodName}#${this.uuid}`, + args, + false + ); + } + Object.defineProperty(obj, methodName, { + value: performOperation, + enumerable: false + }); + } + + installProxyMethods(obj: IObject) { + // xx console.log("xxx in installProxyMethods on",obj.constructor.name); + assert(!!obj); + + const prototype = obj.constructor.prototype; + + const functionToOverride = Object.keys(prototype).filter( + (n) => typeof prototype[n] === "function" + ); + + // ---------------- old + const that = this; + functionToOverride.forEach((funcName) => { + if (funcName === "toString") { + return; + } + // xx console.log("xxx in installProxyMethods replaceObjectMethod",func_name); + that.replaceObjectMethod(obj, funcName); + }); + } + + prepareObject( + obj: IObject, + cmd: string, + uuid: string, + index?: number | string + ) { + if (obj === undefined) { + return; + } + if (typeof obj === "string") { + return; + } + if (typeof obj === "number") { + return; + } + + assert( + !obj.hasOwnProperty("cmd"), + ` object should not have been inserted already ( old cmd : ${obj.cmd})` + ); + assert( + !obj.hasOwnProperty("uuid"), + ` object should not have been inserted already ( old uuid : ${obj.uuid})` + ); + + // store the resulting object in cache + obj.cmd = cmd; + obj.uuid = uuid; + if (index) { + obj.uuid = hash(`${uuid}[${index}]`); + obj.uuid_index = index; + } + debugLog( + " adding object to cache ", + uuid, + "cmd =", + cmd, + " index = ", + index + ); + + this.mapObject[obj.uuid] = obj; + + // prepare the resulting object + this.installProxyMethods(obj); + } + + __performedCachedOperation( + originalObject: IObject, + originalMethod: ObjectMethod, + methodName: string, + theArguments: any[], + callAsConstructor: boolean + ) { + assert(theArguments.hasOwnProperty("length")); + + const h = calculateOperationHash( + methodName, + theArguments, + callAsConstructor + ); + const uuid = h[0]; + const cmd = h[1]; + + debugLog(" executing method ", cmd, uuid); + + // check if object is already known + this.mapQueryCount++; + if (this.mapObject.hasOwnProperty(uuid)) { + const obj = this.mapObject[uuid]; + assert(obj.uuid === uuid, " checking object uuid consistency"); + debugLog(" using object from cache ", obj.uuid, obj.cmd); + + this.mapHit++; + return obj; + } + + // otherwise perform the "costly" original operation + let result; + try { + if (callAsConstructor) { + // New object must be unique.... + assert(false); + // const args = [null].concat(Object.keys(theArguments).map(f => theArguments[f])); + // const FactoryFunction = originalMethod.bind(...args); + // result = new FactoryFunction(); + } else { + // const args = Object.keys(theArguments).map((f) => theArguments[f]); + result = originalMethod.apply(originalObject, theArguments); + } + } catch (err) { + debugLog( + ` FAILING to call ${methodName}(`, + `${theArguments + .map((e) => JSON.stringify(theArguments[e])) + .join(" , ")})` + ); + throw err; // re-throw execption above + } + + const _this = this; + + if (result instanceof Array) { + debugLog("result is an array with ", result.length, " elements"); + + result.forEach((el, index) => { + _this.prepareObject(el, cmd, uuid, index); + }); + + _this.prepareObject(result, cmd, uuid); + } else { + // xx console.log("xxx resylt ) ",methodName,result.constructor.name,result); + _this.prepareObject(result, cmd, uuid); + } + + return result; + } + + __proxy( + originalObject: IObject, + methodName: string, + theArguments: any[], + callAsConstructor: boolean + ) { + return this.__performedCachedOperation( + originalObject, + originalObject[methodName], + methodName, + theArguments, + callAsConstructor + ); + } +} + +function hash(...args: any[]) { + const shasum = crypto.createHash("sha1"); + shasum.update(args.map((a) => a.toString()).join(",")); + return shasum.digest("hex"); +} + +/** + * + */ +function replaceObjectsByGUUID(arg: any) { + const toUUID = (el: { uuid: string }) => el.uuid; + + if (!arg) { + return null; + } + if (arg.hasOwnProperty("uuid")) { + return toUUID(arg); + } else if ( + (arg.length > 0 && typeof arg[0] === "number") || + typeof arg === "number" + ) { + return arg; + } else if ( + (arg.length > 0 && typeof arg[0] === "string") || + typeof arg === "string" + ) { + return arg; + } else if ( + arg.length > 0 && + arg[0] instanceof Object && + arg[0].hasOwnProperty("uuid") + ) { + debugLog(" Found an array of object with guiid", `arg ${arg.map(toUUID)}`); + return arg.map(replaceObjectsByGUUID); + } else { + if (arg.hashCode) { + return hash(`---${arg.hashCode}`); + } + // we can"t use cache yet + const tmp = arg; + // .map(toUUID); + debugLog( + " ERROR : Cannot use cache with object ", + typeof arg, + JSON.stringify(tmp) + ); + + return tmp; + } +} +/** + * + * @private + */ +export function calculateOperationHash( + methodName: string, + theArguments: any[], + _callAsConstructor: boolean +) { + // build the signature of the function + arguments + + let key; + const args = []; + for (key in theArguments) { + if (theArguments.hasOwnProperty(key)) { + args.push(replaceObjectsByGUUID(theArguments[key])); + } + } + const argStr = JSON.stringify(args); + const cmd = `${methodName}(${argStr.substring(1, argStr.length - 1)})`; + const uuid = hash(cmd); + + return [uuid, cmd]; +} + +function isFunction(a: any) { + return typeof a === "function"; +} + +function replaceFunc( + cache: Cache, + proxyObj: IObject, + Obj: IObject, + methodName: string +) { + assert(proxyObj); + debugLog(` installing proxy method ${methodName}`); + + const method = (Obj as any)[methodName]; + if (isFunction(method)) { + assert(isFunction(method), `methodName = ${methodName} ${typeof method}`); + const fn = function (this: any, ...args: any[]) { + // http://stackoverflow.com/questions/367768/how-to-detect-if-a-function-is-called-as-constructor + // Xx console.log(this.constructor.name == methodName, (this.constructor === fn), this.constructor.name); + return cache.__proxy(Obj, methodName, args, this.constructor === fn); + }; + (proxyObj as any)[methodName] = fn; + // http://stackoverflow.com/questions/5871040/how-to-dynamically-set-a-function-object-name-in-javascript-as-it-is-displayed-i + Object.defineProperty(fn, "name", { value: methodName }); + } +} + +export function createProxyObject(originalObject: IObject): IObject { + const proxyObject: Record = {}; + + const cache = new Cache(); + proxyObject.$ = cache; + const properties = Object.keys(originalObject as Record); + properties.forEach((funcName) => + replaceFunc(cache, proxyObject, originalObject, funcName) + ); + return proxyObject as IObject; +} + +/* + * occ.makeBottle = shapeFactory.makeBottle; + * [ + * "makeBox", "makeCylinder", "makeCone", "makeSphere", + * "makeTorus", "makeThickSolid", "makeDraftAngle", + * "makeFillet", + * "fuse", "cut", "common", "compound", + * "makeVertex", "makeEdge", "makeWire", + * // constructors + * "Vertex", "Edge", "Wire", "Transformation","BoundingBox" + * + * ].forEach(function (funcName) { + * replaceFunc(ProxyOCC, occ, funcName); + * }); + * + * ["makeBottle"].forEach(function (funcName) { + * replaceFunc(ProxyOCC, shapeFactory, funcName); + * }); + */ + +import { occ as occOriginal } from "./occ"; + +export interface OCC2 extends OCC { + $: { + resetCache(): void; + mapQueryCount: number; + mapHit: number; + }; +} +//xx export const _cache: OCC2 = cache as any as OCC2; + +export const fastBuilder = createProxyObject(occOriginal) as OCC2; +(fastBuilder as any).buildSolidMesh = occOriginal.buildSolidMesh; diff --git a/lib/index.ts b/lib/index.ts new file mode 100644 index 0000000..ee1cc81 --- /dev/null +++ b/lib/index.ts @@ -0,0 +1,7 @@ +export * from "./interfaces"; +export * from "./occ"; +export { fastBuilder } from "./fastbuilder"; +export * from "./shapeFactory"; +export { ScriptRunner } from "./scriptrunner"; +import * as shapeFactory1 from "./shapeFactory"; +export const shapeFactory = shapeFactory1; diff --git a/lib/interfaces.ts b/lib/interfaces.ts new file mode 100644 index 0000000..e2bc7cd --- /dev/null +++ b/lib/interfaces.ts @@ -0,0 +1,404 @@ +export type Real = number; +export type UInteger = number; + +export interface IPoint { + x: Real; + y: Real; + z: Real; + + equals(otherPoint: PointLike): boolean; + asArray(): Triplet; +} + +export interface IVector { + u: Real; + v: Real; + w: Real; +} + +export interface XYZ { + x: number; + y: number; + z: number; +} + +export type Triplet = [Real, Real, Real]; +export type PointLike = IPoint | Triplet | XYZ; +export type VectorLike = IVector | Triplet; +export type IAxisLike = [PointLike, VectorLike]; + +export interface IBoundingBox { + nearPt: IPoint; + farPt: IPoint; + + /** + * isVoid is true if the box is degenerated (i.e does not enclose any point) + */ + isVoid: boolean; + + addPoint(point: PointLike): void; + isOut(point: PointLike): boolean; + + /** + * return a array containing the 8 corners of the bounding box + */ + getVertices(): IPoint[]; +} + +export interface IMesh { + numVertices: UInteger; + numEdges: UInteger; + numTriangles: UInteger; + + vertices: Triplet[]; + + normals: Float32Array; + + edgeIndices: UInteger[]; + triangles: [UInteger, UInteger, UInteger][]; + triangleNormals: UInteger[]; + + faceRanges: UInteger[]; + edgeRanges: UInteger[]; + + getFaceTriangles(face: IFace): Uint8Array | Uint16Array | Uint32Array; + getEdgeIndices(edge: IEdge): Uint8Array | Uint16Array | Uint32Array; + getFaceTriangleNormals(face: IFace): Uint8Array | Uint16Array | Uint32Array; + + toJSON(): string; +} + +export interface ITransform { + scaleFactor: Real; + makeTranslation(point: PointLike): void; + makeTranslation(x: Real, y: Real, z: Real): void; + makePlaneMirror(point: PointLike, vector: VectorLike): ITransform; +} + +export interface IShape { + shapeType: "SHELL" | "SOLID" | "COMPOUND" | "EDGE" | "FACE"; + name?: string; + + translate(vector: VectorLike): T; + translate(dx: Real, dy: Real, dz: Real): T; + + rotate(rotationCenter: PointLike, vector: VectorLike, angleInDegree: Real): T; + applyTransform(transformation: ITransform): T; + scale(): T; + mirror(): T; + fixShape(): T; + clone(): T; + getBoundingBox(): IBoundingBox; + transformed(transformation: ITransform): T; +} + +export interface IVertex extends IShape, IPoint { + new (x: Real, y: Real, z: Real): IVertex; + new (point: PointLike): IVertex; + isValid: boolean; +} + +export interface IEdge extends IShape { + /** + * true if the edge is collapsed or degenerated + */ + isNull: boolean; + /** + * true if the edge is degenerated + */ + isDegenerated: boolean; + + /** + * isClosed + */ + isClosed: boolean; + /** + * isSeam + */ + isSeam: boolean; + + /** + * length the curvature lengh of the edge segment + */ + length: Real; + + /** + * numVertices number of vertices that this edge has. + */ + numVertices: UInteger; + + firstVertex: IVertex; + lastVertex: IVertex; + + /** + * compute and return the bounding box of the edge. + * + */ + getBoundingBox(): IBoundingBox; + + /** + * + */ + polygonize(): Float32Array; + + getVertices(): IVertex[]; +} + +export interface IFace extends IShape { + numWires: UInteger; + isPlanar: boolean; + centreOfMass: IPoint; + /** + * the area of the face in mm^2 + */ + area: Real; + + getWires(): IWire[]; + + hasMesh: boolean; + + mesh: IMesh; + createMesh(tol: Real, angle?: Real): IMesh; + + getBoundingBox(): IBoundingBox; +} + +export interface IShell extends IShape { + shapeType: "SHELL"; + hashCode: string; + numFaces: UInteger; + orientation: "FORWARD"; + area: Real; + getEdges(): IEdge[]; + getFaces(): IFace[]; + getVertices(): IVertex[]; + getCommonEdges(face1: IFace, face2: IFace): IEdge[]; + getAdjacentFaces(face: IFace): IFace[]; + faces: { + [key: string]: IFace; + }; + hasMesh: boolean; + mesh: IMesh; + createMesh(tolerance: Real, angle?: Real): IMesh; + getShapeName(topologyElement: IFace | IEdge | IVertex): string; +} + +export interface IShapeIterator { + // constructor(solid: ISolid, type: "FACE" | "EDGE"); + more: boolean; + current: T; + next(): T; +} + +export interface ISolid extends IShape { + shapeType: "SOLID" | "COMPOUND"; + + numFaces: UInteger; + numSolids: UInteger; + numShells: UInteger; + outerShell: IShell; + + volume: Real; + area: Real; + + getEdges(): IEdge[]; + getFaces(): IFace[]; + getVertices(): IVertex[]; + getShells(): IShell[]; + + /** + * return a list of individual ISolid(SOLID) if self is a COMPOUND solid + */ + getSolids(): ISolid[]; + + getOuterShell(): IShell; + + getCommonEdges(face1: IFace, face2: IFace): IEdge[]; + getAdjacentFaces(face: IFace): IFace[]; + + // accessed to named faces + faces: { + [key: string]: IFace; + }; + + hasMesh: boolean; + mesh: IMesh; + createMesh(tolerance: Real, angle?: Real): IMesh; + + getShapeName(topologyElement: IFace | IEdge | IVertex): string; +} + +export interface IAxis {} + +export interface IWire extends IShape { + isClosed: boolean; + numEdges: number; + numVertices: number; + length: number; + isDegenerated: boolean; + + getEdges(): IEdge[]; + getVertices(): IVertex[]; + getBoundingBox(): IBoundingBox; + polygonize(): Float32Array; +} + +export type Shape = ISolid | IWire | IFace | IShell | IVertex; + +export interface OCC { + makeAxis(): IAxis; + + makeBox(point1: PointLike, point2: PointLike): ISolid; + makeBox(width: Real, length: Real, height: Real): ISolid; + + makeCylinder( + lowCenterPoint: PointLike, + highCenterPoint: PointLike, + radius: Real + ): ISolid; + makeCylinder([origin, axis]: IAxisLike, radius: Real, height: Real): ISolid; + makeCylinder(radius: Real, height: Real): ISolid; + makeCylinder( + originDirection: [PointLike, VectorLike], + radius: Real, + height: Real + ): ISolid; + + makeSphere(center: PointLike, radius: Real): ISolid; + makeCone(p1: PointLike, r1: Real, p2: PointLike, r2: Real): ISolid; + makeCone(radius1: Real, radius2: Real, height: Real): ISolid; + makeCone(p1: PointLike, p2: PointLike, angle: Real, height: Real): ISolid; + // + makePrism(face: IFace, vector: VectorLike): ISolid; + makeFillet(body: ISolid, edges: IEdge[] | IEdge, radius: number): ISolid; + makeTorus( + center: PointLike, + vector: VectorLike, + mainRadius: Real, + smallRadius: Real + ): ISolid; + + /** + * Constructs a pipe by sweeping the shape Profile along the wire Spine. + * The angle made by the spine with the profile is maintained along the length of the pipe. + * Warning Spine must be G1 continuous; + * that is, on the connection vertex of two edges of the wire, the tangent vectors on the + * left and on the right must have the same direction, + * though not necessarily the same magnitude. Exceptions Standard_DomainError + * if the profile is a solid or a composite solid. + * + * @param spine + * + * @param profile + */ + makePipe(spine: IWire, profile: IWire): IShell; + // makePipe(spine: IFace, profile: IWire): ISolid; + + + // to do find a better name + makePipeShell(params: { + wire: IWire, + spineSupport: IWire, + auxilaryCurve?: IWire, + solid?: false; + }): IShell; + + makePipeShell(params: { + wire: IWire, + spineSupport: IWire, + auxilaryCurve?: IWire, + solid: true; + }): ISolid; + + makePipeShell(params: { + wires: IWire[], + spineSupport: IWire, + auxilaryCurve?: IWire, + solid?: false; + }): IShell; + + makePipeShell(params: { + wires: IWire[], + spineSupport: IWire, + auxilaryCurve?: IWire, + solid: true; + }): ISolid; + makeRevol(vertex: IVertex, axis: IAxisLike, angleDegree?: number): IEdge; + makeRevol(edge: IEdge, axis: IAxisLike, angleDegree?: number): IFace; + makeRevol(wire: IWire, axis: IAxisLike, angleDegree?: number): IShell; + makeRevol(face: IFace, axis: IAxisLike, angleDegree?: number): ISolid; + + // makeRevol(solid: ISolid): ICompound; + + /** + * + * @param point1 + * @param point2 + */ + makeSolidThruSections(sections: IWire[] | IEdge[]): ISolid; + + // boolean operation + // Edges + makeLine(point1: PointLike, point2: PointLike): IEdge; + makeArc3P(point1: PointLike, point2: PointLike, point3: PointLike): IEdge; + makeCircle(center: PointLike, normal: VectorLike, radius: Real): IEdge; + makeInterpolatedCurve( + points: PointLike[], + isPeriodic: boolean, + tolerance: number + ): IEdge; + + // Wires + makeWire(edges: (IEdge | IWire)[]): IWire; + makeWire(...args: (IEdge | IWire)[]): IWire; + + // --- TO IMPLEMENT SOMEHOW !!! + makeVertex(): IVertex; + makeVertex(point: PointLike): IVertex; + makeVertex(x: Real, y: Real, z: Real): IVertex; + // --- END TO IMPLEMENT SOMEHOW !!! + + makeFace(wire: IWire): IFace; + + // Boolean operations: + + fuse(solid1: ISolid, solid2: ISolid): ISolid; + cut(solid1: ISolid, solid2: ISolid): ISolid; + common(solid1: ISolid, solid2: ISolid): ISolid; + + compound(shapes: T[]): T; + compound(shapes: ISolid[]): ISolid; + + makeThickSolid(body: ISolid, faceToRemove: IFace, thickness: number): ISolid; + makeDraftAngle( + body: ISolid, + face: IFace, + angleInRadian: number, + otherFace: IFace + ): ISolid; + + // + buildSolidMesh(solid: ISolid): any; + buildSolidMeshNew(solid: ISolid): any; + + makePlaneMirror(point: PointLike, vector: VectorLike): ITransform; + + gc(): void; + + writeSTEP(filename: string, shape: Shape): boolean; + writeSTEP(filename: string, shapes: Shape[]): boolean; + writeSTEP(filename: string, ...shapes: Shape[]): boolean; + readSTEP(filename: string, callback: (err: Error | null, shapes: Shape[]) => void): void; + + writeBREP(filename: string, solid: ISolid): boolean; + writeBREP(filename: string, solids: ISolid[]): boolean; + writeBREP(filename: string, ...solids: ISolid[]): boolean; + + readBREP( + filename: string, + callback: (err: Error | null, solids: ISolid[]) => void + ): void; + + writeGLTF(filename: string, solid: ISolid): void; + writeGLTF(filename: string, ...solid: ISolid[]): void; +} diff --git a/lib/mesh.js b/lib/mesh.js deleted file mode 100644 index 7dd67c2..0000000 --- a/lib/mesh.js +++ /dev/null @@ -1,66 +0,0 @@ -const assert = require("assert"); -const occ = require("./bindings"); - - -function toArray(meshBuffer) { - const res = []; - for (let i = 0; i < meshBuffer.length; i++) { - res.push(parseFloat(meshBuffer[i].toFixed(3))); - } - return res; -} -exports.init = function () { - - - const hasFaceVertexNormal = (1 << 5); - // hasFaceNormal would be (1 << 4); - occ.Mesh.prototype.toThreeJS_JSONFormat = function () { - - // see https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.1 - // https://github.com/mrdoob/three.js/blob/102497da4213b9fceae9fd9bf87a37f7574ba387/src/loaders/JSONLoader.js - const json = { - metadata: {"formatVersion": 3}, - materials: [{ - DbgColor: 15658734, // => 0xeeeeee - DbgIndex: 0, - DbgName: "dummy", - colorDiffuse: [1, 0, 0] - }], - vertices: [], - normals: [], - faces: [] - }; - - json.vertices = toArray(this.vertices); - json.normals = toArray(this.normals); - json.uvs = []; - json.faces = []; - - for (let i = 0; i < this.numTriangles; i++) { - - json.faces.push(hasFaceVertexNormal); // vertex + normal index - - const i1 = this.triangles[i * 3 + 0]; - const i2 = this.triangles[i * 3 + 1]; - const i3 = this.triangles[i * 3 + 2]; - - const j1 = this.triangleNormals[i * 3 + 0]; - const j2 = this.triangleNormals[i * 3 + 1]; - const j3 = this.triangleNormals[i * 3 + 2]; - - // face triangle vertex indexes - json.faces.push(i1); - json.faces.push(i2); - json.faces.push(i3); - - // face vertex normal indexes - json.faces.push(j1); - json.faces.push(j2); - json.faces.push(j3); - } - return json; - }; - - occ.Mesh.prototype.toJSON = occ.Mesh.prototype.toThreeJS_JSONFormat; - -}; diff --git a/lib/mesh.ts b/lib/mesh.ts new file mode 100644 index 0000000..a7fc24d --- /dev/null +++ b/lib/mesh.ts @@ -0,0 +1,64 @@ +import { _occ } from "./occ"; + +const Mesh = _occ.Mesh; + +function toArray(meshBuffer: number[]) { + const res = []; + for (let i = 0; i < meshBuffer.length; i++) { + res.push(parseFloat(meshBuffer[i].toFixed(3))); + } + return res; +} + +export function init() { + const hasFaceVertexNormal = 1 << 5; + // hasFaceNormal would be (1 << 4); + Mesh.prototype.toThreeJS_JSONFormat = function () { + // see https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.1 + // https://github.com/mrdoob/three.js/blob/102497da4213b9fceae9fd9bf87a37f7574ba387/src/loaders/JSONLoader.js + const json: any = { + metadata: { formatVersion: 3 }, + materials: [ + { + DbgColor: 15658734, // => 0xeeeeee + DbgIndex: 0, + DbgName: "dummy", + colorDiffuse: [1, 0, 0] + } + ], + vertices: [], + normals: [], + faces: [] + }; + + json.vertices = toArray(this.vertices); + json.normals = toArray(this.normals); + json.uvs = []; + json.faces = []; + + for (let i = 0; i < this.numTriangles; i++) { + json.faces.push(hasFaceVertexNormal); // vertex + normal index + + const i1 = this.triangles[i * 3 + 0]; + const i2 = this.triangles[i * 3 + 1]; + const i3 = this.triangles[i * 3 + 2]; + + const j1 = this.triangleNormals[i * 3 + 0]; + const j2 = this.triangleNormals[i * 3 + 1]; + const j3 = this.triangleNormals[i * 3 + 2]; + + // face triangle vertex indexes + json.faces.push(i1); + json.faces.push(i2); + json.faces.push(i3); + + // face vertex normal indexes + json.faces.push(j1); + json.faces.push(j2); + json.faces.push(j3); + } + return json; + }; + + Mesh.prototype.toJSON = Mesh.prototype.toThreeJS_JSONFormat; +} diff --git a/lib/occ.js b/lib/occ.js deleted file mode 100644 index b83e0d1..0000000 --- a/lib/occ.js +++ /dev/null @@ -1,58 +0,0 @@ -/* global exports,require */ -/** - * Module dependencies. - */ -const occ = require("./bindings"); - -exports.version = "0.12"; -exports.description = "OpenCascade Wrapper for NodeJS"; - -// complete object prototypes with pure Javascript -require("./mesh").init(); -require("./shape").init(); - -// forward native module -Object.keys(occ).forEach(method => exports[method] = occ[method]); - - -// add utilities -exports.XDir = [1, 0, 0]; -exports.YDir = [0, 1, 0]; -exports.ZDir = [0, 0, 1]; - -/* -exports.demo = function () { - const solid = occ.makeBox([10, 20, 30], [40, 50, 60]); - solid.mesh; - return solid; -}(); -*/ - -function f(a, w, p) { - return (" " + (a + 0).toFixed(p)).substr(-w); -} - -occ.Point3D.prototype.toString = function () { - - return "{" + - " x: " + f(this.x, 8, 3) + "," + - " y: " + f(this.y, 8, 3) + "," + - " z: " + f(this.z, 8, 3) + "" + - " }"; -}; - -occ.BoundingBox.prototype.toString = function () { - return "{ nearPt: " + this.nearPt.toString() + " , farPt: " + this.farPt.toString() + "}"; -}; - -occ.Vertex.prototype.toString = occ.Point3D.prototype.toString; - -occ.Edge.prototype.toString = function () { - - return "Edge => { \n" + - " numVertices: " + this.numVertices + "\n" + - " vertices: " + - this.getVertices().map(function (f) { - return f.toString(); - }).join(" ") + "}"; -}; diff --git a/lib/occ.ts b/lib/occ.ts new file mode 100644 index 0000000..2749c09 --- /dev/null +++ b/lib/occ.ts @@ -0,0 +1,188 @@ +/* global exports,require */ +/** + * Module dependencies. + */ +import { assert } from "console"; +import { + Real, + IEdge, + IFace, + ISolid, + Triplet, + IPoint, + IVertex, + PointLike, + IBoundingBox, + ITransform, + IVector, + IWire, + OCC, + IShapeIterator +} from "./interfaces"; + +export const _occ = require("../lib/bindings"); +export const occ = _occ as OCC; +exports.version = "0.12"; +exports.description = "OpenCascade Wrapper for NodeJS"; + +// ----------------------------------------------------------------------------- BoundingBox +export declare interface BoundingBox1 extends IBoundingBox {} +export declare class BoundingBox1 implements IBoundingBox { + constructor(); + constructor(point: PointLike); + constructor(point1: PointLike, point2: PointLike); +} +export const BoundingBox = _occ.BoundingBox as typeof BoundingBox1; + +BoundingBox.prototype.toString = function () { + return ( + "{ nearPt: " + + this.nearPt.toString() + + " , farPt: " + + this.farPt.toString() + + "}" + ); +}; +BoundingBox.prototype.toString = function () { + return ( + "[ " + + this.nearPt.x.toFixed(3) + + "," + + this.nearPt.y.toFixed(3) + + "," + + this.nearPt.z.toFixed(3) + + "]" + + "[ " + + this.farPt.x.toFixed(3) + + "," + + this.farPt.y.toFixed(3) + + "," + + this.farPt.z.toFixed(3) + + "]" + ); +}; + +// ----------------------------------------------------------------------------- Point +export interface Point1 extends IPoint {} +export declare class Point1 implements IPoint { + constructor(x: Real, y: Real, z: Real); +} +export const Point = _occ.Point3D as typeof Point1; +Point.prototype.toString = function () { + return ( + "{" + + " x: " + + f(this.x, 8, 3) + + "," + + " y: " + + f(this.y, 8, 3) + + "," + + " z: " + + f(this.z, 8, 3) + + "" + + " }" + ); +}; + +// ----------------------------------------------------------------------------- Vector +export interface Vector1 extends IVector {} +export declare class Vector1 implements IVector { + constructor(u: Real, v: Real, w: Real); +} +export const Vector = _occ.Vector3D as typeof Vector1; +// add utilities +export const XDir: Triplet = [1, 0, 0]; +export const YDir: Triplet = [0, 1, 0]; +export const ZDir: Triplet = [0, 0, 1]; + +// ----------------------------------------------------------------------------- Transformation + +export interface Transformation1 extends ITransform {} +export declare class Transformation1 implements ITransform {} +export const Transformation = _occ.Transformation as typeof Transformation1; + +// ----------------------------------------------------------------------------- Vertex +export interface Vertex1 extends IVertex {} +export declare class Vertex1 implements IVertex {} +export const Vertex = _occ.Vertex as Vertex1; +(Vertex as any).prototype.toString = Point.prototype.toString; + +// ----------------------------------------------------------------------------- Edge +export interface Edge1 extends IEdge {} +export declare class Edge1 implements IEdge {} +export const Edge = _occ.Edge as typeof Edge1; +function f(a: number, w: number, p: number) { + return (" " + (a + 0).toFixed(p)).substr(-w); +} +(Edge as any).prototype.toString = function (this: IEdge) { + return ( + "Edge => { \n" + + " numVertices: " + + this.numVertices + + "\n" + + " vertices: " + + this.getVertices() + .map((f) => { + return f.toString(); + }) + .join(" ") + + "}" + ); +}; + +export const _ShapeIterator = _occ.ShapeIterator; + +export interface EdgeIterator extends IShapeIterator {} +export class EdgeIterator + extends _ShapeIterator + implements IShapeIterator +{ + constructor(faceOrSolid: IFace | ISolid) { + super(faceOrSolid, "EDGE"); + } +} + +// ----------------------------------------------------------------------------- Wire +export interface Wire1 extends IWire {} + +export declare class Wire1 { + constructor(); +} +export const Wire = _occ.Wire as typeof Wire1; + +// ----------------------------------------------------------------------------- Face +export interface Face1 extends IFace {} +export declare class Face1 implements IFace {} +export const Face = _occ.Face as typeof Face1; +assert(Face); + +export interface FaceIterator extends IShapeIterator {} +export class FaceIterator + extends _ShapeIterator + implements IShapeIterator +{ + constructor(solid: ISolid) { + super(solid, "FACE"); + } +} + +// ----------------------------------------------------------------------------- Solid +export interface Solid1 extends ISolid {} +export declare class Solid1 {} +export const Solid = _occ.Solid as typeof Solid1; +assert(Solid); + +// ----------------------------------------------------------------------------- Mesh + +export const makeLine = _occ.makeLine; +export const makeArc3P = _occ.makeArc3P; +export const makeVertex = _occ.makeVertex; +export const makeWire = _occ.makeWire; +export const makeBox = _occ.makeBox; +export const makeCylinder = _occ.makeCylinder; + +// complete object prototypes with pure Javascript +import { init as initMesh } from "./mesh"; +import { init as initShape } from "./shape"; +initMesh(); +initShape(_occ); diff --git a/lib/scriptrunner.js b/lib/scriptrunner.js deleted file mode 100644 index 3949daf..0000000 --- a/lib/scriptrunner.js +++ /dev/null @@ -1,96 +0,0 @@ -"use strict"; -/* global require,console,require */ -const fs = require("fs"); -const vm = require("vm"); -const util = require("util"); -const getTemporaryFilePath = require("gettemporaryfilepath"); -const doDebug = false; - - -function ScriptRunner(envparam) { - const self = this; - self.env = { - - - "print": function () { - self.env.console.log.apply(self.env.console, arguments); - }, - - "fnum": function (value, width, prec) { - const a = value.toFixed(prec); - const s = " " + a; - return s.slice(s.length - width); - }, - - "logs": [], - - "console": { - "log": function () { - /// console.log.apply(console,arguments); - self.env.logs.push(arguments); - } - }, - - "eval": function () { - throw new Error("eval is forbidden"); - }, - "require": function () { - throw new Error("require is forbidden"); - }, - "setTimeout": function () { - throw new Error("setTimeout is forbidden"); - }, - "setInterval": function () { - throw new Error("setInterval is forbidden"); - }, - error: null - }; - - // extend default env object with env parameters - Object.keys(envparam).forEach(p => { - if (envparam.hasOwnProperty(p)) { - self.env[p] = envparam[p]; - } - }); -} - - -function getLineNumber() { - const original = Error.prepareStackTrace; - const error = {}; - Error.captureStackTrace(error, getLineNumber); - const lineNumber = error.stack; - Error.prepareStackTrace = original; - return lineNumber; -} - -ScriptRunner.prototype.run = function (code, done_callback, error_callback) { - - const settings = { - prefix: "script", - suffix: ".bar" - }; - - const self = this; - const log = self.env.console.log; - - const filename = getTemporaryFilePath(settings); - - try { - - vm.runInNewContext(code, self.env, filename); - done_callback(); - } - catch (_err) { - - console.trace("\n-------------------------------- EXCEPTION CAUGHT -----------------"); - - log("transaction ended with an error", _err.message); - log("error string = ", _err.toString()); - log("error stack = ", _err.stack); - error_callback(_err); - } -}; - - -exports.ScriptRunner = ScriptRunner; diff --git a/lib/scriptrunner.ts b/lib/scriptrunner.ts new file mode 100644 index 0000000..1938b4a --- /dev/null +++ b/lib/scriptrunner.ts @@ -0,0 +1,93 @@ +import vm from "vm"; +import os from "os"; +import path from "path"; +const doDebug = false; + +function getTemporaryFilePath({ + prefix, + suffix +}: { + prefix: string; + suffix: string; +}) { + return path.join(os.tmpdir(), prefix, suffix); +} +export class ScriptRunner { + public env: Record; + + constructor(envparam: any) { + console.log("Constructing a ScriptRunner"); + this.env = { + print: () => { + this.env.console.log.apply(this.env.console, arguments); + }, + + fnum: (value: number, width: number, prec: number) => { + const a = value.toFixed(prec); + const s = " " + a; + return s.slice(s.length - width); + }, + + logs: [], + + console: { + log: () => { + /// console.log.apply(console,arguments); + this.env.logs.push(arguments); + } + }, + + eval: () => { + throw new Error("eval is forbidden"); + }, + require: () => { + throw new Error("require is forbidden"); + }, + setTimeout: () => { + throw new Error("setTimeout is forbidden"); + }, + setInterval: () => { + throw new Error("setInterval is forbidden"); + }, + error: null + }; + + // extend default env object with env parameters + Object.keys(envparam).forEach((p) => { + if (envparam.hasOwnProperty(p)) { + this.env[p] = envparam[p]; + } + }); + } + + run( + code: string, + done_callback: () => void, + error_callback: (err: Error) => void + ) { + const settings = { + prefix: "script", + suffix: ".bar" + }; + + const log = this.env.console.log; + + const filename = getTemporaryFilePath(settings); + (async () => { + try { + let result = await vm.runInNewContext(code, this.env, filename); + done_callback(); + } catch (_err) { + const err = _err as Error; + console.trace( + "\n-------------------------------- EXCEPTION CAUGHT -----------------" + ); + + log("transaction ended with an error", err.message); + // log("error string = ", err.toString()); + log("error stack = ", err.stack); + error_callback(err); + } + })(); + } +} diff --git a/lib/shape.js b/lib/shape.js deleted file mode 100644 index 24a9e4a..0000000 --- a/lib/shape.js +++ /dev/null @@ -1,212 +0,0 @@ -const assert = require("assert"); -const occ = require("./bindings"); -const fs = require("fs"); - -function debugLog() { - arguments; -} - -function export_debug_step(solid) { - - let debug_step_file = "debug_step"; - let counter= 0; - while (fs.existsSync(debug_step_file + counter.toString() + ".step")) { - counter ++; - } - debug_step_file = debug_step_file + counter.toString() + ".step"; - - debugLog("The solid causing problem has been saved in ", debug_step_file); - occ.writeSTEP(debug_step_file, solid); -} -exports.init= function() { - - - occ.Solid.prototype.getAllEdges = function() { - // deprecated : use Solid.getEdgesi ! - const edges = []; - const iterator = new occ.ShapeIterator(this, "EDGE"); - while (iterator.more) { - edges.push(iterator.next()); - } - return edges; - }; - occ.Face.prototype.getAllEdges = occ.Solid.prototype.getAllEdges; - occ.Wire.prototype.getAllEdges = occ.Solid.prototype.getAllEdges; - - - occ.BoundingBox.prototype.toString = function () { - return "[ " + this.nearPt.x.toFixed(3) + - "," + this.nearPt.y.toFixed(3) + - "," + this.nearPt.z.toFixed(3) +"]" + - "[ " + this.farPt.x.toFixed(3) + - "," + this.farPt.y.toFixed(3) + - "," + this.farPt.z.toFixed(3) +"]"; - }; - - - occ.buildSolidMeshNew = function (solid) { - - function makeEdgesIndexes(solid, jsonSolidMesh) { - - // produce each edge - const mesh = solid.mesh; - let indexes = null; - - solid.getEdges().forEach(edge => { - if (edge.isSeam) { - return; - } - try { - indexes = mesh.getEdgeIndices(edge); - } - catch(err) { - - // fall back to complete edge - const polyline = edge.polygonize(); - if (!polyline) { - debugLog("mesh# failed ! cannot extract edges indexes on solid", err, solid.hasMesh, solid.name, solid.getShapeName(edge)); - debugLog(" mesh", mesh.numVertex); - debugLog(" edge", edge.polygonize()); - export_debug_step(solid); - //xx process.exit(2); - } - - const entry = { - name: solid.getShapeName(edge), - mesh: toBase64(polyline) - }; - jsonSolidMesh.edges.push(entry); - return; - } - if (!indexes || indexes.length == 0) { - return ; // ignore empty edges - } - - const entry = { - name: solid.getShapeName(edge), - indexes: toBase64(indexes), - }; - jsonSolidMesh.edges.push(entry); - }); - } - - function toBase64_1(typedArray) { - return ( new Buffer(typedArray.buffer)).toString("base64"); - } - - toBase64_1; - - function toBase64(typedArray) { - const a = []; - for (let i = 0; i < typedArray.length; i++) { - a[i] = (typedArray[i]); - } - return a; - } - function makeFacesIndexes(solid, jsonSolidMesh) { - - const mesh = solid.mesh; - solid.getFaces().forEach(face => { - - const indexes = mesh.getFaceTriangles(face); - const normalindexes = mesh.getFaceTriangleNormals(face); - - const entry = { - name: solid.getShapeName(face), - indexes: toBase64(indexes), - normalIndexes: toBase64(normalindexes) - }; - //xx entry.mesh.materials[0].colorDiffuse = [ Math.random(),Math.random(),Math.random()]; - jsonSolidMesh.faces.push(entry); - }); - - } - - assert(solid.hasOwnProperty("name"), "occ.buildSolidMesh : the solid must have a name"); - - - // make sure object is meshed - if (!solid.hasMesh) { - try { - solid.createMesh(0.5,5); - } - catch(err) { - // - } - assert(solid.hasMesh); - } - const mesh = solid.mesh; - - - const jsonSolidMesh = {name: solid.name, vertices: [], faces: [], edges: []}; - - jsonSolidMesh.vertices = toBase64(mesh.vertices); - jsonSolidMesh.normals = toBase64(mesh.normals); - - makeFacesIndexes(solid, jsonSolidMesh); - - makeEdgesIndexes(solid, jsonSolidMesh); - - jsonSolidMesh.version = "2.0"; - return jsonSolidMesh; - }; - - - occ.buildSolidMesh = function (solid) { - - assert(solid.hasOwnProperty("name"), "occ.buildSolidMesh : the solid must have a name"); - - // make sure object is meshed - const mesh = solid.mesh; - mesh; - - // produce each faces - const faces = solid.getFaces(); - let face; - - const jsonSolidMesh = {name: solid.name, faces: [], edges: []}; - let i, entry; - - for (i = 0; i < faces.length; i++) { - face = faces[i]; - - if (!face.hasMesh) { - continue; - } - entry = { - name: solid.getShapeName(face), - // color:(r*255+g)*255+b, - mesh: face.mesh.toJSON() - }; - entry.mesh.materials[0].colorDiffuse = [Math.random(), Math.random(), Math.random()]; - jsonSolidMesh.faces.push(entry); - } - // produce each edge - - const edges = solid.getEdges(); - let edge; - for (i = 0; i < edges.length; i++) { - edge = edges[i]; - - if (edge.isSeam) { - continue; - } - const polygone = edge.polygonize(); - - //xx console.log( "polygone.length = ",polygone.length); - const pts = []; - for (let j = 0; j < polygone.length; j++) { - pts.push(polygone[j]); - } - entry = { - name: solid.getShapeName(edge), - mesh: pts - }; - //entry.mesh.materials[0].colorDiffuse could be [ Math.random(),Math.random(),Math.random()]; - jsonSolidMesh.edges.push(entry); - } - jsonSolidMesh.version = "1.0"; - return jsonSolidMesh; - }; - -}; diff --git a/lib/shape.ts b/lib/shape.ts new file mode 100644 index 0000000..b3f6eca --- /dev/null +++ b/lib/shape.ts @@ -0,0 +1,247 @@ +import assert from "assert"; +import fs from "fs"; +import { OCC, ISolid, Triplet } from "./interfaces"; +import { occ } from "./occ"; + +function debugLog(...args: any[]) { + arguments; +} + +function export_debug_step(solid: ISolid) { + let debug_step_file = "debug_step"; + let counter = 0; + while (fs.existsSync(debug_step_file + counter.toString() + ".step")) { + counter++; + } + debug_step_file = debug_step_file + counter.toString() + ".step"; + + debugLog("The solid causing problem has been saved in ", debug_step_file); + occ.writeSTEP(debug_step_file, solid); +} + +export type TypedArray = + | Uint8Array + | Uint16Array + | Uint32Array + | Float32Array + | Float64Array; + +type Base64EncodingBuffer = number[]; + +interface IFaceMesh { + name: string; + indexes?: Base64EncodingBuffer; + normalIndexes?: Base64EncodingBuffer; + mesh?: any; +} + +export interface IMesh2 { + name?: string; + edges: any; + version: string; + vertices: any; + faces: IFaceMesh[]; + normals: any; +} + +export function init(occ: OCC) { + // Solid.prototype.getAllEdges = function () { + // // deprecated : use Solid.getEdgesi ! + // const edges: IEdge[] = []; + // const iterator = new ShapeIterator(this, "EDGE"); + // while (iterator.more) { + // edges.push(iterator.next()); + // } + // return edges; + // }; + // Face.prototype.getAllEdges = Solid.prototype.getAllEdges; + // Wire.prototype.getAllEdges = Solid.prototype.getAllEdges; + + occ.buildSolidMeshNew = (solid: ISolid) => { + function makeEdgesIndexes(solid: ISolid, jsonSolidMesh: IMesh2) { + // produce each edge + const mesh = solid.mesh; + let indexes: Uint8Array | Uint16Array | Uint32Array | undefined = + undefined; + + solid.getEdges().forEach((edge) => { + if (edge.isSeam) { + return; + } + try { + indexes = mesh.getEdgeIndices(edge); + } catch (err) { + // fall back to complete edge + const polyline = edge.polygonize(); + if (!polyline) { + debugLog( + "mesh# failed ! cannot extract edges indexes on solid", + err, + solid.hasMesh, + solid.name, + solid.getShapeName(edge) + ); + debugLog(" mesh", mesh.numVertices); + debugLog(" edge", edge.polygonize()); + export_debug_step(solid); + //xx process.exit(2); + } + + const entry = { + name: solid.getShapeName(edge), + mesh: toBase64(polyline) + }; + jsonSolidMesh.edges.push(entry); + return; + } + if (!indexes || indexes.length == 0) { + return; // ignore empty edges + } + + const entry = { + name: solid.getShapeName(edge), + indexes: toBase64(indexes) + }; + jsonSolidMesh.edges.push(entry); + }); + } + + Uint16Array; + function toBase64_1(typedArray: TypedArray) { + return Buffer.from(typedArray.buffer).toString("base64"); + } + + toBase64_1; + + function toBase64( + typedArray: TypedArray | number[] | Triplet[] + ): Base64EncodingBuffer { + const a = []; + for (let i = 0; i < typedArray.length; i++) { + a[i] = typedArray[i]; + } + return a as any /* FIX ME */; + } + + function makeFacesIndexes(solid: ISolid, jsonSolidMes: IMesh2) { + const mesh = solid.mesh; + solid.getFaces().forEach((face) => { + const indexes = mesh.getFaceTriangles(face); + const normalindexes = mesh.getFaceTriangleNormals(face); + + const entry = { + name: solid.getShapeName(face), + indexes: toBase64(indexes), + normalIndexes: toBase64(normalindexes) + }; + //xx entry.mesh.materials[0].colorDiffuse = [ Math.random(),Math.random(),Math.random()]; + jsonSolidMesh.faces.push(entry); + }); + } + + assert( + solid.hasOwnProperty("name"), + "occ.buildSolidMesh : the solid must have a name" + ); + + // make sure object is meshed + if (!solid.hasMesh) { + try { + solid.createMesh(0.5, 5); + } catch (err) { + // + } + assert(solid.hasMesh); + } + const mesh = solid.mesh; + + const jsonSolidMesh: IMesh2 = { + name: solid.name, + version: "", + vertices: [], + faces: [], + edges: [], + normals: [] + }; + + jsonSolidMesh.vertices = toBase64(mesh.vertices); + jsonSolidMesh.normals = toBase64(mesh.normals); + + makeFacesIndexes(solid, jsonSolidMesh); + + makeEdgesIndexes(solid, jsonSolidMesh); + + jsonSolidMesh.version = "2.0"; + return jsonSolidMesh; + }; + + occ.buildSolidMesh = function (solid: ISolid) { + assert( + solid.hasOwnProperty("name"), + "occ.buildSolidMesh : the solid must have a name" + ); + + // make sure object is meshed + const mesh = solid.mesh; + mesh; + + // produce each faces + const faces = solid.getFaces(); + let face; + + const jsonSolidMesh: IMesh2 = { + version: "", + name: solid.name, + vertices: [], + faces: [], + edges: [], + normals: [] + }; + let i; + + for (i = 0; i < faces.length; i++) { + face = faces[i]; + + if (!face.hasMesh) { + continue; + } + const entry: IFaceMesh = { + name: solid.getShapeName(face), + // color:(r*255+g)*255+b, + mesh: face.mesh.toJSON() as any + }; + entry.mesh.materials[0].colorDiffuse = [ + Math.random(), + Math.random(), + Math.random() + ]; + jsonSolidMesh.faces.push(entry); + } + // produce each edge + + const edges = solid.getEdges(); + let edge; + for (i = 0; i < edges.length; i++) { + edge = edges[i]; + + if (edge.isSeam) { + continue; + } + const polygone = edge.polygonize(); + + //xx console.log( "polygone.length = ",polygone.length); + const pts = []; + for (let j = 0; j < polygone.length; j++) { + pts.push(polygone[j]); + } + const entry: IFaceMesh = { + name: solid.getShapeName(edge), + mesh: pts + }; + //entry.mesh.materials[0].colorDiffuse could be [ Math.random(),Math.random(),Math.random()]; + jsonSolidMesh.edges.push(entry); + } + jsonSolidMesh.version = "1.0"; + return jsonSolidMesh; + }; +} diff --git a/lib/shapeFactory.js b/lib/shapeFactory.js deleted file mode 100644 index 6d0ef87..0000000 --- a/lib/shapeFactory.js +++ /dev/null @@ -1,755 +0,0 @@ -"use strict"; -// shape factory -const occ = require("./occ"); -const assert = require("assert"); - -/** - * - * @param parameters - * @param parameters.height = 70.0 - * @param parameters.filletRadius = 2.6 - * @returns {*} - */ -exports.makeBottle = function (occ, parameters) { - assert(occ.hasOwnProperty("makeLine")); - - parameters = parameters || {}; - - const smallThickness = 1.0; - const myWidth = 50.0; - const myThickness = 30.0; - const myHeight = parameters.height || 70.0; - const myFilletRadius = parameters.filletRadius || myThickness / 12.0; - - // - // (1) - // +.......................|.......................+ (5) - // | . | - // | | | - // (2)+ . + (4) - // | - // +(3) - // - const aPnt1 = [-myWidth / 2.0, 0.0, 0]; - const aPnt2 = [-myWidth / 2.0, -myThickness / 4.0, 0]; - const aPnt3 = [0.0, -myThickness / 2.0, 0]; - const aPnt4 = [myWidth / 2.0, -myThickness / 4.0, 0]; - const aPnt5 = [myWidth / 2.0, 0.0, 0]; - - const aSegment1 = occ.makeLine(aPnt1, aPnt2); - const aArc1 = occ.makeArc3P(aPnt2, aPnt3, aPnt4); - const aSegment2 = occ.makeLine(aPnt4, aPnt5); - - const aHalfWire = occ.makeWire(aSegment1, aArc1, aSegment2); - - assert( false === aHalfWire.isClosed); - - assert( 3 === aHalfWire.numEdges); - assert( 4 === aHalfWire.numVertices); - - const trsf = occ.makePlaneMirror([0, 0, 0], [0, 1, 0]); - - const aMirroredWire = aHalfWire.transformed(trsf); - assert( false === aMirroredWire.isClosed); - - const aWire = occ.makeWire(aHalfWire, aMirroredWire); - - assert(aWire.isClosed); - - const aFace = occ.makeFace(aWire); - assert( 1 === aFace.numWires); - - let myBody = occ.makePrism(aFace, [0, 0, myHeight]); - - myBody = occ.makeFillet(myBody, myBody.getEdges(), myFilletRadius); - //xx occ.writeSTEP("body1_b.step",myBody); - - // --- create bottle neck - - const neckLocation = [0.0, 0.0, myHeight]; - const neckAxis = [0, 0, 1.0]; - const neckRadius = myThickness / 4.0; - const neckHeight = myHeight / 10.0; - - const myNeck = occ.makeCylinder([neckLocation, neckAxis], neckRadius, neckHeight); - - myBody = occ.fuse(myBody, myNeck); - //xx occ.writeSTEP("body1_c.step",myBody); - - - // --- create an hollow solid - let zMax = 0; - let faceToRemove; - myBody.getFaces().forEach(function (face) { - //xx console.log(" examining face = ", myBody.getShapeName(face),face.isPlanar,face.centreOfMass.z); - if (face.isPlanar && face.centreOfMass.z >= zMax) { - faceToRemove = face; - zMax = face.centreOfMass.z; - } - }); - - myBody = occ.makeThickSolid(myBody, faceToRemove, smallThickness); - return myBody; - -}; - -exports.makePan = function (csg, _height, _radius) { - - const height = _height || 20; - const radius = _radius || 25.0; - const thickness = 1; - const handleRadius = 4; - const handleLength = 30; - - const s1 = csg.makeCylinder([0, 0, 0], [0, 0, height], radius); - - const s2 = csg.makeSphere([0, 0, 0], radius); - - const s3 = csg.makeCylinder([0, 0, -radius * 0.7], [0, 0, height], radius * 2); - const s4 = csg.fuse(s1, s2); - const s5 = csg.common(s4, s3); - - const pt1 = [radius - 2 * thickness, 0, height - handleRadius * 1.1]; - const pt2 = [handleLength + radius - 2 * thickness, 0, height - handleRadius * 1.1]; - const handle = csg.makeCylinder(pt1, pt2, handleRadius); - - const s6 = csg.fuse(s5, handle); - - const r1 = csg.makeCylinder([0, 0, 0], [0, 0, height], radius - thickness); - const r2 = csg.makeSphere([0, 0, 0], radius - thickness); - const r3 = csg.makeCylinder([0, 0, -radius * 0.7 + thickness], [0, 0, height], radius * 2); - const r4 = csg.fuse(r1, r2); - const r5 = csg.common(r4, r3); - - let body = csg.cut(s6, r5); - - const lidHeight = 10; - const lid = exports.makePanLid(csg, radius, lidHeight, height); - lid.translate([0, 0, 1]); - - body = csg.fuse(body, lid); - - return body; - -}; -exports.makePanLid = function (csg, _r, _height, _H) { - "use strict"; - - // r : pan radius - // height : - const r = _r || 25.0; - const h = _height || 10; - const thickness = 1; - - // r**2 + (R-h)**2 = R**2 - // r**2 + R**2-2*h*R +h**2 = R**2 - // => R = ( r**2+h**2)/(2*h); - - const R = ( r * r + h * h) / (2 * h); - - const center = [0, 0, _H + h - R]; - - const outerSphere = csg.makeSphere(center, R); - const innerSphere = csg.makeSphere(center, R - thickness); - let solid = csg.cut(outerSphere, innerSphere); - - const cyl = csg.makeCylinder([0, 0, _H + h - 3 * R], [0, 0, _H], R + r * 2); - - solid = csg.cut(solid, cyl); - - return solid; - -}; - -exports.makeRoundedPlate = function (csg, R1, R2, L, thickness) { - "use strict"; - - R1 = R1 || 7; - R2 = R2 || 2.5; - - L = L || 12; - thickness = thickness || 1.5; - - const rad2deg = 180 / Math.atan(1.0) / 4.0; - - const sinAlpha = (R1 - R2) / L; - const angle = Math.asin(sinAlpha) * rad2deg; - const L2 = L * (1 - sinAlpha * sinAlpha); - - const q0 = [-200 * R1, 0, thickness]; - const p1 = [-R1, L2, 0]; - const p2 = [0, 0, thickness]; - const p3 = [R1, L2, 0]; - const q3 = [200 * R1, 0, thickness]; - - let a = csg.makeBox(p1, p2); - - a = a.rotate(p2, [0, 0, 1], -angle); - - let b = csg.makeBox(p2, p3); - b = b.rotate(p2, [0, 0, 1], angle); - let v = csg.fuse(b, a); - - // remove unwanted material - v = csg.cut(v, csg.makeBox(q0, p1).rotate(p2, [0, 0, 1], -angle)); - v = csg.cut(v, csg.makeBox(q3, p3).rotate(p2, [0, 0, 1], angle)); - - // return v; - const c1 = csg.makeCylinder([0, 0, 0], [0, 0, thickness], R1); - v = csg.fuse(v, c1); - const c2 = csg.makeCylinder([0, L, 0], [0, L, thickness], R2); - v = csg.fuse(v, c2); - - return v; -}; - -exports.makeRivetPlate = function (csg, params) { - // see http://www.tracepartsonline.net/%28S%281gpggj45ixmu5o5540hxuofo%29%29/PartsDefs/Production/ALCOA/22-02072002-063054/documents/AJAL103.pdf - // { A: 18, B:7, C:6.0, F:4.7, H:3.6, H1:2.0, H2:3.0, J:6.0, K:2.5, R:2.5, V:1.5 } - // { A: 24.3, B:9.5, C:8.5, F:4.7, H:5.3, H1:2.8, H2:4.8, J:8.0, K:2.5, R:3.0, V:1.5 } - // { A: 26.0, B:11.0, C:9.5, F:4.7, H:6.0, H1:3.5, H2:5.5, J:8.0, K:2.5, R:3.0, V:1.5 } - // { A: 29.0, B:13.0, C:11.0, F:4.7, H:7.0, H1:4.2, H2:6.2, J:8.0, K:3.3, R:3.5, V:1.5 } - // { A: 33.5, B:18.0, C:13.0, F:6.0, H:9.3, H1:5.1, H2:8.5, J:8.0, K:3.3, R:3.5, V:1.5 } - //xx const A = params.A || 18; - const B = params.B || 7; - const C = params.C || 6; - //xx const F = params.F || 4.7; - //xx const H = params.H || 3.6; - const H1 = params.H1 || 2.0; - const H2 = params.H2 || 3.0; - const J = params.J || 6.0; - const K = params.K || 2.5; - const R = params.R || 2.5; - const V = params.V || 1.5; - - let base = exports.makeRoundedPlate(csg, B / 2, R, C + J, V); - base = csg.fuse(base, csg.makeCylinder([0, 0, 0], [0, 0, H1], B / 2 * 0.8)); - base = csg.fuse(base, csg.makeCone([0, 0, H1], B / 2 * 0.8, [0, 0, H2], B / 2 * 0.6)); - base = csg.cut(base, csg.makeCylinder([0, 0, 0], [0, 0, H2], K / 2)); - base = csg.cut(base, csg.makeCylinder([0, C + J, 0], [0, C + J, H2], K / 2)); - base = csg.cut(base, csg.makeCylinder([0, C, 0], [0, C, V], K / 2)); - return base; -}; - -occ.makePan = function (params) { - "use strict"; - // { R: 10, H: 30 } - return exports.makePan(occ, params.H, params.R); -}; -occ.makeRivetPlate = function (params) { - "use strict"; - return exports.makeRivetPlate(occ, params); -}; - -occ.makeRoundedPlate = function (R1, R2, L, thickness) { - "use strict"; - return exports.makeRoundedPlate(occ, R1, R2, L, thickness); -}; - -/** - * params: - * r1 : radius of the cylinder and base of cone - * r2 : cone top face radius - * H : cone height - * H2 : cylinder height - * rs : fillet radius or radius of the torus which is - * tangent to the cone and the cylinder. - */ -occ.makeCylinderTorusCone = function (r1, r2, H, H2, rs) { - // ------------------------------------------------------------ - // create a cylinder capped with a cone and a round fillet - // at the intersection. - // R2| - // /----. H - // / | - // (rs) (------.- 0 ( torus) - // | | - // | . - // +------|- -H2 - // R1 - // ------------------------------------------------------------ - - const csg = this; - - /* example : r1 = 20 ,r2 = 15 , H = 5 ,H2 = 10 rs = 5 */ - - // calculate the cone half angle - const angle = Math.atan((r1 - r2) / H); - // calculate the distance below the cylinder top - // at which the torus is tangent to the cylinder - const d = -Math.tan(angle / 2) * rs; - // calculate the distance above the cone bottom - // at which the torus is tangent to the cone - const d2 = d + rs * Math.sin(angle); - // calculate the radius of the cone at the - // tangent edge with the torus. - const r1b = r1 - rs * (1.0 - Math.cos(angle)); - - const cyl = csg.makeCylinder([0, 0, -H2], [0, 0, d], r1); - const cone = csg.makeCone([0, 0, d2], r1b, [0, 0, H], r2); - const tore = csg.makeTorus([0, 0, d], [0, 0, 1], r1 - rs, rs); - - let v = csg.cut(tore, cone); - v = csg.cut(v, cyl); - - v = csg.fuse(v, cone); - v = csg.fuse(v, cyl); - return v; -}; - - -/** - * parameters: - * r : external radius of the lid - * height : - * H : Z position of the planar face of the lid - * - * _ ----| - * + . - * / \/ | - * +--+\ . - * \ | - * \ . - * \ | - * \ | - * \| - * + - */ -exports.makeLidWithTorus = function (csg, r, h, rs, thickness) { - "use strict"; - - const r0 = r - rs; - const h0 = h - rs; - const tanAlpha = h0 / r0; - const alpha = Math.atan(tanAlpha); - - const hyp0_2 = r0 * r0 + h0 * h0; - // h0/hyp0 = (hyp0/2)/R0 - - const R0 = (hyp0_2 / 2.0) / h0; - const R = R0 + rs; - - const center = [0, 0, h0 - R0]; - - - const outerSphere = csg.makeSphere(center, R); - const innerSphere = csg.makeSphere(center, R - thickness); - let solid = csg.cut(outerSphere, innerSphere); - - // lets cut the sphere - // lets cut the sphere - const hh = R / 3; - // . - // . | tan(a)=s/c => s=h*tan( - // +-----|------- - const c1 = [center[0], center[1], center[2] + hh]; - const r1 = Math.tan(2 * alpha) * hh; - const c2 = [center[0], center[1], center[2] + (R + hh)]; - const r2 = Math.tan(2 * alpha) * (R + hh); - - const cuttingcone = csg.makeCone(c1, r1, c2, r2); - solid = csg.common(solid, cuttingcone); - - solid = csg.common(solid, cuttingcone); - - const cyl = csg.makeCylinder(center, [0, 0, 0], R); - // lets add a torus - let outerfillet = csg.makeTorus([0, 0, 0], [0, 0, 1], r0, rs); - outerfillet = csg.cut(outerfillet, cuttingcone); - outerfillet = csg.cut(outerfillet, cyl); - - - let fillet = outerfillet; - if (rs - thickness > 0) { - let innerfillet = csg.makeTorus([0, 0, 0], [0, 0, 1], r0, rs - thickness); - innerfillet = csg.cut(innerfillet, cuttingcone); - fillet = csg.cut(fillet, innerfillet); - } - fillet = csg.cut(fillet, cuttingcone); - return csg.fuse(solid, fillet); - //xx return csg.compound([solid,fillet]); - -}; - -exports.makeTube = function (csg, p1, p2, R, thickness) { - const cyl1 = csg.makeCylinder(p1, p2, R); - const cyl2 = csg.makeCylinder(p1, p2, R - thickness); - return csg.cut(cyl1, cyl2); -}; - - -exports.makeHollowCylinder = function (csg, R, H, h, rf, thickness) { - let top = exports.makeLidWithTorus(csg, R, h, rf, thickness); - let bottom = top.clone(); - bottom = bottom.rotate([0, 0, 0], [1, 0, 0], 180); - - const cyl = exports.makeTube(csg, [0, 0, 0], [0, 0, H], R, thickness); - top = top.translate([0, 0, H]); - let solid = csg.fuse(bottom, cyl); - solid = csg.fuse(solid, top); - return solid; -}; - - -exports.testHollowCylinder = function (csg) { - - const obj = exports.makeHollowCylinder(csg, 40, 100, 10, 5, 1); - // create a section to verify visually the correctness of - // the construction. - const cuttingPlanes = csg.makeBox([0, 0, -100], [100, 200, 100]); - return csg.cut(obj, cuttingPlanes); - -}; - - -exports.makeLegoBrickSlow = function (csg, nX, nY, h) { - - if (h === "thin") { - h = 2; - } else if (h === "thick") { - h = 6; - } else { - throw new Error("invalid"); - } - - - const u = 1.6; // lego unit - - const outerWidth = nX * u * 5; - const outerLength = nY * u * 5; - const outerHeight = h * u; - - const outerBlock = csg.makeBox([0, 0, 0], [outerWidth, outerLength, outerHeight]); - - const innerWidth = outerWidth - 2 * u; - const innerLength = outerLength - 2 * u; - const innerHeight = outerHeight - u; - - let innerBlock = csg.makeBox([0, 0, 0], [innerWidth, innerLength, innerHeight]); - innerBlock = innerBlock.translate([u, u, 0]); - let hollowBlock = csg.cut(outerBlock, innerBlock); - - const pt1 = [2.5 * u, 2.5 * u, outerHeight - 3 * u]; - const pt2 = [2.5 * u, 2.5 * u, outerHeight + 3 * u]; - let h1 = csg.makeCylinder(pt1, pt2, 0.75 * u); - - const pt3 = [2.5 * u, 2.5 * u, outerHeight]; - const pt4 = [2.5 * u, 2.5 * u, outerHeight + u]; - let h2 = csg.makeCylinder(pt3, pt4, 1.5 * u); - - // installer la grille - for (let y = 0; y < nY; y++) { - let hh1 = h1.clone(); - let hh2 = h2.clone(); - for (let x = 0; x < nX; x++) { - // - hollowBlock = csg.cut(hollowBlock, hh1); - hollowBlock = csg.fuse(hollowBlock, hh2); - hh1 = hh1.translate([5 * u, 0, 0]); - hh2 = hh2.translate([5 * u, 0, 0]); - } - h1 = h1.translate([0, 5 * u, 0]); - h2 = h2.translate([0, 5 * u, 0]); - } - - const pt5 = [2.5 * u, 2.5 * u, 0]; - const pt6 = [2.5 * u, 2.5 * u, outerHeight - u]; - let pinOuter = csg.makeCylinder(pt5, pt6, u); - - const pt7 = [2.5 * u, 2.5 * u, 0]; - const pt8 = [2.5 * u, 2.5 * u, outerHeight - u]; - let pinInner = csg.makeCylinder(pt7, pt8, 0.5 * u); - - let p = csg.cut(pinOuter, pinInner); - let pp; - if (nY == 1) { - // install small pin insid - p = p.translate([2.5 * u, 0, 0]); - for (let x = 0; x < nX - 1; x++) { - hollowBlock = csg.fuse(hollowBlock, p); - p = p.translate([5 * u, 0, 0]); - } - } - if (nX == 1) { - p = p.translate([0, 2.5 * u, 0]); - for (let y = 0; y < nY - 1; y++) { - hollowBlock = csg.fuse(hollowBlock, p); - p = p.translate([0, 5 * u, 0]); - } - } - if (nX > 1 && nY > 1) { - - const pt9 = [5 * u, 5 * u, 0]; - const pt10 = [5 * u, 5 * u, outerHeight - u]; - pinOuter = csg.makeCylinder(pt9, pt10, 4.07 / 2.0 * u); - - const pt11 = [5 * u, 5 * u, 0]; - const pt12 = [5 * u, 5 * u, outerHeight - u]; - pinInner = csg.makeCylinder(pt11, pt12, 1.5 * u); - - let pin = csg.cut(pinOuter, pinInner); - - for (let x = 0; x < nX - 1; x++) { - pp = pin.clone(); - for (let y = 0; y < nY - 1; y++) { - hollowBlock = csg.fuse(hollowBlock, pp); - pp = pp.translate([0, 5 * u, 0]); - } - pin = pin.translate([5 * u, 0, 0]); - } - } - return hollowBlock; -}; - - -function makeRepetition(csg, shape, dX, nX, dY, nY) { - let h1 = shape.clone(); - // installer la grille - const shapeArray = []; - for (let y = 0; y < nY; y++) { - let hh1 = h1.clone(); - for (let x = 0; x < nX; x++) { - shapeArray.push(hh1); - hh1 = hh1.translate([dX, 0, 0]); - } - h1 = h1.translate([0, dY, 0]); - } - return csg.compound(shapeArray); -} - -exports.makeLegoBrick = function (csg, nX, nY, h) { - - "use strict"; - - if (h === "thin") { - h = 2; - } else if (h === "thick") { - h = 6; - } else { - throw new Error("invalid h"); - } - - - const u = 1.6; // lego unit - - const outerWidth = nX * u * 5; - const outerLength = nY * u * 5; - const outerHeight = h * u; - - let brick = csg.makeBox([0, 0, 0], [outerWidth, outerLength, outerHeight]); - brick = csg.makeThickSolid(brick, brick.faces.bottom, -u); - - const pt1 = [2.5 * u, 2.5 * u, outerHeight]; - const pt2 = [2.5 * u, 2.5 * u, outerHeight + u]; - const h2 = csg.makeCylinder(pt1, pt2, 1.5 * u); - - let tetons = makeRepetition(csg, h2, 5 * u, nX, 5 * u, nY); - brick = csg.fuse(brick, tetons); - - const pt3 = [2.5 * u, 2.5 * u, outerHeight - 3 * u]; - const pt4 = [2.5 * u, 2.5 * u, outerHeight + 0.75]; - const h1 = csg.makeCylinder(pt3, pt4, 0.74 * u); - tetons = makeRepetition(csg, h1, 5 * u, nX, 5 * u, nY); - brick = csg.cut(brick, tetons); - - //xx console.log(Object.keys(brick.faces));//.bottom); - - // small pins - const pt5 = [2.5 * u, 2.5 * u, 0]; - const pt6 = [2.5 * u, 2.5 * u, outerHeight - u]; - let pinOuter = csg.makeCylinder(pt5, pt6, u); - - const pt7 = [2.5 * u, 2.5 * u, 0]; - const pt8 = [2.5 * u, 2.5 * u, outerHeight - u]; - let pinInner = csg.makeCylinder(pt7, pt8, 0.5 * u); - - let pin = csg.cut(pinOuter, pinInner); - - let p; - if (nY == 1) { - // install small pin insid - p = pin.clone(); - p = p.translate([2.5 * u, 0, 0]); - tetons = makeRepetition(csg, p, 5 * u, nX - 1, 0, 1); - brick = csg.fuse(brick, tetons); - - } else if (nX == 1) { - - p = pin.clone(); - p = p.translate([0, 2.5 * u, 0]); - tetons = makeRepetition(csg, p, 0, 1, 5 * u, nY - 1); - brick = csg.fuse(brick, tetons); - - } else if (nX > 1 && nY > 1) { - pinOuter = csg.makeCylinder([5 * u, 5 * u, 0], [5 * u, 5 * u, outerHeight - u], 4.07 / 2.0 * u); - pinInner = csg.makeCylinder([5 * u, 5 * u, 0], [5 * u, 5 * u, outerHeight - u], 1.5 * u); - pin = csg.cut(pinOuter, pinInner); - tetons = makeRepetition(csg, pin, 5 * u, nX - 1, 5 * u, nY - 1); - brick = csg.fuse(brick, tetons); - } - - return brick; -}; - - -exports.makePiston = function (occ) { - - // create the top wire - // ---| - // . . - // / | - // 2+-----+ . - // | 3 | - // 1+-------------. - // |<------------w--...> - // - - const w = 65; - const r = 20; - const h = 12; - - const p0 = occ.makeVertex([0, 0, 0]); - - const p1 = p0.translate([-w / 2.0, 0, 0]); - - const p2 = p1.translate([0.0, h, 0]); - const p3 = p0.translate([-r, h, 0]); - const p4 = p0.translate([0, h + r, 0]); - - - const trsf = occ.makePlaneMirror([0, 0, 0], [1, 0, 0]); - - const q1 = p1.transformed(trsf); - const q2 = p2.transformed(trsf); - const q3 = p3.transformed(trsf); - - const e1 = occ.makeLine(q1, p1); - const e2 = occ.makeLine(p1, p2); - const e3 = occ.makeLine(p2, p3); - const e4 = occ.makeArc3P(p3, p4, q3); - const e5 = occ.makeLine(q3, q2); - const e6 = occ.makeLine(q2, q1); - - const wire1 = occ.makeWire(e1, e2, e3, e4, e5, e6); - assert( 6 === wire1.numEdges); - - const face1 = occ.makeFace(wire1); - - const height = 12; - return occ.makePrism(face1, [0, 0, height]); - -}; - -exports.makeTutorialPart = function (occ) { - - const w = 60; - const H = 50; - const h = H / 2; - const a = 7.5; - const b = 20; - - const p0 = [b, -a / 2, 0]; - const p1 = [0, -a / 2, 0]; - const p2 = [0, -h, 0]; - const p3 = [w, -h, 0]; - const p4 = [w, h, 0]; - const p5 = [0, h, 0]; - const p6 = [0, a / 2, 0]; - const p7 = [b, a / 2, 0]; - - const p8 = [b + a / 2, 0, 0]; - - const e1 = occ.makeLine(p0, p1); - const e2 = occ.makeLine(p1, p2); - const e3 = occ.makeLine(p2, p3); - const e4 = occ.makeLine(p3, p4); - const e5 = occ.makeLine(p4, p5); - const e6 = occ.makeLine(p5, p6); - const e7 = occ.makeLine(p6, p7); - const e8 = occ.makeArc3P(p7, p8, p0); - - const wire = occ.makeWire(e1, e2, e3, e4, e5, e6, e7, e8); - assert(true === wire.isClosed); - - const height = 20; - const face = occ.makeFace(wire); - const body1 = occ.makePrism(face, [0, 0, height]); - - // -------------------------------------------------- - const height2 = 45; - const circle = occ.makeCircle([w, 0, 0], [0, 0, 1], h); - const wire2 = occ.makeWire(circle); - const face2 = occ.makeFace(wire2); - const body2 = occ.makePrism(face2, [0, 0, height2]); - - // ----------------------------------------------------- - const body3 = occ.fuse(body1, body2); - - // - // ------+ - // / - // + - // ------+ - // - const R = 15; - const angle = Math.asin(7.5 / R); - const dx = R * Math.cos(angle); - const dy = R * Math.sin(angle); - - const q1 = [w + dx, dy, 0]; - const q2 = [w + dx + 100, dy, 0]; - const q3 = [w + dx + 100, -dy, 0]; - const q4 = [w + dx, -dy, 0]; - const q5 = [w - R, 0, 0]; - - const ee1 = occ.makeLine(q1, q2); - const ee2 = occ.makeLine(q2, q3); - const ee3 = occ.makeLine(q3, q4); - const ee4 = occ.makeArc3P(q4, q5, q1); - const wire4 = occ.makeWire(ee1, ee2, ee3, ee4); - const face4 = occ.makeFace(wire4); - const body4 = occ.makePrism(face4, [0, 0, height2]); - - const body5 = occ.cut(body3, body4); - const edges = body5.getEdges(); - // -------------------------------------------- - // Select vertical edges with vertex P1 and P6 - // -------------------------------------------- - function same(a, b, tol) { - return Math.abs(a - b) < tol; - } - - function samePoint(p1, p2) { - const tol = 0.001; - return same(p1.x, p2.x, tol) && - same(p1.y, p2.y, tol) && - same(p1.z, p2.z, tol); - } - - function selectEdge(edges, p) { - - if (p instanceof occ.Vertex) { - p = occ.makeVertex(p) - } - const results = edges.filter(function (edge) { - const firstVertex = edge.firstVertex; - const lastVertex = edge.lastVertex; - return ( samePoint(firstVertex, p) || samePoint(lastVertex, p)) && - same(firstVertex.x, lastVertex.x, 0.01) && - same(firstVertex.y, lastVertex.y, 0.01); - }); - return results[0]; - } - - const edges_for_filet = [selectEdge(edges, p2), selectEdge(edges, p5)]; - - const body6 = occ.makeFillet(body5, edges_for_filet, 10); - - // create hole - const smallR = 5; - const heigth3 = height2 - smallR - 10; - const cyl = occ.makeCylinder([w - R - 10, 0, heigth3], [w - R + 20, 0, heigth3], smallR); - - return occ.cut(body6, cyl); -}; - diff --git a/lib/shapeFactory.ts b/lib/shapeFactory.ts new file mode 100644 index 0000000..a3b8be2 --- /dev/null +++ b/lib/shapeFactory.ts @@ -0,0 +1,818 @@ +import assert from "assert"; + +import { + OCC, + IEdge, + IFace, + IPoint, + PointLike, + Triplet, + UInteger, + VectorLike +} from "./interfaces"; +import { _occ } from "./occ"; + +export interface MakeBottleOptions { + height: number; // @default 70 + filletRadius: number; +} + +export function makeBottle(occ: OCC, parameters: MakeBottleOptions) { + assert(occ.hasOwnProperty("makeLine")); + + parameters = parameters || {}; + + const smallThickness = 1.0; + const myWidth = 50.0; + const myThickness = 30.0; + const myHeight = parameters.height || 70.0; + const myFilletRadius = parameters.filletRadius || myThickness / 12.0; + + // + // (1) + // +.......................|.......................+ (5) + // | . | + // | | | + // (2)+ . + (4) + // | + // +(3) + // + const aPnt1: Triplet = [-myWidth / 2.0, 0.0, 0]; + const aPnt2: Triplet = [-myWidth / 2.0, -myThickness / 4.0, 0]; + const aPnt3: Triplet = [0.0, -myThickness / 2.0, 0]; + const aPnt4: Triplet = [myWidth / 2.0, -myThickness / 4.0, 0]; + const aPnt5: Triplet = [myWidth / 2.0, 0.0, 0]; + + const aSegment1 = occ.makeLine(aPnt1, aPnt2); + const aArc1 = occ.makeArc3P(aPnt2, aPnt3, aPnt4); + const aSegment2 = occ.makeLine(aPnt4, aPnt5); + + const aHalfWire = occ.makeWire(aSegment1, aArc1, aSegment2); + + assert(false === aHalfWire.isClosed); + + assert(3 === aHalfWire.numEdges); + assert(4 === aHalfWire.numVertices); + + const trsf = occ.makePlaneMirror([0, 0, 0], [0, 1, 0]); + + const aMirroredWire = aHalfWire.transformed(trsf); + assert(false === aMirroredWire.isClosed); + + const aWire = occ.makeWire(aHalfWire, aMirroredWire); + + assert(aWire.isClosed); + + const aFace = occ.makeFace(aWire); + assert(1 === aFace.numWires); + + let myBody = occ.makePrism(aFace, [0, 0, myHeight]); + + myBody = occ.makeFillet(myBody, myBody.getEdges(), myFilletRadius); + //xx occ.writeSTEP("body1_b.step",myBody); + + // --- create bottle neck + + const neckLocation: PointLike = [0.0, 0.0, myHeight]; + const neckAxis: VectorLike = [0, 0, 1.0]; + const neckRadius = myThickness / 4.0; + const neckHeight = myHeight / 10.0; + + const myNeck = occ.makeCylinder( + [neckLocation, neckAxis], + neckRadius, + neckHeight + ); + + myBody = occ.fuse(myBody, myNeck); + //xx occ.writeSTEP("body1_c.step",myBody); + + // --- create an hollow solid + let zMax = 0; + let faceToRemove: IFace | undefined; + myBody.getFaces().forEach(function (face) { + //xx console.log(" examining face = ", myBody.getShapeName(face),face.isPlanar,face.centreOfMass.z); + if (face.isPlanar && face.centreOfMass.z >= zMax) { + faceToRemove = face; + zMax = face.centreOfMass.z; + } + }); + + if (!faceToRemove) throw new Error("Cannot find face to remove"); + + myBody = occ.makeThickSolid(myBody, faceToRemove, smallThickness); + return myBody; +} + +export function makePan(csg: OCC, _height: number, _radius: number) { + const height = _height || 20; + const radius = _radius || 25.0; + const thickness = 1; + const handleRadius = 4; + const handleLength = 30; + + const s1 = csg.makeCylinder([0, 0, 0], [0, 0, height], radius); + + const s2 = csg.makeSphere([0, 0, 0], radius); + + const s3 = csg.makeCylinder( + [0, 0, -radius * 0.7], + [0, 0, height], + radius * 2 + ); + const s4 = csg.fuse(s1, s2); + const s5 = csg.common(s4, s3); + + const pt1: Triplet = [radius - 2 * thickness, 0, height - handleRadius * 1.1]; + const pt2: Triplet = [ + handleLength + radius - 2 * thickness, + 0, + height - handleRadius * 1.1 + ]; + const handle = csg.makeCylinder(pt1, pt2, handleRadius); + + const s6 = csg.fuse(s5, handle); + + const r1 = csg.makeCylinder([0, 0, 0], [0, 0, height], radius - thickness); + const r2 = csg.makeSphere([0, 0, 0], radius - thickness); + const r3 = csg.makeCylinder( + [0, 0, -radius * 0.7 + thickness], + [0, 0, height], + radius * 2 + ); + const r4 = csg.fuse(r1, r2); + const r5 = csg.common(r4, r3); + + let body = csg.cut(s6, r5); + + const lidHeight = 10; + const lid = makePanLid(csg, radius, lidHeight, height); + lid.translate([0, 0, 1]); + + body = csg.fuse(body, lid); + + return body; +} + +export function makePanLid(csg: OCC, _r: number, _height: number, _H: number) { + "use strict"; + + // r : pan radius + // height : + const r = _r || 25.0; + const h = _height || 10; + const thickness = 1; + + // r**2 + (R-h)**2 = R**2 + // r**2 + R**2-2*h*R +h**2 = R**2 + // => R = ( r**2+h**2)/(2*h); + + const R = (r * r + h * h) / (2 * h); + + const center: Triplet = [0, 0, _H + h - R]; + + const outerSphere = csg.makeSphere(center, R); + const innerSphere = csg.makeSphere(center, R - thickness); + let solid = csg.cut(outerSphere, innerSphere); + + const cyl = csg.makeCylinder([0, 0, _H + h - 3 * R], [0, 0, _H], R + r * 2); + + solid = csg.cut(solid, cyl); + + return solid; +} + +export function makeRoundedPlate( + csg: OCC, + R1: number, + R2: number, + L: number, + thickness: number +) { + "use strict"; + + R1 = R1 || 7; + R2 = R2 || 2.5; + + L = L || 12; + thickness = thickness || 1.5; + + const rad2deg = 180 / Math.atan(1.0) / 4.0; + + const sinAlpha = (R1 - R2) / L; + const angle = Math.asin(sinAlpha) * rad2deg; + const L2 = L * (1 - sinAlpha * sinAlpha); + + const q0: PointLike = [-200 * R1, 0, thickness]; + const p1: PointLike = [-R1, L2, 0]; + const p2: PointLike = [0, 0, thickness]; + const p3: PointLike = [R1, L2, 0]; + const q3: PointLike = [200 * R1, 0, thickness]; + + let a = csg.makeBox(p1, p2); + + a = a.rotate(p2, [0, 0, 1], -angle); + + let b = csg.makeBox(p2, p3); + b = b.rotate(p2, [0, 0, 1], angle); + let v = csg.fuse(b, a); + + // remove unwanted material + v = csg.cut(v, csg.makeBox(q0, p1).rotate(p2, [0, 0, 1], -angle)); + v = csg.cut(v, csg.makeBox(q3, p3).rotate(p2, [0, 0, 1], angle)); + + // return v; + const c1 = csg.makeCylinder([0, 0, 0], [0, 0, thickness], R1); + v = csg.fuse(v, c1); + const c2 = csg.makeCylinder([0, L, 0], [0, L, thickness], R2); + v = csg.fuse(v, c2); + + return v; +} + +export function makeRivetPlate( + csg: OCC, + params: { + B: number; + C: number; + H1: number; + H2: number; + J: number; + K: number; + R: number; + V: number; + } +) { + // see http://www.tracepartsonline.net/%28S%281gpggj45ixmu5o5540hxuofo%29%29/PartsDefs/Production/ALCOA/22-02072002-063054/documents/AJAL103.pdf + // { A: 18, B:7, C:6.0, F:4.7, H:3.6, H1:2.0, H2:3.0, J:6.0, K:2.5, R:2.5, V:1.5 } + // { A: 24.3, B:9.5, C:8.5, F:4.7, H:5.3, H1:2.8, H2:4.8, J:8.0, K:2.5, R:3.0, V:1.5 } + // { A: 26.0, B:11.0, C:9.5, F:4.7, H:6.0, H1:3.5, H2:5.5, J:8.0, K:2.5, R:3.0, V:1.5 } + // { A: 29.0, B:13.0, C:11.0, F:4.7, H:7.0, H1:4.2, H2:6.2, J:8.0, K:3.3, R:3.5, V:1.5 } + // { A: 33.5, B:18.0, C:13.0, F:6.0, H:9.3, H1:5.1, H2:8.5, J:8.0, K:3.3, R:3.5, V:1.5 } + //xx const A = params.A || 18; + const B = params.B || 7; + const C = params.C || 6; + //xx const F = params.F || 4.7; + //xx const H = params.H || 3.6; + const H1 = params.H1 || 2.0; + const H2 = params.H2 || 3.0; + const J = params.J || 6.0; + const K = params.K || 2.5; + const R = params.R || 2.5; + const V = params.V || 1.5; + + let base = exports.makeRoundedPlate(csg, B / 2, R, C + J, V); + base = csg.fuse(base, csg.makeCylinder([0, 0, 0], [0, 0, H1], (B / 2) * 0.8)); + base = csg.fuse( + base, + csg.makeCone([0, 0, H1], (B / 2) * 0.8, [0, 0, H2], (B / 2) * 0.6) + ); + base = csg.cut(base, csg.makeCylinder([0, 0, 0], [0, 0, H2], K / 2)); + base = csg.cut(base, csg.makeCylinder([0, C + J, 0], [0, C + J, H2], K / 2)); + base = csg.cut(base, csg.makeCylinder([0, C, 0], [0, C, V], K / 2)); + return base; +} + +/** + * params: + * r1 : radius of the cylinder and base of cone + * r2 : cone top face radius + * H : cone height + * H2 : cylinder height + * rs : fillet radius or radius of the torus which is + * tangent to the cone and the cylinder. + */ +export function makeCylinderTorusCone( + csg: OCC, + r1: number, + r2: number, + H: number, + H2: number, + rs: number +) { + // ------------------------------------------------------------ + // create a cylinder capped with a cone and a round fillet + // at the intersection. + // R2| + // /----. H + // / | + // (rs) (------.- 0 ( torus) + // | | + // | . + // +------|- -H2 + // R1 + // ------------------------------------------------------------ + + /* example : r1 = 20 ,r2 = 15 , H = 5 ,H2 = 10 rs = 5 */ + + // calculate the cone half angle + const angle = Math.atan((r1 - r2) / H); + // calculate the distance below the cylinder top + // at which the torus is tangent to the cylinder + const d = -Math.tan(angle / 2) * rs; + // calculate the distance above the cone bottom + // at which the torus is tangent to the cone + const d2 = d + rs * Math.sin(angle); + // calculate the radius of the cone at the + // tangent edge with the torus. + const r1b = r1 - rs * (1.0 - Math.cos(angle)); + + const cyl = csg.makeCylinder([0, 0, -H2], [0, 0, d], r1); + const cone = csg.makeCone([0, 0, d2], r1b, [0, 0, H], r2); + const tore = csg.makeTorus([0, 0, d], [0, 0, 1], r1 - rs, rs); + + let v = csg.cut(tore, cone); + v = csg.cut(v, cyl); + + v = csg.fuse(v, cone); + v = csg.fuse(v, cyl); + return v; +} + +/** + * parameters: + * r : external radius of the lid + * height : + * H : Z position of the planar face of the lid + * + * _ ----| + * + . + * / \/ | + * +--+\ . + * \ | + * \ . + * \ | + * \ | + * \| + * + + */ +export function makeLidWithTorus( + csg: OCC, + r: number, + h: number, + rs: number, + thickness: number +) { + const r0 = r - rs; + const h0 = h - rs; + const tanAlpha = h0 / r0; + const alpha = Math.atan(tanAlpha); + + const hyp0_2 = r0 * r0 + h0 * h0; + // h0/hyp0 = (hyp0/2)/R0 + + const R0 = hyp0_2 / 2.0 / h0; + const R = R0 + rs; + + const center: Triplet = [0, 0, h0 - R0]; + + const outerSphere = csg.makeSphere(center, R); + const innerSphere = csg.makeSphere(center, R - thickness); + let solid = csg.cut(outerSphere, innerSphere); + + // lets cut the sphere + // lets cut the sphere + const hh = R / 3; + // . + // . | tan(a)=s/c => s=h*tan( + // +-----|------- + const c1: Triplet = [center[0], center[1], center[2] + hh]; + const r1 = Math.tan(2 * alpha) * hh; + const c2: Triplet = [center[0], center[1], center[2] + (R + hh)]; + const r2 = Math.tan(2 * alpha) * (R + hh); + + const cuttingcone = csg.makeCone(c1, r1, c2, r2); + solid = csg.common(solid, cuttingcone); + + solid = csg.common(solid, cuttingcone); + + const cyl = csg.makeCylinder(center, [0, 0, 0], R); + // lets add a torus + let outerfillet = csg.makeTorus([0, 0, 0], [0, 0, 1], r0, rs); + outerfillet = csg.cut(outerfillet, cuttingcone); + outerfillet = csg.cut(outerfillet, cyl); + + let fillet = outerfillet; + if (rs - thickness > 0) { + let innerfillet = csg.makeTorus([0, 0, 0], [0, 0, 1], r0, rs - thickness); + innerfillet = csg.cut(innerfillet, cuttingcone); + fillet = csg.cut(fillet, innerfillet); + } + fillet = csg.cut(fillet, cuttingcone); + return csg.fuse(solid, fillet); + //xx return csg.compound([solid,fillet]); +} + +export function makeTube( + csg: OCC, + p1: PointLike, + p2: PointLike, + R: number, + thickness: number +) { + const cyl1 = csg.makeCylinder(p1, p2, R); + const cyl2 = csg.makeCylinder(p1, p2, R - thickness); + return csg.cut(cyl1, cyl2); +} + +export function makeHollowCylinder( + csg: OCC, + R: number, + H: number, + h: number, + rf: number, + thickness: number +) { + let top = exports.makeLidWithTorus(csg, R, h, rf, thickness); + let bottom = top.clone(); + bottom = bottom.rotate([0, 0, 0], [1, 0, 0], 180); + + const cyl = exports.makeTube(csg, [0, 0, 0], [0, 0, H], R, thickness); + top = top.translate([0, 0, H]); + let solid = csg.fuse(bottom, cyl); + solid = csg.fuse(solid, top); + return solid; +} + +export function testHollowCylinder(csg: OCC) { + const obj = exports.makeHollowCylinder(csg, 40, 100, 10, 5, 1); + // create a section to verify visually the correctness of + // the construction. + const cuttingPlanes = csg.makeBox([0, 0, -100], [100, 200, 100]); + return csg.cut(obj, cuttingPlanes); +} + +export function makeLegoBrickSlow( + csg: OCC, + nX: UInteger, + nY: UInteger, + type: "thin" | "thick" +) { + let h: number; + + if (type === "thin") { + h = 2; + } else if (type === "thick") { + h = 6; + } else { + throw new Error("invalid"); + } + + const u = 1.6; // lego unit + + const outerWidth = nX * u * 5; + const outerLength = nY * u * 5; + const outerHeight = h * u; + + const outerBlock = csg.makeBox( + [0, 0, 0], + [outerWidth, outerLength, outerHeight] + ); + + const innerWidth = outerWidth - 2 * u; + const innerLength = outerLength - 2 * u; + const innerHeight = outerHeight - u; + + let innerBlock = csg.makeBox( + [0, 0, 0], + [innerWidth, innerLength, innerHeight] + ); + innerBlock = innerBlock.translate([u, u, 0]); + let hollowBlock = csg.cut(outerBlock, innerBlock); + + const pt1: Triplet = [2.5 * u, 2.5 * u, outerHeight - 3 * u]; + const pt2: Triplet = [2.5 * u, 2.5 * u, outerHeight + 3 * u]; + let h1 = csg.makeCylinder(pt1, pt2, 0.75 * u); + + const pt3: Triplet = [2.5 * u, 2.5 * u, outerHeight]; + const pt4: Triplet = [2.5 * u, 2.5 * u, outerHeight + u]; + let h2 = csg.makeCylinder(pt3, pt4, 1.5 * u); + + // installer la grille + for (let y = 0; y < nY; y++) { + let hh1 = h1.clone(); + let hh2 = h2.clone(); + for (let x = 0; x < nX; x++) { + // + hollowBlock = csg.cut(hollowBlock, hh1); + hollowBlock = csg.fuse(hollowBlock, hh2); + hh1 = hh1.translate([5 * u, 0, 0]); + hh2 = hh2.translate([5 * u, 0, 0]); + } + h1 = h1.translate([0, 5 * u, 0]); + h2 = h2.translate([0, 5 * u, 0]); + } + + const pt5: Triplet = [2.5 * u, 2.5 * u, 0]; + const pt6: Triplet = [2.5 * u, 2.5 * u, outerHeight - u]; + let pinOuter = csg.makeCylinder(pt5, pt6, u); + + const pt7: Triplet = [2.5 * u, 2.5 * u, 0]; + const pt8: Triplet = [2.5 * u, 2.5 * u, outerHeight - u]; + let pinInner = csg.makeCylinder(pt7, pt8, 0.5 * u); + + let p = csg.cut(pinOuter, pinInner); + let pp; + if (nY == 1) { + // install small pin insid + p = p.translate([2.5 * u, 0, 0]); + for (let x = 0; x < nX - 1; x++) { + hollowBlock = csg.fuse(hollowBlock, p); + p = p.translate([5 * u, 0, 0]); + } + } + if (nX == 1) { + p = p.translate([0, 2.5 * u, 0]); + for (let y = 0; y < nY - 1; y++) { + hollowBlock = csg.fuse(hollowBlock, p); + p = p.translate([0, 5 * u, 0]); + } + } + if (nX > 1 && nY > 1) { + const pt9: Triplet = [5 * u, 5 * u, 0]; + const pt10: Triplet = [5 * u, 5 * u, outerHeight - u]; + pinOuter = csg.makeCylinder(pt9, pt10, (4.07 / 2.0) * u); + + const pt11: Triplet = [5 * u, 5 * u, 0]; + const pt12: Triplet = [5 * u, 5 * u, outerHeight - u]; + pinInner = csg.makeCylinder(pt11, pt12, 1.5 * u); + + let pin = csg.cut(pinOuter, pinInner); + + for (let x = 0; x < nX - 1; x++) { + pp = pin.clone(); + for (let y = 0; y < nY - 1; y++) { + hollowBlock = csg.fuse(hollowBlock, pp); + pp = pp.translate([0, 5 * u, 0]); + } + pin = pin.translate([5 * u, 0, 0]); + } + } + return hollowBlock; +} + +function makeRepetition( + csg: OCC, + shape: T, + dX: number, + nX: number, + dY: number, + nY: number +) { + let h1 = shape.clone(); + // installer la grille + const shapeArray: T[] = []; + for (let y = 0; y < nY; y++) { + let hh1 = h1.clone(); + for (let x = 0; x < nX; x++) { + shapeArray.push(hh1); + hh1 = hh1.translate([dX, 0, 0]); + } + h1 = h1.translate([0, dY, 0]); + } + return csg.compound(shapeArray); +} + +export function makeLegoBrick( + csg: OCC, + nX: UInteger, + nY: UInteger, + type: "thin" | "thick" +) { + let h = 0; + if (type === "thin") { + h = 2; + } else if (type === "thick") { + h = 6; + } else { + throw new Error("invalid h"); + } + + const u = 1.6; // lego unit + + const outerWidth = nX * u * 5; + const outerLength = nY * u * 5; + const outerHeight = h * u; + + let brick = csg.makeBox([0, 0, 0], [outerWidth, outerLength, outerHeight]); + brick = csg.makeThickSolid(brick, brick.faces.bottom, -u); + + const pt1: Triplet = [2.5 * u, 2.5 * u, outerHeight]; + const pt2: Triplet = [2.5 * u, 2.5 * u, outerHeight + u]; + const h2 = csg.makeCylinder(pt1, pt2, 1.5 * u); + + let tetons = makeRepetition(csg, h2, 5 * u, nX, 5 * u, nY); + brick = csg.fuse(brick, tetons); + + const pt3: Triplet = [2.5 * u, 2.5 * u, outerHeight - 3 * u]; + const pt4: Triplet = [2.5 * u, 2.5 * u, outerHeight + 0.75]; + const h1 = csg.makeCylinder(pt3, pt4, 0.74 * u); + tetons = makeRepetition(csg, h1, 5 * u, nX, 5 * u, nY); + brick = csg.cut(brick, tetons); + + //xx console.log(Object.keys(brick.faces));//.bottom); + + // small pins + const pt5: Triplet = [2.5 * u, 2.5 * u, 0]; + const pt6: Triplet = [2.5 * u, 2.5 * u, outerHeight - u]; + let pinOuter = csg.makeCylinder(pt5, pt6, u); + + const pt7: Triplet = [2.5 * u, 2.5 * u, 0]; + const pt8: Triplet = [2.5 * u, 2.5 * u, outerHeight - u]; + let pinInner = csg.makeCylinder(pt7, pt8, 0.5 * u); + + let pin = csg.cut(pinOuter, pinInner); + + let p; + if (nY == 1) { + // install small pin insid + p = pin.clone(); + p = p.translate([2.5 * u, 0, 0]); + tetons = makeRepetition(csg, p, 5 * u, nX - 1, 0, 1); + brick = csg.fuse(brick, tetons); + } else if (nX == 1) { + p = pin.clone(); + p = p.translate([0, 2.5 * u, 0]); + tetons = makeRepetition(csg, p, 0, 1, 5 * u, nY - 1); + brick = csg.fuse(brick, tetons); + } else if (nX > 1 && nY > 1) { + pinOuter = csg.makeCylinder( + [5 * u, 5 * u, 0], + [5 * u, 5 * u, outerHeight - u], + (4.07 / 2.0) * u + ); + pinInner = csg.makeCylinder( + [5 * u, 5 * u, 0], + [5 * u, 5 * u, outerHeight - u], + 1.5 * u + ); + pin = csg.cut(pinOuter, pinInner); + tetons = makeRepetition(csg, pin, 5 * u, nX - 1, 5 * u, nY - 1); + brick = csg.fuse(brick, tetons); + } + + return brick; +} + +export function makePiston(occ: OCC) { + // create the top wire + // ---| + // . . + // / | + // 2+-----+ . + // | 3 | + // 1+-------------. + // |<------------w--...> + // + + const w = 65; + const r = 20; + const h = 12; + + const p0 = occ.makeVertex([0, 0, 0]); + + const p1 = p0.translate([-w / 2.0, 0, 0]); + + const p2 = p1.translate([0.0, h, 0]); + const p3 = p0.translate([-r, h, 0]); + const p4 = p0.translate([0, h + r, 0]); + + const trsf = occ.makePlaneMirror([0, 0, 0], [1, 0, 0]); + + const q1 = p1.transformed(trsf); + const q2 = p2.transformed(trsf); + const q3 = p3.transformed(trsf); + + const e1 = occ.makeLine(q1, p1); + const e2 = occ.makeLine(p1, p2); + const e3 = occ.makeLine(p2, p3); + const e4 = occ.makeArc3P(p3, p4, q3); + const e5 = occ.makeLine(q3, q2); + const e6 = occ.makeLine(q2, q1); + + const wire1 = occ.makeWire(e1, e2, e3, e4, e5, e6); + assert(6 === wire1.numEdges); + + const face1 = occ.makeFace(wire1); + + const height = 12; + return occ.makePrism(face1, [0, 0, height]); +} + +export function makeTutorialPart(occ: OCC) { + const w = 60; + const H = 50; + const h = H / 2; + const a = 7.5; + const b = 20; + + const p0: Triplet = [b, -a / 2, 0]; + const p1: Triplet = [0, -a / 2, 0]; + const p2: Triplet = [0, -h, 0]; + const p3: Triplet = [w, -h, 0]; + const p4: Triplet = [w, h, 0]; + const p5: Triplet = [0, h, 0]; + const p6: Triplet = [0, a / 2, 0]; + const p7: Triplet = [b, a / 2, 0]; + + const p8: Triplet = [b + a / 2, 0, 0]; + + const e1 = occ.makeLine(p0, p1); + const e2 = occ.makeLine(p1, p2); + const e3 = occ.makeLine(p2, p3); + const e4 = occ.makeLine(p3, p4); + const e5 = occ.makeLine(p4, p5); + const e6 = occ.makeLine(p5, p6); + const e7 = occ.makeLine(p6, p7); + const e8 = occ.makeArc3P(p7, p8, p0); + + const wire = occ.makeWire(e1, e2, e3, e4, e5, e6, e7, e8); + assert(true === wire.isClosed); + + const height = 20; + const face = occ.makeFace(wire); + const body1 = occ.makePrism(face, [0, 0, height]); + + // -------------------------------------------------- + const height2 = 45; + const circle = occ.makeCircle([w, 0, 0], [0, 0, 1], h); + const wire2 = occ.makeWire(circle); + const face2 = occ.makeFace(wire2); + const body2 = occ.makePrism(face2, [0, 0, height2]); + + // ----------------------------------------------------- + const body3 = occ.fuse(body1, body2); + + // + // ------+ + // / + // + + // ------+ + // + const R = 15; + const angle = Math.asin(7.5 / R); + const dx = R * Math.cos(angle); + const dy = R * Math.sin(angle); + + const q1: Triplet = [w + dx, dy, 0]; + const q2: Triplet = [w + dx + 100, dy, 0]; + const q3: Triplet = [w + dx + 100, -dy, 0]; + const q4: Triplet = [w + dx, -dy, 0]; + const q5: Triplet = [w - R, 0, 0]; + + const ee1 = occ.makeLine(q1, q2); + const ee2 = occ.makeLine(q2, q3); + const ee3 = occ.makeLine(q3, q4); + const ee4 = occ.makeArc3P(q4, q5, q1); + const wire4 = occ.makeWire(ee1, ee2, ee3, ee4); + const face4 = occ.makeFace(wire4); + const body4 = occ.makePrism(face4, [0, 0, height2]); + + const body5 = occ.cut(body3, body4); + const edges = body5.getEdges(); + // -------------------------------------------- + // Select vertical edges with vertex P1 and P6 + // -------------------------------------------- + function same(a: number, b: number, tol: number) { + return Math.abs(a - b) < tol; + } + + function samePoint(p1: IPoint, p2: IPoint) { + const tol = 0.001; + return ( + same(p1.x, p2.x, tol) && same(p1.y, p2.y, tol) && same(p1.z, p2.z, tol) + ); + } + + function selectEdge(edges: IEdge[], p: PointLike) { + if (p instanceof Array) { + p = occ.makeVertex(p); + } + const results = edges.filter((edge) => { + const firstVertex = edge.firstVertex; + const lastVertex = edge.lastVertex; + return ( + (samePoint(firstVertex, p as IPoint) || + samePoint(lastVertex, p as IPoint)) && + same(firstVertex.x, lastVertex.x, 0.01) && + same(firstVertex.y, lastVertex.y, 0.01) + ); + }); + return results[0]; + } + + const edges_for_filet = [selectEdge(edges, p2), selectEdge(edges, p5)]; + + const body6 = occ.makeFillet(body5, edges_for_filet, 10); + + // create hole + const smallR = 5; + const heigth3 = height2 - smallR - 10; + const cyl = occ.makeCylinder( + [w - R - 10, 0, heigth3], + [w - R + 20, 0, heigth3], + smallR + ); + + return occ.cut(body6, cyl); +} diff --git a/package-lock.json b/package-lock.json index cfb48ee..de6bc71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3923 +1,18 @@ { "name": "node-occ", "version": "1.0.1", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "node-occ", - "version": "1.0.1", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.4", - "colors": "*", - "gettemporaryfilepath": "1.0.1", - "nan": "^2.16.0", - "node-pre-gyp": "^0.15.0", - "pace": "~0.0.4", - "progress": "~2.0.3" - }, - "devDependencies": { - "@types/mocha": "^9.1.1", - "aws-sdk": "^2.1209.0", - "eslint": "^8.23.0", - "eslint-config-standard": "^17.0.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.0.1", - "eslint-plugin-require-path-exists": "^1.1.9", - "eslint-plugin-standard": "^4.1.0", - "eslint-utils": "^3.0.0", - "mocha": "^10.0.0", - "should": "~13.2.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1209.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1209.0.tgz", - "integrity": "sha512-m4Dd0HtyKeKBjwzP9rhe+NcmsRKR0wW+QXfpepu6vgXYhmcJuOB9TLUoeB7jiNDPimmwU+KxtL6eonRfeFhANw==", - "dev": true, - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.4.19" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/builtins/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/charm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", - "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-standard": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", - "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0", - "eslint-plugin-promise": "^6.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-es/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/eslint-plugin-n": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.5.tgz", - "integrity": "sha512-8+BYsqiyZfpu6NXmdLOXVUfk8IocpCjpd8nMRRH0A9ulrcemhb2VI9RSJMEy5udx++A/YcVPD11zT8hpFq368g==", - "dev": true, - "peer": true, - "dependencies": { - "builtins": "^5.0.1", - "eslint-plugin-es": "^4.1.0", - "eslint-utils": "^3.0.0", - "ignore": "^5.1.1", - "is-core-module": "^2.10.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.1", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", - "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", - "dev": true, - "peer": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "peer": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-plugin-n/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.1.tgz", - "integrity": "sha512-uM4Tgo5u3UWQiroOyDEsYcVMOo7re3zmno0IZmB5auxoaQNIceAbXEkSt8RNrKtaYehARHG06pYK6K1JhtP0Zw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-require-path-exists": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-require-path-exists/-/eslint-plugin-require-path-exists-1.1.9.tgz", - "integrity": "sha512-moZRfrPr4GFyT/W8PHzjzC7D4Hnj7Us+GYj0fbVKQoPvP4xIF8VG702L1jzyhqE8eIYkcs8p1CoqSfjk9WkxBg==", - "dev": true, - "dependencies": { - "builtin-modules": "^1.1.1", - "fs-plus": "^3.0.0", - "resolve": "^1.1.7" - } - }, - "node_modules/eslint-plugin-standard": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", - "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs-plus": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", - "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", - "dev": true, - "dependencies": { - "async": "^1.5.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2", - "underscore-plus": "1.x" - } - }, - "node_modules/fs-plus/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gettemporaryfilepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gettemporaryfilepath/-/gettemporaryfilepath-1.0.1.tgz", - "integrity": "sha512-MVCSgF1blIZuIV3KYhMKOwU1OSxPF1s+ZcyqWMSGR5Fzl6fN7EjIXDFGu9PmWAAwyGjMjmkS2ruqPaj13J3SXA==" - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dependencies": { - "minimatch": "^3.0.4" - } - }, - "node_modules/import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-cache/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/needle": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", - "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/node-pre-gyp": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", - "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", - "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", - "dependencies": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.3", - "needle": "^2.5.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/node-pre-gyp/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dependencies": { - "abbrev": "1", - "osenv": "^0.1.4" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dependencies": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" - }, - "node_modules/npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dependencies": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pace": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/pace/-/pace-0.0.4.tgz", - "integrity": "sha1-1mQF1fW8EtJUQabibIeNvGnnenc=", - "dependencies": { - "charm": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", - "dev": true - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dev": true, - "dependencies": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "node_modules/should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dev": true, - "dependencies": { - "should-type": "^1.4.0" - } - }, - "node_modules/should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "node_modules/should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", - "dev": true - }, - "node_modules/should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "node_modules/should-util": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", - "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", - "dev": true - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/tar/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", - "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==", - "dev": true - }, - "node_modules/underscore-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", - "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", - "dev": true, - "dependencies": { - "underscore": "^1.9.1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" - } - }, - "node_modules/xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "requires": { + "@jridgewell/trace-mapping": "0.3.9" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { "@eslint/eslintrc": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", @@ -3944,15 +39,6 @@ "ms": "2.1.2" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4001,6 +87,52 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@mapbox/node-pre-gyp": { + "version": "1.0.10", + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4027,6 +159,34 @@ "fastq": "^1.6.0" } }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "@types/async": { + "version": "3.2.20", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -4039,6 +199,21 @@ "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", "dev": true }, + "@types/node": { + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", + "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==", + "dev": true + }, + "@types/should": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/should/-/should-13.0.0.tgz", + "integrity": "sha512-Mi6YZ2ABnnGGFMuiBDP0a8s1ZDCDNHqP97UH8TyDmCWuGGavpsFMfJnAMYaaqmDlSCOCNbVLHBrSDEOpx/oLhw==", + "dev": true, + "requires": { + "should": "*" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -4060,8 +235,21 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } }, "ajv": { "version": "6.12.6", @@ -4082,9 +270,9 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", @@ -4106,19 +294,25 @@ } }, "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", "requires": { "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "readable-stream": "^3.6.0" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4156,11 +350,6 @@ "es-shim-unscopables": "^1.0.0" } }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -4168,9 +357,7 @@ "dev": true }, "aws-sdk": { - "version": "2.1209.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1209.0.tgz", - "integrity": "sha512-m4Dd0HtyKeKBjwzP9rhe+NcmsRKR0wW+QXfpepu6vgXYhmcJuOB9TLUoeB7jiNDPimmwU+KxtL6eonRfeFhANw==", + "version": "2.1396.0", "dev": true, "requires": { "buffer": "4.9.2", @@ -4182,7 +369,7 @@ "url": "0.10.3", "util": "^0.12.4", "uuid": "8.0.0", - "xml2js": "0.4.19" + "xml2js": "0.5.0" } }, "balanced-match": { @@ -4191,9 +378,9 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "binary-extensions": { @@ -4237,34 +424,17 @@ "isarray": "^1.0.0" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "requires": { - "semver": "^7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -4341,9 +511,9 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "cliui": { "version": "7.0.4", @@ -4390,11 +560,6 @@ } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4410,25 +575,26 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -4442,11 +608,11 @@ } }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -4455,11 +621,6 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -4479,12 +640,12 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" }, "diff": { "version": "5.0.0", @@ -4513,8 +674,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "es-abstract": { "version": "1.20.2", @@ -4641,15 +801,6 @@ "ms": "2.1.2" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4671,8 +822,7 @@ "version": "17.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", - "dev": true, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -4781,15 +931,6 @@ "esutils": "^2.0.2" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4798,75 +939,6 @@ } } }, - "eslint-plugin-n": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.5.tgz", - "integrity": "sha512-8+BYsqiyZfpu6NXmdLOXVUfk8IocpCjpd8nMRRH0A9ulrcemhb2VI9RSJMEy5udx++A/YcVPD11zT8hpFq368g==", - "dev": true, - "peer": true, - "requires": { - "builtins": "^5.0.1", - "eslint-plugin-es": "^4.1.0", - "eslint-utils": "^3.0.0", - "ignore": "^5.1.1", - "is-core-module": "^2.10.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.1", - "semver": "^7.3.7" - }, - "dependencies": { - "eslint-plugin-es": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", - "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", - "dev": true, - "peer": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "peer": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "peer": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -4908,8 +980,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.1.tgz", "integrity": "sha512-uM4Tgo5u3UWQiroOyDEsYcVMOo7re3zmno0IZmB5auxoaQNIceAbXEkSt8RNrKtaYehARHG06pYK6K1JhtP0Zw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-require-path-exists": { "version": "1.1.9", @@ -4926,8 +997,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "7.1.1", @@ -5006,7 +1076,7 @@ "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", "dev": true }, "fast-deep-equal": { @@ -5131,11 +1201,21 @@ } }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } } }, "fs-plus": { @@ -5201,18 +1281,19 @@ "dev": true }, "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", "requires": { - "aproba": "^1.0.3", + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" } }, "get-caller-file": { @@ -5222,13 +1303,14 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" } }, @@ -5292,6 +1374,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", @@ -5328,6 +1419,12 @@ "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -5346,7 +1443,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "he": { "version": "1.2.0", @@ -5354,12 +1451,13 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "agent-base": "6", + "debug": "4" } }, "ieee754": { @@ -5374,14 +1472,6 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "requires": { - "minimatch": "^3.0.4" - } - }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", @@ -5412,11 +1502,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -5473,9 +1558,9 @@ "dev": true }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", "dev": true, "requires": { "has": "^1.0.3" @@ -5497,12 +1582,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-generator-function": { "version": "1.0.10", @@ -5587,15 +1669,15 @@ } }, "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", "for-each": "^0.3.3", + "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" } }, @@ -5617,7 +1699,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -5653,9 +1736,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -5700,21 +1783,31 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, "requires": { "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" }, "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5732,9 +1825,9 @@ } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } @@ -5742,29 +1835,38 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" }, "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } } }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -5870,57 +1972,20 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "needle": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", - "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", + "node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - } - } - }, - "node-pre-gyp": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", - "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.3", - "needle": "^2.5.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - } + "whatwg-url": "^5.0.0" } }, "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1" } }, "normalize-path": { @@ -5929,49 +1994,21 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.2", @@ -6030,25 +2067,6 @@ "word-wrap": "^1.2.3" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6125,10 +2143,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true }, "progress": { "version": "2.0.3", @@ -6138,13 +2157,13 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "dev": true }, "queue-microtask": { @@ -6162,29 +2181,14 @@ "safe-buffer": "^5.1.0" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdirp": { @@ -6246,6 +2250,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, "requires": { "glob": "^7.0.5" } @@ -6262,23 +2267,22 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "requires": { + "lru-cache": "^6.0.0" + } }, "serialize-javascript": { "version": "6.0.0", @@ -6292,7 +2296,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "shebang-command": { "version": "2.0.0", @@ -6375,9 +2379,9 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "slash": { "version": "3.0.0", @@ -6385,22 +2389,26 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.21", "requires": { - "safe-buffer": "~5.1.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -6425,12 +2433,27 @@ "es-abstract": "^1.19.5" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -6439,11 +2462,6 @@ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -6460,23 +2478,22 @@ "dev": true }, "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" } } }, @@ -6495,6 +2512,40 @@ "is-number": "^7.0.0" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -6522,6 +2573,12 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6569,7 +2626,7 @@ "url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", "dev": true, "requires": { "punycode": "1.3.2", @@ -6577,23 +2634,22 @@ } }, "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", "which-typed-array": "^1.1.2" } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "uuid": { "version": "8.0.0", @@ -6601,6 +2657,26 @@ "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6624,25 +2700,25 @@ } }, "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", "for-each": "^0.3.3", + "gopd": "^1.0.1", "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "is-typed-array": "^1.1.10" } }, "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "word-wrap": { @@ -6708,19 +2784,19 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", "dev": true, "requires": { "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "xmlbuilder": "~11.0.0" } }, "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true }, "y18n": { @@ -6730,9 +2806,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yargs": { "version": "16.2.0", @@ -6801,6 +2877,12 @@ "is-plain-obj": "^2.1.0" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 66296d8..4feb5e7 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,19 @@ "description": "OpenCascade OCCT Wrapper for Node js", "preferGlobal": true, "dependencies": { - "async": "^3.2.4", - "colors": "*", "gettemporaryfilepath": "1.0.1", + "@mapbox/node-pre-gyp": "^1.0.10", "nan": "^2.16.0", - "node-pre-gyp": "^0.15.0", "pace": "~0.0.4", - "progress": "~2.0.3" + "progress": "~2.0.3", + "source-map-support": "^0.5.21" }, "devDependencies": { + "@types/async": "^3.2.20", "@types/mocha": "^9.1.1", - "aws-sdk": "^2.1209.0", + "@types/node": "^20.2.3", + "@types/should": "^13.0.0", + "aws-sdk": "^2.1396.0", "eslint": "^8.23.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", @@ -24,14 +26,18 @@ "eslint-plugin-standard": "^4.1.0", "eslint-utils": "^3.0.0", "mocha": "^10.0.0", - "should": "~13.2.3" + "prettier": "^3.0.0", + "should": "~13.2.3", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" }, - "main": "index", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "author": { "name": "Etienne Rossignon" }, "engines": { - "node": "*" + "node": ">=18" }, "keywords": [ "3D", @@ -47,17 +53,19 @@ "url": "https://github.com/openwebcad/node-occ.git" }, "scripts": { - "install": "node-pre-gyp install --fallback-to-build", - "test": "mocha -R spec", + "build": "tsc ", + "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build", + "test": "mocha test/*.ts", "lint": "eslint lib test bin", "doc": "grunt doc", + "prettier": "prettier -w lib/*.ts test/*.ts", "postinstall": "node post-install.js" }, "binary": { "module_name": "occ", "module_path": "./lib/binding/", - "host-aws": "https://nodeocc.s3-us-west-1.amazonaws.com", - "host": "https://github.com/openwebcad/node-occ/releases/download/", + "host": "https://nodeocc.s3-us-west-1.amazonaws.com", + "host__": "https://github.com/openwebcad/node-occ/releases/download/", "remote_path": "{version}" }, "gypfile": true, @@ -68,4 +76,4 @@ "test": "test" }, "license": "MIT" -} +} \ No newline at end of file diff --git a/post-install.js b/post-install.js index 1ed77cf..9efa93e 100644 --- a/post-install.js +++ b/post-install.js @@ -1,14 +1,16 @@ -const { exec }= require("child_process"); +const { exec } = require("child_process"); +console.log("platform", process.platform); if (process.platform === "linux") { const cmd = "(cd lib/binding && ls *.so.7.2.1 | sed sP^libPPg | sed sp.so.7.2.1pp | xargs -i ln -sf lib{}.so.7.2.1 lib{}.so.7)"; - - exec(cmd, (error, stdout, stderr) => { + + console.log("cmd = ", cmd); + exec(cmd, (error, stdout, stderr) => { if (error) { - console.log(error.code); + console.log("failed with err: ", error.code); } else { console.log("done"); } diff --git a/samples/sample1.ts b/samples/sample1.ts new file mode 100644 index 0000000..367f284 --- /dev/null +++ b/samples/sample1.ts @@ -0,0 +1,5 @@ +import { occ } from ".."; + + +const shapeBox = occ.makeBox([1, 2, 3], [20, 30, 40]) +const translatedShapeBox = shapeBox.translate(0, 0, 10); diff --git a/src/AsyncWorkerWithProgress.h b/src/AsyncWorkerWithProgress.h index 99467d7..74c56c3 100644 --- a/src/AsyncWorkerWithProgress.h +++ b/src/AsyncWorkerWithProgress.h @@ -9,91 +9,81 @@ struct ProgressData { }; inline ProgressData::ProgressData() -:m_lastValue(0) -,m_percent(0) -,m_progress(0) -{} + : m_lastValue(0), m_percent(0), m_progress(0) {} class AsyncWorkerWithProgress : public Nan::AsyncWorker { - Nan::Callback* _progressCallback; + Nan::Callback *_progressCallback; uv_async_t async; + protected: std::string _filename; + public: ProgressData m_data; public: - AsyncWorkerWithProgress( - Nan::Callback *callback, - Nan::Callback* progressCallback, - std::string* pfilename - ) - : Nan::AsyncWorker(callback) , _progressCallback(progressCallback) - { - _filename = *pfilename; + AsyncWorkerWithProgress(Nan::Callback *callback, + Nan::Callback *progressCallback, + std::string *pfilename) + : Nan::AsyncWorker(callback), _progressCallback(progressCallback) { + _filename = *pfilename; delete pfilename; async.data = this; uv_async_init(Nan::GetCurrentEventLoop(), &async, AsyncProgress_); - } - inline static void AsyncClose_(uv_handle_t* handle) { - AsyncWorkerWithProgress* worker = static_cast(handle->data); + inline static void AsyncClose_(uv_handle_t *handle) { + AsyncWorkerWithProgress *worker = + static_cast(handle->data); delete worker; handle->data = nullptr; } virtual void Destroy() { - uv_close(reinterpret_cast(&async), AsyncClose_); + uv_close(reinterpret_cast(&async), AsyncClose_); } ~AsyncWorkerWithProgress() { if (_progressCallback) { delete _progressCallback; } - } - - - /** - * Method wich is called in the context of a working thread - */ - void Execute () =0; + * Method wich is called in the context of a working thread + */ + void Execute() = 0; /** - * send a message to the main loop so that a progress callback can be made - * in the thread of the main loop. - * this is equivalent of asking uv to call notify_progress in the context of the - * main loop in the near future. - */ - void send_notify_progress() { - uv_async_send(&this->async); - }; - + * send a message to the main loop so that a progress callback can be made + * in the thread of the main loop. + * this is equivalent of asking uv to call notify_progress in the context of + * the main loop in the near future. + */ + void send_notify_progress() { uv_async_send(&this->async); }; static NAUV_WORK_CB(AsyncProgress_) { - AsyncWorkerWithProgress *worker = static_cast(async->data); + AsyncWorkerWithProgress *worker = + static_cast(async->data); worker->notify_progress1(); } /** - * - * Note: - * - this method is called in the main loop thread. - * - there is no garanty that this method will be called for each send_notify_progress - */ + * + * Note: + * - this method is called in the main loop thread. + * - there is no garanty that this method will be called for each + * send_notify_progress + */ void notify_progress1() { - + Nan::HandleScope scope; if (_progressCallback && !_progressCallback->IsEmpty()) { v8::Local argv[2] = { - Nan::New(this->m_data.m_progress), - Nan::New((int)this->m_data.m_percent) - }; - _progressCallback->Call(2,argv, async_resource); + Nan::New(this->m_data.m_progress), + Nan::New((int)this->m_data.m_percent)}; + _progressCallback->Call(2, argv, async_resource); } } }; \ No newline at end of file diff --git a/src/Base.cc b/src/Base.cc index 53b9ffb..d6575cd 100644 --- a/src/Base.cc +++ b/src/Base.cc @@ -1,20 +1,13 @@ #include "Base.h" -#include "Util.h" #include "BoundingBox.h" #include "Transformation.h" +#include "Util.h" +Base::~Base() {} -Base::~Base() -{ -} - -bool Base::isNull() -{ - return shape().IsNull() ? true : false; -} +bool Base::isNull() { return shape().IsNull() ? true : false; } -bool Base::isValid() -{ +bool Base::isValid() { if (isNull()) { return false; } @@ -22,51 +15,42 @@ bool Base::isValid() return aChecker.IsValid() ? true : false; } -const char* Base::shapeType() -{ +const char *Base::shapeType() { if (isNull()) { return "UNDEFINED"; } - switch(shape().ShapeType()) { - case TopAbs_COMPOUND: + switch (shape().ShapeType()) { + case TopAbs_COMPOUND: return "COMPOUND"; break; - case TopAbs_COMPSOLID: + case TopAbs_COMPSOLID: return "COMPSOLID"; break; - case TopAbs_SOLID: + case TopAbs_SOLID: return "SOLID"; - break; - case TopAbs_SHELL: + case TopAbs_SHELL: return "SHELL"; - break; - case TopAbs_FACE: + case TopAbs_FACE: return "FACE"; - break; - case TopAbs_WIRE: + case TopAbs_WIRE: return "WIRE"; - break; - case TopAbs_EDGE: + case TopAbs_EDGE: return "EDGE"; - break; - case TopAbs_VERTEX: + case TopAbs_VERTEX: return "VERTEX"; - break; - case TopAbs_SHAPE: + case TopAbs_SHAPE: return "SHAPE"; - break; } - assert(0=="invalid case"); + assert(0 == "invalid case"); return "???"; } -const char* Base::orientation() -{ +const char *Base::orientation() { if (isNull()) { return "UNDEFINED"; } TopAbs_Orientation value = shape().Orientation(); - switch(value) { + switch (value) { case TopAbs_FORWARD: return "FORWARD"; break; @@ -83,185 +67,185 @@ const char* Base::orientation() return "???"; } -NAN_METHOD(Base::translate) -{ - +NAN_METHOD(Base::translate) { CHECK_THIS_DEFINED(Base); - const Base* pThis = ObjectWrap::Unwrap(info.This()); + const Base *pThis = ObjectWrap::Unwrap(info.This()); try { gp_Trsf transformation; - double x=0,y=0,z=0; - if (info.Length() == 3) { - ReadDouble(info[0], x); - ReadDouble(info[1], y); - ReadDouble(info[2], z); - } - else if (info.Length() == 1) { - ReadPoint(info[0], &x, &y, &z); - } - else { - return Nan::ThrowError("Wrong Arguments"); - } - transformation.SetTranslation(gp_Vec(x,y,z)); + double x = 0, y = 0, z = 0; + if (info.Length() == 3) { + ReadDouble(info[0], x); + ReadDouble(info[1], y); + ReadDouble(info[2], z); + } else if (info.Length() == 1) { + ReadPoint(info[0], &x, &y, &z); + } else { + return Nan::ThrowError("Wrong Arguments"); + } + transformation.SetTranslation(gp_Vec(x, y, z)); - v8::Local copy = pThis->Clone(); + v8::Local copy = pThis->Clone(); - pThis->Unwrap(copy)->setShape(BRepBuilderAPI_Transform(pThis->shape(), transformation,Standard_True).Shape()); + pThis->Unwrap(copy)->setShape( + BRepBuilderAPI_Transform(pThis->shape(), transformation, Standard_True) + .Shape()); return info.GetReturnValue().Set(copy); - - } CATCH_AND_RETHROW("Failed to calculate a translated shape "); - + } + CATCH_AND_RETHROW("Failed to calculate a translated shape "); } -NAN_METHOD(Base::rotate) -{ +NAN_METHOD(Base::rotate) { CHECK_THIS_DEFINED(Base); - const Base* pThis = ObjectWrap::Unwrap(info.This()); + const Base *pThis = ObjectWrap::Unwrap(info.This()); try { - gp_Trsf transformation; + gp_Trsf transformation; - ReadRotationFromArgs(info,transformation); + ReadRotationFromArgs(info, transformation); - v8::Local copy = pThis->Clone(); - pThis->Unwrap(copy)->setShape(BRepBuilderAPI_Transform(pThis->shape(), transformation,Standard_True).Shape()); + v8::Local copy = pThis->Clone(); + pThis->Unwrap(copy)->setShape( + BRepBuilderAPI_Transform(pThis->shape(), transformation, Standard_True) + .Shape()); return info.GetReturnValue().Set(copy); - - } CATCH_AND_RETHROW("Failed to calculate a rotated shape "); - + } + CATCH_AND_RETHROW("Failed to calculate a rotated shape "); } -NAN_METHOD(Base::mirror) -{ +NAN_METHOD(Base::mirror) { CHECK_THIS_DEFINED(Base); - const Base* pThis = ObjectWrap::Unwrap(info.This()); - // TODO - v8::Local copy = pThis->Clone(); + const Base *pThis = ObjectWrap::Unwrap(info.This()); + // TODO + v8::Local copy = pThis->Clone(); info.GetReturnValue().Set(copy); } -NAN_METHOD(Base::applyTransform) -{ +NAN_METHOD(Base::applyTransform) { CHECK_THIS_DEFINED(Base); - Base* pThis = ObjectWrap::Unwrap(info.This()); + Base *pThis = ObjectWrap::Unwrap(info.This()); - if (info.Length()!=1 && !IsInstanceOf(info[0]) ) { + if (info.Length() != 1 && !IsInstanceOf(info[0])) { return Nan::ThrowError("invalid transformation"); } try { - Transformation* pTrans = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + Transformation *pTrans = ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); - const gp_Trsf& transformation = pTrans->m_trsf; - pThis->setShape(BRepBuilderAPI_Transform(pThis->shape(), transformation).Shape()); - - info.GetReturnValue().Set(info.This()); - - } CATCH_AND_RETHROW("Failed to calculate a transformed shape "); + const gp_Trsf &transformation = pTrans->m_trsf; + pThis->setShape( + BRepBuilderAPI_Transform(pThis->shape(), transformation).Shape()); + info.GetReturnValue().Set(info.This()); + } + CATCH_AND_RETHROW("Failed to calculate a transformed shape "); } - -NAN_METHOD(Base::transformed) -{ +NAN_METHOD(Base::transformed) { CHECK_THIS_DEFINED(Base); - Base* pThis = Nan::ObjectWrap::Unwrap(info.This()); + Base *pThis = Nan::ObjectWrap::Unwrap(info.This()); - if (info.Length()!=1) { + if (info.Length() != 1) { return Nan::ThrowError("Wrong arguments"); } - Transformation* pTrans = DynamicCast(info[0]); + Transformation *pTrans = DynamicCast(info[0]); if (!pTrans) { return Nan::ThrowError("transform expects a Transformation object"); } try { - const gp_Trsf& trsf = pTrans->m_trsf; - gp_Trsf transformation = trsf; + const gp_Trsf &trsf = pTrans->m_trsf; + gp_Trsf transformation = trsf; - v8::Local copy = pThis->Clone(); + v8::Local copy = pThis->Clone(); if (!pThis->shape().IsNull()) { - pThis->Unwrap(copy)->setShape( - BRepBuilderAPI_Transform(pThis->shape(), - transformation,Standard_True).Shape()); + pThis->Unwrap(copy)->setShape(BRepBuilderAPI_Transform(pThis->shape(), + transformation, + Standard_True) + .Shape()); } - info.GetReturnValue().Set(copy); - } CATCH_AND_RETHROW("Failed to calculate a transformed shape "); - + info.GetReturnValue().Set(copy); + } + CATCH_AND_RETHROW("Failed to calculate a transformed shape "); } - -//void Shape::ApplyWorkplane(Handle json) { +// void Shape::ApplyWorkplane(Handle json) { // -// Local workplane = json->Get(String::New("workplane"))->ToObject(); +// Local workplane = json->Get(String::New("workplane"))->ToObject(); // -// if (!workplane->IsNull()) { +// if (!workplane->IsNull()) { // // -// Local workplane_origin = workplane->Get(String::New("origin"))->ToObject(); +// Local workplane_origin = +// workplane->Get(String::New("origin"))->ToObject(); // -// double x = ReadDouble(workplane_origin,"x"); -// double y = ReadDouble(workplane_origin,"y"); -// double z = ReadDouble(workplane_origin,"z"); +// double x = ReadDouble(workplane_origin,"x"); +// double y = ReadDouble(workplane_origin,"y"); +// double z = ReadDouble(workplane_origin,"z"); // -// Local workplane_axis = workplane->Get(String::New("axis"))->ToObject(); +// Local workplane_axis = +// workplane->Get(String::New("axis"))->ToObject(); // -// double u = ReadDouble(workplane_axis,"x"); -// double v = ReadDouble(workplane_axis,"y"); -// double w = ReadDouble(workplane_axis,"z"); +// double u = ReadDouble(workplane_axis,"x"); +// double v = ReadDouble(workplane_axis,"y"); +// double w = ReadDouble(workplane_axis,"z"); // -// double angle = ReadDouble(workplane,"angle"); +// double angle = ReadDouble(workplane,"angle"); // -// gp_Trsf transformation1 = gp_Trsf(); -// transformation1.SetRotation(gp_Ax1(gp_Pnt(0.0,0.0,0.0), gp_Dir(u,v,w)), angle/180*M_PI); -// shape_ = BRepBuilderAPI_Transform(shape_, transformation1).Shape(); +// gp_Trsf transformation1 = gp_Trsf(); +// transformation1.SetRotation(gp_Ax1(gp_Pnt(0.0,0.0,0.0), +// gp_Dir(u,v,w)), angle/180*M_PI); shape_ = +// BRepBuilderAPI_Transform(shape_, transformation1).Shape(); // -// gp_Trsf transformation2 = gp_Trsf(); -// transformation2.SetTranslation(gp_Vec(x,y,z)); -// shape_ = BRepBuilderAPI_Transform(shape_, transformation2).Shape(); -// } -//} +// gp_Trsf transformation2 = gp_Trsf(); +// transformation2.SetTranslation(gp_Vec(x,y,z)); +// shape_ = BRepBuilderAPI_Transform(shape_, transformation2).Shape(); +// } +// } // -//void Shape::ApplyReverseWorkplane(Handle json) { +// void Shape::ApplyReverseWorkplane(Handle json) { // -// Local workplane = json->Get(String::New("workplane"))->ToObject();; -// if (!workplane->IsNull()) { +// Local workplane = +// json->Get(String::New("workplane"))->ToObject();; if +// (!workplane->IsNull()) { // -// Local workplane_origin = workplane->Get(String::New("origin"))->ToObject();; +// Local workplane_origin = +// workplane->Get(String::New("origin"))->ToObject();; // -// double x = ReadDouble(workplane_origin,"x"); -// double y = ReadDouble(workplane_origin,"y"); -// double z = ReadDouble(workplane_origin,"z"); +// double x = ReadDouble(workplane_origin,"x"); +// double y = ReadDouble(workplane_origin,"y"); +// double z = ReadDouble(workplane_origin,"z"); // -// Local workplane_axis = workplane->Get(String::New("axis"))->ToObject();; +// Local workplane_axis = +// workplane->Get(String::New("axis"))->ToObject();; // -// double u = ReadDouble(workplane_axis,"x"); -// double v = ReadDouble(workplane_axis,"y"); -// double w = ReadDouble(workplane_axis,"z"); +// double u = ReadDouble(workplane_axis,"x"); +// double v = ReadDouble(workplane_axis,"y"); +// double w = ReadDouble(workplane_axis,"z"); // -// double angle = ReadDouble(workplane,"angle"); +// double angle = ReadDouble(workplane,"angle"); // -// gp_Trsf transformation1 = gp_Trsf(); -// transformation1.SetTranslation(gp_Vec(x,y,z)); -// shape_ = BRepBuilderAPI_Transform(shape_, transformation1).Shape(); +// gp_Trsf transformation1 = gp_Trsf(); +// transformation1.SetTranslation(gp_Vec(x,y,z)); +// shape_ = BRepBuilderAPI_Transform(shape_, transformation1).Shape(); // -// gp_Trsf transformation2 = gp_Trsf(); -// transformation2.SetRotation(gp_Ax1(gp_Pnt(0.0,0.0,0.0), gp_Dir(u,v,w)), angle/180*M_PI); -// shape_ = BRepBuilderAPI_Transform(shape_, transformation2).Shape(); +// gp_Trsf transformation2 = gp_Trsf(); +// transformation2.SetRotation(gp_Ax1(gp_Pnt(0.0,0.0,0.0), +// gp_Dir(u,v,w)), angle/180*M_PI); shape_ = +// BRepBuilderAPI_Transform(shape_, transformation2).Shape(); // -// } -//} -bool Base::fixShape() -{ +// } +// } +bool Base::fixShape() { if (this->shape().IsNull()) { return false; @@ -269,7 +253,8 @@ bool Base::fixShape() BRepCheck_Analyzer aChecker(this->shape()); if (!aChecker.IsValid()) { ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(this->shape(),Precision::Confusion(),Precision::Confusion()); + aSFT.LimitTolerance(this->shape(), Precision::Confusion(), + Precision::Confusion()); occHandle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(this->shape()); aSfs->SetPrecision(Precision::Confusion()); @@ -282,14 +267,12 @@ bool Base::fixShape() } } return aChecker.IsValid() ? true : false; - } -NAN_METHOD(Base::fixShape) -{ +NAN_METHOD(Base::fixShape) { CHECK_THIS_DEFINED(Base); - Base* pThis = Nan::ObjectWrap::Unwrap(info.This()); - if (info.Length()!=0) { + Base *pThis = Nan::ObjectWrap::Unwrap(info.This()); + if (info.Length() != 0) { return Nan::ThrowError("Wrong arguments"); } @@ -298,65 +281,58 @@ NAN_METHOD(Base::fixShape) info.GetReturnValue().Set(info.This()); } -NAN_METHOD(Base::getBoundingBox) -{ +NAN_METHOD(Base::getBoundingBox) { CHECK_THIS_DEFINED(Base); - Base* pThis = Nan::ObjectWrap::Unwrap(info.This()); - if (info.Length()!=0) { + Base *pThis = Nan::ObjectWrap::Unwrap(info.This()); + if (info.Length() != 0) { return Nan::ThrowError("Wrong arguments"); } try { - const double tolerance= 1E-12; - const TopoDS_Shape& shape = pThis->shape(); + const double tolerance = 1E-12; + const TopoDS_Shape &shape = pThis->shape(); Bnd_Box aBox; BRepBndLib::Add(shape, aBox); aBox.SetGap(tolerance); - info.GetReturnValue().Set(BoundingBox::NewInstance(aBox)); - - } CATCH_AND_RETHROW("Failed to compute bounding box "); - + info.GetReturnValue().Set(BoundingBox::NewInstance(aBox)); + } + CATCH_AND_RETHROW("Failed to compute bounding box "); } -NAN_METHOD(Base::clone) -{ +NAN_METHOD(Base::clone) { CHECK_THIS_DEFINED(Base); - Base* pThis = Nan::ObjectWrap::Unwrap(info.This()); + Base *pThis = Nan::ObjectWrap::Unwrap(info.This()); - if (info.Length()!=0) { + if (info.Length() != 0) { return Nan::ThrowError("Wrong arguments"); } info.GetReturnValue().Set(pThis->Clone()); } -void Base::InitNew(_NAN_METHOD_ARGS) -{ - REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base,shapeType); - REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base,orientation); +void Base::InitNew(_NAN_METHOD_ARGS) { + REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base, shapeType); + REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base, orientation); } -void Base::InitProto(v8::Local& proto) -{ - EXPOSE_METHOD(Base,clone); - EXPOSE_METHOD(Base,translate); - EXPOSE_METHOD(Base,rotate); - EXPOSE_METHOD(Base,mirror); - - EXPOSE_METHOD(Base,transformed); - EXPOSE_METHOD(Base,applyTransform); - EXPOSE_METHOD(Base,getBoundingBox); - - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Base,isNull); - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Base,isValid); - EXPOSE_READ_ONLY_PROPERTY_INTEGER(Base,hashCode); - EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base,shapeType); - EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base,orientation); - +void Base::InitProto(v8::Local &proto) { + EXPOSE_METHOD(Base, clone); + EXPOSE_METHOD(Base, translate); + EXPOSE_METHOD(Base, rotate); + EXPOSE_METHOD(Base, mirror); + + EXPOSE_METHOD(Base, transformed); + EXPOSE_METHOD(Base, applyTransform); + EXPOSE_METHOD(Base, getBoundingBox); + + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Base, isNull); + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Base, isValid); + EXPOSE_READ_ONLY_PROPERTY_INTEGER(Base, hashCode); + EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base, shapeType); + EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(Base, orientation); } -int Base::hashCode() -{ +int Base::hashCode() { return shape().HashCode(std::numeric_limits::max()); } diff --git a/src/Base.h b/src/Base.h index e1c9923..36f4086 100644 --- a/src/Base.h +++ b/src/Base.h @@ -4,20 +4,20 @@ #include "Util.h" #include "vector" - class Base : public Nan::ObjectWrap { public: int hashCode(); bool isNull(); bool isValid(); - const char* shapeType(); - const char* orientation(); + const char *shapeType(); + const char *orientation(); bool fixShape(); - virtual const TopoDS_Shape& shape() const = 0; - virtual void setShape(const TopoDS_Shape&) = 0; - virtual v8::Local Clone() const = 0; - virtual Base* Unwrap(v8::Local obj) const = 0;// { return node::ObjectWrap::Unwrap(obj); } + virtual const TopoDS_Shape &shape() const = 0; + virtual void setShape(const TopoDS_Shape &) = 0; + virtual v8::Local Clone() const = 0; + virtual Base *Unwrap(v8::Local obj) + const = 0; // { return node::ObjectWrap::Unwrap(obj); } virtual ~Base(); @@ -35,35 +35,36 @@ class Base : public Nan::ObjectWrap { static NAN_METHOD(clone); static NAN_METHOD(getBoundingBox); - static void InitProto(v8::Local& target); + static void InitProto(v8::Local &target); }; v8::Local buildEmptyWrapper(TopAbs_ShapeEnum type); v8::Local buildWrapper(const TopoDS_Shape shape); - -template -size_t extractArgumentList(_NAN_METHOD_ARGS, std::vector& elements) -{ +template +size_t extractArgumentList(_NAN_METHOD_ARGS, + std::vector &elements) { elements.reserve(elements.size() + info.Length()); for (int i = 0; i < info.Length(); i++) { if (IsInstanceOf(info[i])) { auto o = Nan::To(info[i]).ToLocalChecked(); - + elements.push_back(Nan::ObjectWrap::Unwrap(o)); } } return elements.size(); } -template -bool extractArg(const v8::Local& value, ClassType*& pObj) -{ +template +bool extractArg(v8::Local value, ClassType *&pObj) { + assert(pObj == 0); - if (value.IsEmpty()) return false; - if (!value->IsObject()) return false; + if (value.IsEmpty()) + return false; + if (!value->IsObject()) + return false; auto lo = Nan::To(value).ToLocalChecked(); if (IsInstanceOf(lo)) { @@ -73,27 +74,27 @@ bool extractArg(const v8::Local& value, ClassType*& pObj) return false; } +template +bool _extractArray(v8::Local value, + std::vector &elements) { -template -bool _extractArray(const v8::Local& value, std::vector& elements) -{ if (value->IsArray()) { v8::Local arr = v8::Local::Cast(value); int length = arr->Length(); elements.reserve(elements.size() + length); for (int i = 0; i < length; i++) { - auto elementI = Nan::Get(arr,i).ToLocalChecked(); + auto elementI = Nan::Get(arr, i).ToLocalChecked(); if (!elementI->IsObject()) { return false; // element is not an object } - v8::Local obj = Nan::To(elementI).ToLocalChecked(); + v8::Local obj = + Nan::To(elementI).ToLocalChecked(); if (IsInstanceOf(obj)) { elements.push_back(Nan::ObjectWrap::Unwrap(obj)); } } - } - else if (value->IsObject()) { + } else if (value->IsObject()) { // a single element v8::Local obj = Nan::To(value).ToLocalChecked(); if (IsInstanceOf(obj)) { @@ -102,9 +103,3 @@ bool _extractArray(const v8::Local& value, std::vector& e } return elements.size() >= 1; } - - - - - - diff --git a/src/BooleanOperation.cc b/src/BooleanOperation.cc index 0cc5c1e..9b499d7 100644 --- a/src/BooleanOperation.cc +++ b/src/BooleanOperation.cc @@ -1,54 +1,48 @@ #include "BooleanOperation.h" -BooleanOperation::BooleanOperation() - :m_bop(0) -{ -} -BooleanOperation::~BooleanOperation() -{ - delete m_bop; -} +BooleanOperation::BooleanOperation() : m_bop(0) {} +BooleanOperation::~BooleanOperation() { delete m_bop; } Nan::Persistent BooleanOperation::_template; - -v8::Local BooleanOperation::NewInstance(BOPAlgo_Operation op) -{ - +v8::Local BooleanOperation::NewInstance(BOPAlgo_Operation op) { v8::Local instance = makeInstance(_template); - BooleanOperation* pThis = ObjectWrap::Unwrap(instance); + BooleanOperation *pThis = ObjectWrap::Unwrap(instance); return instance; } - -inline bool _isEqual(v8::Local a,const std::string txt) { +inline bool _isEqual(v8::Local a, const std::string txt) { return txt == *Nan::Utf8String(a); } -BOPAlgo_Operation ReadOperationType(const v8::Local& arg) -{ - +BOPAlgo_Operation ReadOperationType(v8::Local arg) { v8::Local str = Nan::To(arg).ToLocalChecked(); - if (_isEqual(str,"SECTION")) return BOPAlgo_SECTION; - if (_isEqual(str,"COMMON")) return BOPAlgo_COMMON; - if (_isEqual(str,"FUSE")) return BOPAlgo_FUSE; - if (_isEqual(str,"CUT")) return BOPAlgo_CUT; - if (_isEqual(str,"CUT21")) return BOPAlgo_CUT21; + if (_isEqual(str, "SECTION")) + return BOPAlgo_SECTION; + if (_isEqual(str, "COMMON")) + return BOPAlgo_COMMON; + if (_isEqual(str, "FUSE")) + return BOPAlgo_FUSE; + if (_isEqual(str, "CUT")) + return BOPAlgo_CUT; + if (_isEqual(str, "CUT21")) + return BOPAlgo_CUT21; return BOPAlgo_UNKNOWN; } -NAN_METHOD(BooleanOperation::New) -{ +NAN_METHOD(BooleanOperation::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.BooleanOperation() to construct a BooleanOperation"); + return Nan::ThrowError( + " use new occ.BooleanOperation() to construct a BooleanOperation"); } - BooleanOperation* pThis = new BooleanOperation(); + BooleanOperation *pThis = new BooleanOperation(); pThis->Wrap(info.This()); BOPAlgo_Operation op = ReadOperationType(info[0]); if (op == BOPAlgo_UNKNOWN) { - return Nan::ThrowError("bad operation type, must be SECTION COMMON FUSE CUT or CUT21"); + return Nan::ThrowError( + "bad operation type, must be SECTION COMMON FUSE CUT or CUT21"); } info.GetReturnValue().Set(info.This()); @@ -75,28 +69,26 @@ Handle BooleanOperation_getSameShape2(const v8::Arguments& args) } */ -void BooleanOperation::Init(v8::Local target) -{ - +NAN_MODULE_INIT(BooleanOperation::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(BooleanOperation::New); + v8::Local tpl = Nan::New(New); tpl->SetClassName(Nan::New("BooleanOperation").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); - - _template.Reset(tpl); + _template.Reset(tpl); // Prototype - //xx Local proto = constructor->PrototypeTemplate(); + // xx Local proto = constructor->PrototypeTemplate(); // xx Base::InitProto(proto); - //xx EXPOSE_READ_ONLY_PROPERTY_INTEGER(Face,numWires); - //xx EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face,area); - //XX EXPOSE_METHOD(BooleanOperation,getSameShape1); - //XX EXPOSE_METHOD(BooleanOperation,getSameShape2); - //XX EXPOSE_READ_ONLY_PROPERTY(BooleanOperation,_shape1,shape1); - //XX EXPOSE_READ_ONLY_PROPERTY(BooleanOperation,_shape2,shape2); - - Nan::Set(target, Nan::New("BooleanOperation").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + // xx EXPOSE_READ_ONLY_PROPERTY_INTEGER(Face,numWires); + // xx EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face,area); + // XX EXPOSE_METHOD(BooleanOperation,getSameShape1); + // XX EXPOSE_METHOD(BooleanOperation,getSameShape2); + // XX EXPOSE_READ_ONLY_PROPERTY(BooleanOperation,_shape1,shape1); + // XX EXPOSE_READ_ONLY_PROPERTY(BooleanOperation,_shape2,shape2); + + Nan::Set(target, Nan::New("BooleanOperation").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } diff --git a/src/BooleanOperation.h b/src/BooleanOperation.h index 9a76ddb..0145b21 100644 --- a/src/BooleanOperation.h +++ b/src/BooleanOperation.h @@ -1,22 +1,21 @@ #pragma once -#include "Shape.h" #include "Point3Wrap.h" +#include "Shape.h" #include - - class BooleanOperation : public Nan::ObjectWrap { - BRepAlgoAPI_BooleanOperation* m_bop; - BooleanOperation(); - ~BooleanOperation(); + BRepAlgoAPI_BooleanOperation *m_bop; + BooleanOperation(); + ~BooleanOperation(); + public: - typedef class BooleanOperation _ThisType; + typedef class BooleanOperation _ThisType; - static Nan::Persistent _template; - static v8::Local NewInstance(BOPAlgo_Operation op); + static Nan::Persistent _template; + static v8::Local NewInstance(BOPAlgo_Operation op); - static NAN_METHOD(New); - static void Init(v8::Local target); + static NAN_METHOD(New); + static NAN_MODULE_INIT(Init); }; diff --git a/src/BoundingBox.cc b/src/BoundingBox.cc index c9ca681..1953a3d 100644 --- a/src/BoundingBox.cc +++ b/src/BoundingBox.cc @@ -5,106 +5,92 @@ Nan::Persistent BoundingBox::_template; - -v8::Local BoundingBox::NewInstance(const Bnd_Box& box) -{ - +v8::Local BoundingBox::NewInstance(const Bnd_Box &box) { v8::Local instance = makeInstance(_template); - - BoundingBox* pThis = ObjectWrap::Unwrap(instance); - + BoundingBox *pThis = ObjectWrap::Unwrap(instance); pThis->m_box = box; - return instance; } -v8::Local BoundingBox::NewInstance(const gp_Pnt& nearPt,const gp_Pnt& farPt) -{ +v8::Local BoundingBox::NewInstance(const gp_Pnt &nearPt, + const gp_Pnt &farPt) { Bnd_Box box; box.Add(nearPt); box.Add(farPt); return NewInstance(box); } -void BoundingBox::Update(BoundingBox* pThis,_NAN_METHOD_ARGS) -{ +void BoundingBox::Update(BoundingBox *pThis, _NAN_METHOD_ARGS) { // info could be one or several points // or a array of point - for (int i=0; iIsArray()) { v8::Local arr = v8::Local::Cast(info[i]); - v8::Local element0 = Nan::Get(arr,0).ToLocalChecked(); - - if ( element0->IsArray() || element0->IsObject()) { + v8::Local element0 = Nan::Get(arr, 0).ToLocalChecked(); + + if (element0->IsArray() || element0->IsObject()) { // probably an array of point } else { // a single point gp_Pnt point; - ReadPoint(info[i],&point); - pThis->m_box.Update(point.X(),point.Y(),point.Z()); + ReadPoint(info[i], &point); + pThis->m_box.Update(point.X(), point.Y(), point.Z()); } } } } - -NAN_METHOD(BoundingBox::New) -{ +NAN_METHOD(BoundingBox::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.BoundingBox() to construct a BoundingBox"); + return Nan::ThrowError( + " use new occ.BoundingBox() to construct a BoundingBox"); } - BoundingBox* pThis = new BoundingBox(); + BoundingBox *pThis = new BoundingBox(); pThis->Wrap(info.This()); - BoundingBox::Update(pThis,info); + BoundingBox::Update(pThis, info); pThis->InitNew(info); info.GetReturnValue().Set(info.This()); - } -NAN_METHOD(BoundingBox::addPoint) -{ - - BoundingBox* pThis = ObjectWrap::Unwrap(info.This()); - BoundingBox::Update(pThis,info); - +NAN_METHOD(BoundingBox::addPoint) { + BoundingBox *pThis = ObjectWrap::Unwrap(info.This()); + BoundingBox::Update(pThis, info); info.GetReturnValue().Set(info.This()); } -bool checkCoerceToPoint(const v8::Local& v) -{ +bool checkCoerceToPoint(v8::Local v) { + Nan::HandleScope scope; // TODO ... return true; } -NAN_METHOD(BoundingBox::isOut) -{ +NAN_METHOD(BoundingBox::isOut) { - BoundingBox* pThis = ObjectWrap::Unwrap(info.This()); + BoundingBox *pThis = ObjectWrap::Unwrap(info.This()); bool _itOut = false; if (info.Length() != 1 || !checkCoerceToPoint(info[0])) { return Nan::ThrowError(" error expecting a point or a arrya of 3 doubles"); } gp_Pnt point; - ReadPoint(info[0],&point); + ReadPoint(info[0], &point); bool retVal = pThis->m_box.IsOut(point) ? true : false; info.GetReturnValue().Set(Nan::New(retVal)); } - -void BoundingBox::Init(v8::Local target) -{ +NAN_MODULE_INIT(BoundingBox::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(BoundingBox::New); + v8::Local tpl = + Nan::New(BoundingBox::New); tpl->SetClassName(Nan::New("BoundingBox").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -112,19 +98,19 @@ void BoundingBox::Init(v8::Local target) // Prototype v8::Local proto = tpl->PrototypeTemplate(); - EXPOSE_METHOD(BoundingBox,addPoint); - EXPOSE_METHOD(BoundingBox,isOut); + EXPOSE_METHOD(BoundingBox, addPoint); + EXPOSE_METHOD(BoundingBox, isOut); - EXPOSE_TEAROFF(BoundingBox,nearPt); - EXPOSE_TEAROFF(BoundingBox,farPt); - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(BoundingBox,isVoid); + EXPOSE_TEAROFF(BoundingBox, nearPt); + EXPOSE_TEAROFF(BoundingBox, farPt); + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(BoundingBox, isVoid); - Nan::Set(target, Nan::New("BoundingBox").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("BoundingBox").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } -void BoundingBox::InitNew(_NAN_METHOD_ARGS) -{ - //xx Base::InitNew(info); - REXPOSE_TEAROFF(BoundingBox,nearPt); - REXPOSE_TEAROFF(BoundingBox,farPt); +void BoundingBox::InitNew(_NAN_METHOD_ARGS) { + // xx Base::InitNew(info); + REXPOSE_TEAROFF(BoundingBox, nearPt); + REXPOSE_TEAROFF(BoundingBox, farPt); } \ No newline at end of file diff --git a/src/BoundingBox.h b/src/BoundingBox.h index 4dfef90..6ec10d4 100644 --- a/src/BoundingBox.h +++ b/src/BoundingBox.h @@ -1,62 +1,60 @@ #pragma once -#include "Shape.h" #include "Point3Wrap.h" +#include "Shape.h" #include const double qNaN = std::numeric_limits::quiet_NaN(); class BoundingBox : public Nan::ObjectWrap { - Bnd_Box m_box; -public: - typedef class BoundingBox _ThisType; + Bnd_Box m_box; - BoundingBox() - {} +public: + typedef class BoundingBox _ThisType; - const gp_XYZ nearPt() const { + BoundingBox() {} - if (m_box.IsVoid()) { - return gp_XYZ(qNaN,qNaN,qNaN); - } - Standard_Real aXmin,aYmin,aZmin; - Standard_Real aXmax,aYmax,aZmax; - m_box.Get(aXmin,aYmin,aZmin,aXmax,aYmax,aZmax); - return gp_XYZ(aXmin,aYmin,aZmin); - } + const gp_XYZ nearPt() const { - const gp_XYZ farPt() const { - if (m_box.IsVoid()) { - return gp_XYZ(-qNaN,-qNaN,-qNaN); - } - Standard_Real aXmin,aYmin,aZmin; - Standard_Real aXmax,aYmax,aZmax; - m_box.Get(aXmin,aYmin,aZmin,aXmax,aYmax,aZmax); - return gp_XYZ(aXmax,aYmax,aZmax); + if (m_box.IsVoid()) { + return gp_XYZ(qNaN, qNaN, qNaN); } - - bool isVoid() { - return m_box.IsVoid() ? true : false ; + Standard_Real aXmin, aYmin, aZmin; + Standard_Real aXmax, aYmax, aZmax; + m_box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + return gp_XYZ(aXmin, aYmin, aZmin); + } + + const gp_XYZ farPt() const { + if (m_box.IsVoid()) { + return gp_XYZ(-qNaN, -qNaN, -qNaN); } + Standard_Real aXmin, aYmin, aZmin; + Standard_Real aXmax, aYmax, aZmax; + m_box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + return gp_XYZ(aXmax, aYmax, aZmax); + } - TEAROFF_POINT(BoundingBox,nearPt,Point3Wrap,gp_XYZ); - TEAROFF_POINT(BoundingBox,farPt, Point3Wrap,gp_XYZ); + bool isVoid() { return m_box.IsVoid() ? true : false; } - static NAN_METHOD(addPoint); - static NAN_METHOD(isOut); + TEAROFF_POINT(BoundingBox, nearPt, Point3Wrap, gp_XYZ); + TEAROFF_POINT(BoundingBox, farPt, Point3Wrap, gp_XYZ); + static NAN_METHOD(addPoint); + static NAN_METHOD(isOut); - virtual void InitNew(_NAN_METHOD_ARGS); + virtual void InitNew(_NAN_METHOD_ARGS); - static Nan::Persistent _template; + static Nan::Persistent _template; - static v8::Local NewInstance(const gp_Pnt& near,const gp_Pnt& far); - static v8::Local NewInstance(const Bnd_Box& box); + static v8::Local NewInstance(const gp_Pnt &near, + const gp_Pnt &far); + static v8::Local NewInstance(const Bnd_Box &box); - static NAN_METHOD(New); - static void Init(v8::Local target); + static NAN_METHOD(New); + static NAN_MODULE_INIT(Init); protected: - static void Update(BoundingBox* pThis,_NAN_METHOD_ARGS); + static void Update(BoundingBox *pThis, _NAN_METHOD_ARGS); }; \ No newline at end of file diff --git a/src/Edge.cc b/src/Edge.cc index f685424..f950bc6 100644 --- a/src/Edge.cc +++ b/src/Edge.cc @@ -1,37 +1,36 @@ #include "Edge.h" -#include "Util.h" #include "Mesh.h" +#include "Util.h" #include +#define EXPOSE_POINT_PROPERTY(THISTYPE, ACCESSOR) \ + Nan::SetAccessor(proto, Nan::New(#ACCESSOR).ToLocalChecked(), \ + &THISTYPE::getter_##ACCESSOR, 0, v8::Local(), \ + v8::DEFAULT, \ + (v8::PropertyAttribute)(v8::ReadOnly | v8::DontDelete)) -#define EXPOSE_POINT_PROPERTY(THISTYPE,ACCESSOR) \ - Nan::SetAccessor(proto, \ - Nan::New(#ACCESSOR).ToLocalChecked(), \ - &THISTYPE::getter_##ACCESSOR, 0,v8::Local(),v8::DEFAULT,(v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)) - -#define REXPOSE_POINT_PROPERTY(THISTYPE,ACCESSOR) \ - Nan::SetAccessor(info.This(), \ - Nan::New(#ACCESSOR).ToLocalChecked(), \ - &THISTYPE::getter_##ACCESSOR, 0,v8::Local(),v8::DEFAULT,(v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)) +#define REXPOSE_POINT_PROPERTY(THISTYPE, ACCESSOR) \ + Nan::SetAccessor( \ + info.This(), Nan::New(#ACCESSOR).ToLocalChecked(), \ + &THISTYPE::getter_##ACCESSOR, 0, v8::Local(), v8::DEFAULT, \ + (v8::PropertyAttribute)(v8::ReadOnly | v8::DontDelete)) -bool Edge::isSeam(Base *face) -{ +bool Edge::isSeam(Base *face) { if (this->shape().IsNull()) return false; - return BRep_Tool::IsClosed(this->edge(), TopoDS::Face(face->shape())) ? true : false; + return BRep_Tool::IsClosed(this->edge(), TopoDS::Face(face->shape())) ? true + : false; } -bool Edge::isDegenerated() -{ +bool Edge::isDegenerated() { if (this->shape().IsNull()) return true; return BRep_Tool::Degenerated(this->edge()) ? true : false; } -bool Edge::isClosed() -{ +bool Edge::isClosed() { if (this->shape().IsNull()) return false; TopoDS_Vertex aV1, aV2; @@ -41,45 +40,60 @@ bool Edge::isClosed() return false; } -int Edge::numVertices() -{ +int Edge::numVertices() { TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(this->edge(), TopAbs_VERTEX, anIndices); return anIndices.Extent(); } -double Edge::length() -{ - if (edge().IsNull()) return 0.0; +double Edge::length() { + if (edge().IsNull()) + return 0.0; GProp_GProps prop; BRepGProp::LinearProperties(this->edge(), prop); return prop.Mass(); } - - -int Edge::createLine(Vertex *start, Vertex *end) -{ +int Edge::createLine(Vertex *start, Vertex *end) { try { gp_Pnt aP1 = start->point(); gp_Pnt aP2 = end->point(); gce_MakeLin mLine(aP1, aP2); - const gp_Lin& line= mLine.Value(); + const gp_Lin &line = mLine.Value(); - TopoDS_Shape shape = BRepBuilderAPI_MakeEdge(line, start->vertex(), end->vertex()); + TopoDS_Shape shape = + BRepBuilderAPI_MakeEdge(line, start->vertex(), end->vertex()); this->setShape(shape); - } CATCH_AND_RETHROW_NO_RETURN("Failed to create line"); return 1; } -int Edge::createArc(Vertex *start, Vertex *end, const gp_Pnt& center) -{ +int Edge::createInterpolatedCurve(std::vector &pointArray, + bool periodic, double tolerance) { + try { + const unsigned int n_vertices = pointArray.size(); + occHandle(TColgp_HArray1OfPnt) vertices = + new TColgp_HArray1OfPnt(1, n_vertices); + + for (unsigned int vertex = 0; vertex < n_vertices; ++vertex) { + vertices->SetValue(vertex + 1, pointArray[vertex]); + } + GeomAPI_Interpolate interpolator(vertices, periodic, tolerance); + interpolator.Perform(); + if (interpolator.IsDone()) { + this->setShape(BRepBuilderAPI_MakeEdge(interpolator.Curve())); + } + } + CATCH_AND_RETHROW_NO_RETURN("Failed to create interpolated edge"); + return 1; +} + +int Edge::createArc(Vertex *start, Vertex *end, const gp_Pnt ¢er) { try { gp_Pnt aP1 = start->point(); gp_Pnt aP2 = center; @@ -87,35 +101,36 @@ int Edge::createArc(Vertex *start, Vertex *end, const gp_Pnt& center) Standard_Real Radius = aP1.Distance(aP2); gce_MakeCirc MC(aP2, gce_MakePln(aP1, aP2, aP3).Value(), Radius); - const gp_Circ& Circ = MC.Value(); + const gp_Circ &Circ = MC.Value(); Standard_Real Alpha1 = ElCLib::Parameter(Circ, aP1); Standard_Real Alpha2 = ElCLib::Parameter(Circ, aP3); occHandle(Geom_Circle) C = new Geom_Circle(Circ); - occHandle(Geom_TrimmedCurve) arc = new Geom_TrimmedCurve(C, Alpha1, Alpha2, false); - - this->setShape(BRepBuilderAPI_MakeEdge(arc, start->vertex(), end->vertex())); + occHandle(Geom_TrimmedCurve) arc = + new Geom_TrimmedCurve(C, Alpha1, Alpha2, false); + this->setShape( + BRepBuilderAPI_MakeEdge(arc, start->vertex(), end->vertex())); } CATCH_AND_RETHROW_NO_RETURN("Failed to create arc"); return 1; } -int Edge::createArc3P(Vertex *start, Vertex *end, const gp_Pnt& aPoint) -{ +int Edge::createArc3P(Vertex *start, Vertex *end, const gp_Pnt &aPoint) { try { gp_Pnt aP1 = start->point(); gp_Pnt aP2 = aPoint; gp_Pnt aP3 = end->point(); GC_MakeArcOfCircle arc(aP1, aP2, aP3); - this->setShape(BRepBuilderAPI_MakeEdge(arc.Value(), start->vertex(), end->vertex())); + this->setShape( + BRepBuilderAPI_MakeEdge(arc.Value(), start->vertex(), end->vertex())); } CATCH_AND_RETHROW_NO_RETURN("Failed to create arc"); return 1; } -int Edge::createCircle(const gp_Pnt& center, const gp_Dir& normal, double radius) -{ +int Edge::createCircle(const gp_Pnt ¢er, const gp_Dir &normal, + double radius) { try { gp_Pnt aP1 = center; gp_Dir aD1 = normal; @@ -126,80 +141,130 @@ int Edge::createCircle(const gp_Pnt& center, const gp_Dir& normal, double radius gce_MakeCirc circle(aP1, aD1, radius); this->setShape(BRepBuilderAPI_MakeEdge(circle)); - } CATCH_AND_RETHROW_NO_RETURN("Failed to create circle"); return 1; } -template T* my_unwrap(v8::MaybeLocal value) { - - auto a = Nan::To(value.ToLocalChecked()).ToLocalChecked(); - return Nan::ObjectWrap::Unwrap(a); +v8::Local getOrCreateVertex(v8::Local arg) { + Nan::EscapableHandleScope scope; + if (arg->IsArray()) { + v8::Local constructor = Constructor(); + const int argc = 1; + v8::Local argv[argc] = {arg}; + v8::Local objV = + Nan::NewInstance(constructor, argc, argv).ToLocalChecked(); + // // make a new vertex from the point array + // const int argc = 1; + // v8::Local objV = Nan::NewInstance(cons, argc, + // arg).ToLocalChecked(); + return scope.Escape(objV); + } else if (arg->IsObject()) { + + v8::Local obj = Nan::To(arg).ToLocalChecked(); + if (!IsInstanceOf(obj)) { + return scope.Escape(Nan::To(Nan::Null()).ToLocalChecked()); + } + return scope.Escape(obj); + } else { + return scope.Escape(Nan::To(Nan::Null()).ToLocalChecked()); + } } -Vertex* getOrCreateVertex(v8::Local arg) -{ +void getPointArray(v8::Local arg, std::vector &pointArray) { Nan::HandleScope scope; - if (arg->IsArray()) { - auto objV = Nan::NewInstance(Constructor(), 1, &arg).ToLocalChecked(); - if (!IsInstanceOf(objV)) { - return 0; - } - Vertex* vertex = my_unwrap(objV); - return vertex; - } - else if (arg->IsObject()) { + v8::Local arr = v8::Local::Cast(arg); + int length = arr->Length(); + pointArray.reserve(pointArray.size() + length); + for (int i = 0; i < length; i++) { + + auto elementI = Nan::Get(arr, i).ToLocalChecked(); + v8::Local jV1 = getOrCreateVertex(elementI); + if (jV1.IsEmpty()) { + return Nan::ThrowError("Arg1 must be a point"); + } + Vertex *v1 = Nan::ObjectWrap::Unwrap(jV1); - v8::Local obj = Nan::To(arg).ToLocalChecked(); - if (!IsInstanceOf(obj)) { - return 0; + gp_Pnt p2; + ReadPoint(elementI, &p2); + pointArray.push_back(p2); } - Vertex* vertex = Nan::ObjectWrap::Unwrap(Nan::To(obj).ToLocalChecked()); - return vertex; - } - else { - return 0; } } Nan::Persistent Edge::_template; -NAN_METHOD(Edge::static_createLine) -{ +NAN_METHOD(Edge::static_makeLine) { + v8::Local arg1 = info[0]; v8::Local arg2 = info[1]; if (arg1.IsEmpty() || arg2.IsEmpty()) { - return Nan::ThrowError("expecting 2 arguments : , "); + return Nan::ThrowError( + "expecting 2 arguments : , "); + } + + v8::Local v1 = getOrCreateVertex(info[0]); + v8::Local v2 = getOrCreateVertex(info[1]); + + if (v1.IsEmpty() || v2.IsEmpty()) { + return Nan::ThrowError( + "expecting 2 arguments : , "); } - Vertex* v1 = getOrCreateVertex(info[0]); - Vertex* v2 = getOrCreateVertex(info[1]); - if (!v1 || !v2) { - return Nan::ThrowError("expecting 2 arguments : , "); + v8::Local instance = makeInstance(_template); + Edge *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(instance).ToLocalChecked()); + + Vertex *_v1 = Nan::ObjectWrap::Unwrap(v1); + Vertex *_v2 = Nan::ObjectWrap::Unwrap(v2); + + pThis->createLine(_v1, _v2); + info.GetReturnValue().Set(instance); +} + +/** + * info[0] => PntArray or Vertex Array + */ +NAN_METHOD(Edge::static_makeInterpolatedCurve) { + v8::Local instance = makeInstance(_template); + Edge *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(instance).ToLocalChecked()); + + try { + v8::Local arg1 = info[0]; + v8::Local arg2 = info[1]; + v8::Local arg3 = info[2]; + std::vector pointArray; + getPointArray(arg1, pointArray); + + bool periodic = false; + ReadBoolean(arg2, periodic, false); + + double tolerance = 0.01; + ReadDouble(arg3, tolerance, tolerance); + + pThis->createInterpolatedCurve(pointArray, periodic, tolerance); } + CATCH_AND_RETHROW_NO_RETURN("Failed to create an interpolated curve"); - v8::Local instance = Nan::NewInstance(Constructor()).ToLocalChecked(); - Edge* pThis = Nan::ObjectWrap::Unwrap(Nan::To(instance).ToLocalChecked()); - - pThis->createLine(v1, v2); info.GetReturnValue().Set(instance); } -NAN_METHOD(Edge::static_createCircle) -{ +NAN_METHOD(Edge::static_makeCircle) { v8::Local arg1 = info[0]; v8::Local arg2 = info[1]; v8::Local arg3 = info[2]; if (arg1.IsEmpty() || arg2.IsEmpty() || arg3.IsEmpty()) { - return Nan::ThrowError("expecting three arguments :
,,"); + return Nan::ThrowError( + "expecting three arguments :
,,"); } gp_Pnt center; ReadPoint(arg1, ¢er); + gp_Dir normal; ReadDir(arg2, &normal); @@ -213,8 +278,7 @@ NAN_METHOD(Edge::static_createCircle) return Nan::ThrowError("radius cannot be zero ( or close to zero)"); } - - Edge* pThis = new Edge(); + Edge *pThis = new Edge(); v8::Local instance = makeInstance(_template); pThis->Wrap(instance); @@ -223,40 +287,49 @@ NAN_METHOD(Edge::static_createCircle) info.GetReturnValue().Set(instance); } -NAN_METHOD(Edge::static_createArc3P) -{ +NAN_METHOD(Edge::static_makeArc3P) { v8::Local arg1 = info[0]; v8::Local arg2 = info[1]; v8::Local arg3 = info[2]; if (arg1.IsEmpty() || arg2.IsEmpty() || arg3.IsEmpty()) { - return Nan::ThrowError("expecting three arguments :
,,"); + return Nan::ThrowError( + "expecting three arguments :
,,"); } + v8::Local jV1 = getOrCreateVertex(arg1); + if (jV1.IsEmpty()) { + return Nan::ThrowError("Arg1 must be a point"); + } + Vertex *v1 = Nan::ObjectWrap::Unwrap(jV1); - Vertex* v1 = getOrCreateVertex(arg1); - gp_Pnt p2; + gp_Pnt p2; ReadPoint(arg2, &p2); - Vertex* v3 = getOrCreateVertex(arg3); + v8::Local jV3 = getOrCreateVertex(arg3); + if (jV3.IsEmpty()) { + return Nan::ThrowError("Arg3 must be a point"); + } + Vertex *v3 = Nan::ObjectWrap::Unwrap(jV3); - Edge* pThis = new Edge(); + Edge *pThis = new Edge(); v8::Local instance = makeInstance(_template); pThis->Wrap(instance); - pThis->createArc3P(v1, v3, p2); + try { + pThis->createArc3P(v1, v3, p2); + } + CATCH_AND_RETHROW_NO_RETURN("Failed to create arc with 3 points"); info.GetReturnValue().Set(instance); } - -NAN_METHOD(Edge::New) -{ +NAN_METHOD(Edge::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Edge() to construct a Edge"); } - Edge* pThis = new Edge(); + Edge *pThis = new Edge(); pThis->Wrap(info.This()); pThis->InitNew(info); @@ -268,19 +341,15 @@ NAN_METHOD(Edge::New) REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Edge, isClosed); REXPOSE_POINT_PROPERTY(Edge, firstVertex); REXPOSE_POINT_PROPERTY(Edge, lastVertex); - } - - -v8::Local Edge::Clone() const -{ - - Edge* obj = new Edge(); +v8::Local Edge::Clone() const { + Nan::EscapableHandleScope scope; + Edge *obj = new Edge(); v8::Local instance = makeInstance(_template); obj->Wrap(instance); obj->setShape(this->shape()); - return instance; + return scope.Escape(instance); } NAN_PROPERTY_GETTER(Edge::getter_firstVertex) { @@ -295,13 +364,12 @@ NAN_PROPERTY_GETTER(Edge::getter_firstVertex) { return; } - Edge* pThis = Nan::ObjectWrap::Unwrap(info.This()); + Edge *pThis = Nan::ObjectWrap::Unwrap(info.This()); - TopoDS_Vertex shape = TopExp::FirstVertex(pThis->edge()/*,CumOri=false*/); + TopoDS_Vertex shape = TopExp::FirstVertex(pThis->edge() /*,CumOri=false*/); v8::Local obj = buildWrapper(shape); info.GetReturnValue().Set(obj); - } NAN_PROPERTY_GETTER(Edge::getter_lastVertex) { @@ -315,28 +383,21 @@ NAN_PROPERTY_GETTER(Edge::getter_lastVertex) { return; } - Edge* pThis = Nan::ObjectWrap::Unwrap(info.This()); + Edge *pThis = Nan::ObjectWrap::Unwrap(info.This()); - TopoDS_Vertex shape = TopExp::LastVertex(pThis->edge()/*,CumOri=false*/); + TopoDS_Vertex shape = TopExp::LastVertex(pThis->edge() /*,CumOri=false*/); v8::Local obj = buildWrapper(shape); info.GetReturnValue().Set(obj); - } - - - - -void Edge::Init(v8::Local target) -{ - +NAN_MODULE_INIT(Edge::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(Edge::New); + v8::Local tpl = + Nan::New(Edge::New); tpl->SetClassName(Nan::New("Edge").ToLocalChecked()); - - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -355,40 +416,42 @@ void Edge::Init(v8::Local target) EXPOSE_POINT_PROPERTY(Edge, firstVertex); EXPOSE_POINT_PROPERTY(Edge, lastVertex); - EXPOSE_METHOD(Edge, polygonize); - //xx EXPOSE_METHOD(Edge, polygonOnTriangulation); - - - Nan::Set(target, Nan::New("Edge").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); - - //xx EXPOSE_STATIC_METHOD(Edge,createLine); - //xx EXPOSE_STATIC_METHOD(Edge,createCircle); - //xx EXPOSE_STATIC_METHOD(Edge,createArc3P); - Nan::SetMethod(tpl, "makeLine", Edge::static_createLine); - Nan::SetMethod(tpl, "makeArc3P", Edge::static_createArc3P); - Nan::SetMethod(tpl, "makeCircle", Edge::static_createCircle); - - Nan::SetMethod(target, "makeLine", Edge::static_createLine); - Nan::SetMethod(target, "makeArc3P", Edge::static_createArc3P); - Nan::SetMethod(target, "makeCircle", Edge::static_createCircle); - + // xx EXPOSE_METHOD(Edge, polygonOnTriangulation); + + Nan::Set(target, Nan::New("Edge").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); + + // xx EXPOSE_STATIC_METHOD(Edge,createLine); + // xx EXPOSE_STATIC_METHOD(Edge,createCircle); + // xx EXPOSE_STATIC_METHOD(Edge,createArc3P); + Nan::SetMethod(tpl, "makeLine", Edge::static_makeLine); + Nan::SetMethod(tpl, "makeArc3P", Edge::static_makeArc3P); + Nan::SetMethod(tpl, "makeCircle", Edge::static_makeCircle); + Nan::SetMethod(tpl, "makeInterpolatedCurve", + Edge::static_makeInterpolatedCurve); + + Nan::SetMethod(target, "makeLine", Edge::static_makeLine); + Nan::SetMethod(target, "makeArc3P", Edge::static_makeArc3P); + Nan::SetMethod(target, "makeCircle", Edge::static_makeCircle); + Nan::SetMethod(target, "makeInterpolatedCurve", + Edge::static_makeInterpolatedCurve); } - -void extractEdgePolygon(const TopoDS_Edge& edge, std::vector& positions) -{ +void extractEdgePolygon(const TopoDS_Edge &edge, + std::vector &positions) { if (edge.IsNull()) { StdFail_NotDone::Raise("Face is Null"); } TopLoc_Location loc; occHandle(Poly_Polygon3D) polygon = BRep_Tool::Polygon3D(edge, loc); if (polygon.IsNull()) { - StdFail_NotDone::Raise("cannot find Poly_Polygon3D on edge with BRep_Tool::Polygon3Dated"); + StdFail_NotDone::Raise( + "cannot find Poly_Polygon3D on edge with BRep_Tool::Polygon3Dated"); } - //xx if (polygon.Deflection() == factor) - const TColgp_Array1OfPnt& points = polygon->Nodes(); + // xx if (polygon.Deflection() == factor) + const TColgp_Array1OfPnt &points = polygon->Nodes(); positions.clear(); int n = points.Length(); @@ -400,18 +463,17 @@ void extractEdgePolygon(const TopoDS_Edge& edge, std::vector& positions) positions.push_back(static_cast(pt.Z())); } return; - } -v8::Local Edge::polygonize(double factor) -{ +v8::Local Edge::polygonize(double factor) { - const TopoDS_Edge& edge = TopoDS::Edge(this->shape()); + Nan::EscapableHandleScope scope; + const TopoDS_Edge &edge = TopoDS::Edge(this->shape()); if (factor == 0.0) { extractEdgePolygon(edge, m_positions); int length = (int)m_positions.size(); - return makeFloat32Array(m_positions.data(), length); + return scope.Escape(makeFloat32Array(m_positions.data(), length)); } BRepAdaptor_Curve curve_adaptor(edge); @@ -427,38 +489,35 @@ v8::Local Edge::polygonize(double factor) m_positions.push_back(static_cast(pt.Z())); } int length = (int)m_positions.size(); - return makeFloat32Array(m_positions.data(), length); - + auto retValue = makeFloat32Array(m_positions.data(), length); + return scope.Escape(retValue); } -NAN_METHOD(Edge::getVertices) -{ - Edge* pThis = UNWRAP(Edge); +NAN_METHOD(Edge::getVertices) { + Edge *pThis = UNWRAP(Edge); auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_VERTEX); info.GetReturnValue().Set(arr); } - -NAN_METHOD(Edge::polygonize) -{ - Edge* pThis = UNWRAP(Edge); +NAN_METHOD(Edge::polygonize) { + Edge *pThis = UNWRAP(Edge); if (info.Length() == 0) { try { - const TopoDS_Edge& edge = TopoDS::Edge(pThis->shape()); + const TopoDS_Edge &edge = TopoDS::Edge(pThis->shape()); extractEdgePolygon(edge, pThis->m_positions); int length = (int)pThis->m_positions.size(); - info.GetReturnValue().Set(makeFloat32Array(pThis->m_positions.data(), length)); + info.GetReturnValue().Set( + makeFloat32Array(pThis->m_positions.data(), length)); return; - } - catch (Standard_Failure& e) { + } catch (Standard_Failure &e) { const Standard_CString msg = e.GetMessageString(); if (msg != NULL && strlen(msg) > 1) { - //xx cout << " message =" << msg << "\n";// setErrorMessage(msg); - } - else { - //xx cout << " message =" << "failed to polygonize edge ( extracting default )" << "\n";// setErrorMessage(msg); + // xx cout << " message =" << msg << "\n";// setErrorMessage(msg); + } else { + // xx cout << " message =" << "failed to polygonize edge ( extracting + // default )" << "\n";// setErrorMessage(msg); } } } @@ -469,4 +528,3 @@ NAN_METHOD(Edge::polygonize) v8::Local ret = pThis->polygonize(factor); info.GetReturnValue().Set(ret); } - diff --git a/src/Edge.h b/src/Edge.h index a72f7cb..889ed9d 100644 --- a/src/Edge.h +++ b/src/Edge.h @@ -6,67 +6,67 @@ class Edge : public Base { public: - TopoDS_Edge m_edge; - std::vector m_positions; - - Edge() { - ; - } - - bool isSeam(Base *face); - - bool isDegenerated(); - bool isClosed(); - int numVertices(); - double length(); - - v8::Local polygonize(double factor); - - int createLine(Vertex *start, Vertex *end); - int createArc(Vertex *start, Vertex *end, const gp_Pnt& center); - int createArc3P(Vertex *start, Vertex *end, const gp_Pnt& middlePoint); - - int createCircle(const gp_Pnt& center , const gp_Dir& normal, double radius); - - //int createEllipse(OCCStruct3d pnt, OCCStruct3d nor, double rMajor, double rMinor); - //int createHelix(double pitch, double height, double radius, double angle, bool leftHanded); - //int createBezier(OCCVertex *start, OCCVertex *end, std::vector points); - //int createSpline(OCCVertex *start, OCCVertex *end, std::vector points,double tolerance); - //int createNURBS(OCCVertex *start, OCCVertex *end, std::vector points, DVec knots, DVec weights, IVec mult); - - bool canSetShape(const TopoDS_Shape& shape) const { - return shape.ShapeType() == TopAbs_EDGE; - } - virtual const TopoDS_Shape& shape() const { - return m_edge; - } - virtual const TopoDS_Edge& edge() const { - return m_edge; - } - virtual void setShape(const TopoDS_Shape& shape) { - m_edge = TopoDS::Edge(shape); - } - virtual v8::Local Clone() const ; - virtual Base* Unwrap(v8::Local obj) const { - return Nan::ObjectWrap::Unwrap(obj); - } - - static NAN_PROPERTY_GETTER(getter_firstVertex); - static NAN_PROPERTY_GETTER(getter_lastVertex); - - // Static Methods - static NAN_METHOD(static_createLine); - static NAN_METHOD(static_createCircle); - static NAN_METHOD(static_createArc3P); - - - static NAN_METHOD(polygonize); - static NAN_METHOD(getVertices); - - static NAN_METHOD(New); - static NAN_METHOD(startVertex); - static NAN_METHOD(endVertex); - - static void Init(v8::Local target); - static Nan::Persistent _template; + TopoDS_Edge m_edge; + std::vector m_positions; + + Edge() { ; } + + bool isSeam(Base *face); + + bool isDegenerated(); + bool isClosed(); + int numVertices(); + double length(); + + v8::Local polygonize(double factor); + + int createLine(Vertex *start, Vertex *end); + int createArc(Vertex *start, Vertex *end, const gp_Pnt ¢er); + int createArc3P(Vertex *start, Vertex *end, const gp_Pnt &middlePoint); + + int createCircle(const gp_Pnt ¢er, const gp_Dir &normal, double radius); + + int createInterpolatedCurve(std::vector &PointArray, bool periodic, + double tolerance); + + // int createEllipse(OCCStruct3d pnt, OCCStruct3d nor, double rMajor, double + // rMinor); int createHelix(double pitch, double height, double radius, double + // angle, bool leftHanded); int createBezier(OCCVertex *start, OCCVertex *end, + // std::vector points); int createSpline(OCCVertex *start, + // OCCVertex *end, std::vector points,double tolerance); int + // createNURBS(OCCVertex *start, OCCVertex *end, std::vector + // points, DVec knots, DVec weights, IVec mult); + + bool canSetShape(const TopoDS_Shape &shape) const { + return shape.ShapeType() == TopAbs_EDGE; + } + virtual const TopoDS_Shape &shape() const { return m_edge; } + virtual const TopoDS_Edge &edge() const { return m_edge; } + virtual void setShape(const TopoDS_Shape &shape) { + m_edge = TopoDS::Edge(shape); + } + virtual v8::Local Clone() const; + virtual Base *Unwrap(v8::Local obj) const { + return Nan::ObjectWrap::Unwrap(obj); + } + + static NAN_PROPERTY_GETTER(getter_firstVertex); + static NAN_PROPERTY_GETTER(getter_lastVertex); + + // Static Methods + static NAN_METHOD(static_makeLine); + static NAN_METHOD(static_makeCircle); + static NAN_METHOD(static_makeArc3P); + static NAN_METHOD(static_makeInterpolatedCurve); + + static NAN_METHOD(polygonize); + static NAN_METHOD(getVertices); + + static NAN_METHOD(New); + static NAN_METHOD(startVertex); + static NAN_METHOD(endVertex); + + static NAN_MODULE_INIT(Init); + + static Nan::Persistent _template; }; \ No newline at end of file diff --git a/src/Face.cc b/src/Face.cc index e66a8c3..4d4c591 100644 --- a/src/Face.cc +++ b/src/Face.cc @@ -1,75 +1,59 @@ #include "Face.h" -#include "Wire.h" #include "Edge.h" -#include "Util.h" #include "Mesh.h" +#include "Util.h" +#include "Wire.h" -Face::~Face() { - m_cacheMesh.Reset(); -}; +Face::~Face() { m_cacheMesh.Reset(); }; -const TopoDS_Shape& Face::shape() const -{ - return face(); -} +const TopoDS_Shape &Face::shape() const { return face(); } -void Face::setShape( const TopoDS_Shape& shape) -{ - m_face = TopoDS::Face(shape); -} +void Face::setShape(const TopoDS_Shape &shape) { m_face = TopoDS::Face(shape); } -int Face::numWires() -{ - if(shape().IsNull()) return 0; +int Face::numWires() { + if (shape().IsNull()) + return 0; TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(shape(), TopAbs_WIRE, anIndices); return anIndices.Extent(); } -NAN_METHOD(Face::getWires) -{ - Face* pThis = UNWRAP(Face); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_WIRE); +NAN_METHOD(Face::getWires) { + Face *pThis = UNWRAP(Face); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_WIRE); info.GetReturnValue().Set(arr); } -bool Face::fixShape() -{ - return true; -} +bool Face::fixShape() { return true; } -double Face::area() -{ +double Face::area() { GProp_GProps prop; BRepGProp::SurfaceProperties(shape(), prop); return prop.Mass(); } -bool Face::hasMesh() -{ +bool Face::hasMesh() { TopLoc_Location loc; - occHandle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(this->face(), loc); - return triangulation.IsNull()?false:true; + occHandle(Poly_Triangulation) triangulation = + BRep_Tool::Triangulation(this->face(), loc); + return triangulation.IsNull() ? false : true; } -std::vector Face::inertia() -{ +std::vector Face::inertia() { std::vector ret; GProp_GProps prop; BRepGProp::SurfaceProperties(this->shape(), prop); gp_Mat mat = prop.MatrixOfInertia(); - ret.push_back(mat(1,1)); // Ixx - ret.push_back(mat(2,2)); // Iyy - ret.push_back(mat(3,3)); // Izz - ret.push_back(mat(1,2)); // Ixy - ret.push_back(mat(1,3)); // Ixz - ret.push_back(mat(2,3)); // Iyz + ret.push_back(mat(1, 1)); // Ixx + ret.push_back(mat(2, 2)); // Iyy + ret.push_back(mat(3, 3)); // Izz + ret.push_back(mat(1, 2)); // Ixy + ret.push_back(mat(1, 3)); // Ixz + ret.push_back(mat(2, 3)); // Iyz return ret; } - -const gp_XYZ Face::centreOfMass() const -{ +const gp_XYZ Face::centreOfMass() const { GProp_GProps prop; BRepGProp::SurfaceProperties(this->shape(), prop); @@ -78,8 +62,7 @@ const gp_XYZ Face::centreOfMass() const return cg.Coord(); } -bool Face::isPlanar() -{ +bool Face::isPlanar() { Handle_Geom_Surface surf = BRep_Tool::Surface(this->m_face); GeomLib_IsPlanarSurface tool(surf); @@ -88,9 +71,9 @@ bool Face::isPlanar() Nan::Persistent Face::_template; -bool Face::buildFace(std::vector& wires) -{ - if (wires.size()==0) return false; +bool Face::buildFace(std::vector &wires) { + if (wires.size() == 0) + return false; // checling that all wires are closed for (uint32_t i = 0; i < wires.size(); i++) { @@ -101,13 +84,13 @@ bool Face::buildFace(std::vector& wires) } try { - const TopoDS_Wire& outerwire = wires[0]->wire(); + const TopoDS_Wire &outerwire = wires[0]->wire(); BRepBuilderAPI_MakeFace MF(outerwire); // add optional holes for (unsigned i = 1; i < wires.size(); i++) { - const TopoDS_Wire& wire = wires[i]->wire(); + const TopoDS_Wire &wire = wires[i]->wire(); if (wire.Orientation() != outerwire.Orientation()) { MF.Add(TopoDS::Wire(wire.Reversed())); @@ -121,7 +104,6 @@ bool Face::buildFace(std::vector& wires) if (!this->fixShape()) { StdFail_NotDone::Raise("Shapes not valid"); } - } CATCH_AND_RETHROW_NO_RETURN("Failed to create a face"); return true; @@ -129,100 +111,97 @@ bool Face::buildFace(std::vector& wires) NAN_METHOD(Face::NewInstance) { _NewInstance(info); } -NAN_METHOD(Face::New) -{ +NAN_METHOD(Face::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.Face() to construct a Face"); + return Nan::ThrowError(" use new occ.Face() to construct a Face"); } - Face* pThis = new Face(); + Face *pThis = new Face(); pThis->Wrap(info.This()); pThis->InitNew(info); - std::vector wires; - extractArgumentList(info,wires); + std::vector wires; + extractArgumentList(info, wires); pThis->buildFace(wires); info.GetReturnValue().Set(info.This()); - } -v8::Local Face::Clone() const -{ - Face* obj = new Face(); +v8::Local Face::Clone() const { + Nan::EscapableHandleScope scope; + Face *obj = new Face(); v8::Local instance = makeInstance(_template); obj->Wrap(instance); obj->setShape(this->shape()); - return instance; + return scope.Escape(instance); } -v8::Local Face::NewInstance(const TopoDS_Face& face) -{ - Face* obj = new Face(); +v8::Local Face::NewInstance(const TopoDS_Face &face) { + Nan::EscapableHandleScope scope; + Face *obj = new Face(); v8::Local instance = makeInstance(_template); obj->Wrap(instance); obj->setShape(face); - return instance; + return scope.Escape(instance); } -NAN_PROPERTY_GETTER(Face::_mesh) -{ - Face* pThis = UNWRAP(Face) +NAN_PROPERTY_GETTER(Face::_mesh) { + Face *pThis = UNWRAP(Face) - if (pThis->m_cacheMesh.IsEmpty()) { - pThis->m_cacheMesh.Reset(pThis->createMesh(1,0.5, true)); + if (pThis->m_cacheMesh.IsEmpty()) { + pThis->m_cacheMesh.Reset(pThis->createMesh(1, 0.5, true)); } info.GetReturnValue().Set(Nan::New(pThis->m_cacheMesh)); } -v8::Local Face::createMesh(double factor, double angle, bool qualityNormals) -{ +v8::Local Face::createMesh(double factor, double angle, + bool qualityNormals) { Nan::EscapableHandleScope scope; const unsigned argc = 0; - v8::Local argv[1] = { }; - + v8::Local argv[1] = {}; + v8::Local theMesh = makeInstance(Mesh::_template); - Mesh *mesh = Mesh::Unwrap(theMesh); + Mesh *mesh = Mesh::Unwrap(theMesh); - const TopoDS_Shape& shape = this->shape(); + const TopoDS_Shape &shape = this->shape(); try { TopLoc_Location loc; - occHandle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(this->face(), loc); + occHandle(Poly_Triangulation) triangulation = + BRep_Tool::Triangulation(this->face(), loc); if (triangulation.IsNull()) { - BRepMesh_IncrementalMesh MSH(shape,factor,Standard_True,angle,Standard_True); + BRepMesh_IncrementalMesh MSH(shape, factor, Standard_True, angle, + Standard_True); } - // this code assume that the triangulation has been created // on the parent object mesh->extractFaceMesh(this->face(), qualityNormals); mesh->optimize(); - - } CATCH_AND_RETHROW_NO_RETURN("Failed to mesh solid "); + } + CATCH_AND_RETHROW_NO_RETURN("Failed to mesh solid "); return scope.Escape(theMesh); } - -void Face::InitNew(_NAN_METHOD_ARGS) -{ +void Face::InitNew(_NAN_METHOD_ARGS) { Base::InitNew(info); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face,area); - REXPOSE_READ_ONLY_PROPERTY_INTEGER(Face,numWires); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face,area); - REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face,isPlanar); - REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face,hasMesh); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face, area); + REXPOSE_READ_ONLY_PROPERTY_INTEGER(Face, numWires); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face, area); + REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face, isPlanar); + REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face, hasMesh); } -void Face::Init(v8::Local target) -{ +NAN_MODULE_INIT(Face::Init) { + // Prepare constructor template - v8::Local tpl = Nan::New(Face::New); + v8::Local tpl = + Nan::New(Face::New); tpl->SetClassName(Nan::New("Face").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -232,20 +211,20 @@ void Face::Init(v8::Local target) Base::InitProto(proto); - EXPOSE_METHOD(Face,getWires); - EXPOSE_METHOD(Face,createMesh); - EXPOSE_READ_ONLY_PROPERTY_INTEGER(Face,numWires); - EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face,area); - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face,isPlanar); - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face,hasMesh); - EXPOSE_READ_ONLY_PROPERTY(_mesh,mesh); - EXPOSE_TEAROFF(Face,centreOfMass); - Nan::Set(target,Nan::New("Face").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); -} - -NAN_METHOD(Face::createMesh) -{ - Face* pThis = UNWRAP(Face); - v8::Local mesh = pThis->createMesh(1,0.5,true); + EXPOSE_METHOD(Face, getWires); + EXPOSE_METHOD(Face, createMesh); + EXPOSE_READ_ONLY_PROPERTY_INTEGER(Face, numWires); + EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Face, area); + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face, isPlanar); + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Face, hasMesh); + EXPOSE_READ_ONLY_PROPERTY(_mesh, mesh); + EXPOSE_TEAROFF(Face, centreOfMass); + Nan::Set(target, Nan::New("Face").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); +} + +NAN_METHOD(Face::createMesh) { + Face *pThis = UNWRAP(Face); + v8::Local mesh = pThis->createMesh(1, 0.5, true); info.GetReturnValue().Set(mesh); } diff --git a/src/Face.h b/src/Face.h index ca4311e..7933b18 100644 --- a/src/Face.h +++ b/src/Face.h @@ -1,13 +1,13 @@ #pragma once -#include "OCC.h" #include "NodeV8.h" +#include "OCC.h" #include "Base.h" #include "Point3Wrap.h" #include class Wire; -class Face: public Base { +class Face : public Base { friend class Mesh; TopoDS_Face m_face; @@ -24,30 +24,27 @@ class Face: public Base { const gp_XYZ centreOfMass() const; - TEAROFF_POINT(Face,centreOfMass,Point3Wrap,gp_XYZ); + TEAROFF_POINT(Face, centreOfMass, Point3Wrap, gp_XYZ); - virtual const TopoDS_Shape& shape() const; - const TopoDS_Face& face() const { - return m_face; - } - virtual void setShape(const TopoDS_Shape&); + virtual const TopoDS_Shape &shape() const; + const TopoDS_Face &face() const { return m_face; } + virtual void setShape(const TopoDS_Shape &); - bool buildFace(std::vector& wires); + bool buildFace(std::vector &wires); static NAN_METHOD(extrude); virtual v8::Local Clone() const; - virtual Base* Unwrap(v8::Local obj) const { + virtual Base *Unwrap(v8::Local obj) const { return Nan::ObjectWrap::Unwrap(obj); } virtual void InitNew(_NAN_METHOD_ARGS); + v8::Local createMesh(double factor, double angle, + bool qualityNormals); - v8::Local createMesh(double factor, double angle, bool qualityNormals); - - static void Init(v8::Local target); - static v8::Local NewInstance(const TopoDS_Face& face); + static v8::Local NewInstance(const TopoDS_Face &face); static NAN_METHOD(New); static NAN_METHOD(createMesh); // custom mesh @@ -55,6 +52,7 @@ class Face: public Base { static NAN_METHOD(getWires); static NAN_METHOD(NewInstance); + static NAN_MODULE_INIT(Init); static Nan::Persistent _template; }; \ No newline at end of file diff --git a/src/GeometryBuilder.h b/src/GeometryBuilder.h index 6c43992..86ec595 100644 --- a/src/GeometryBuilder.h +++ b/src/GeometryBuilder.h @@ -1,6 +1,3 @@ #pragma once #include "NodeV8.h" #include "OCC.h" - - - diff --git a/src/Mesh.cc b/src/Mesh.cc index 06176de..62f5520 100644 --- a/src/Mesh.cc +++ b/src/Mesh.cc @@ -1,33 +1,32 @@ #include "Mesh.h" -#include -#include #include -#include -#include #include +#include +#include +#include +#include -#include "Util.h" #include "TShort_Array1OfShortReal.hxx" - +#include "Util.h" // old handle in V8 : see http://create.tpsitulsa.com/wiki/V8/Handles -Mesh::Mesh() -{ -} +Mesh::Mesh() {} -NAN_METHOD(Mesh::New) -{ +NAN_METHOD(Mesh::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Mesh() to construct a Mesh"); } - Mesh* obj = new Mesh(); + Mesh *obj = new Mesh(); - Nan::Set(info.This(),Nan::New("normals").ToLocalChecked(), Nan::New()); - Nan::Set(info.This(),Nan::New("edgeIndices").ToLocalChecked(), Nan::New()); - Nan::Set(info.This(),Nan::New("triangles").ToLocalChecked(), Nan::New()); + Nan::Set(info.This(), Nan::New("normals").ToLocalChecked(), + Nan::New()); + Nan::Set(info.This(), Nan::New("edgeIndices").ToLocalChecked(), + Nan::New()); + Nan::Set(info.This(), Nan::New("triangles").ToLocalChecked(), + Nan::New()); obj->Wrap(info.This()); info.GetReturnValue().Set(info.This()); @@ -35,15 +34,13 @@ NAN_METHOD(Mesh::New) Nan::Persistent Mesh::_template; - -/*static*/ -void Mesh::Init(v8::Local target) -{ +NAN_MODULE_INIT(Mesh::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(Mesh::New); + v8::Local tpl = + Nan::New(Mesh::New); tpl->SetClassName(Nan::New("Mesh").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -61,19 +58,18 @@ void Mesh::Init(v8::Local target) EXPOSE_METHOD(Mesh, getFaceTriangleNormals); // other Mesh prototype members are defined in the mesh.js script - Nan::Set(target,Nan::New("Mesh").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); - + Nan::Set(target, Nan::New("Mesh").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } -long hashpoint(double x, double y, double z) -{ +long hashpoint(double x, double y, double z) { long nx = static_cast(x * 1000); long ny = static_cast(y * 1000); long nz = static_cast(z * 1000); return (nx * 9138553 + ny * 485993 + nz * 1194163) % 15485653; } -uint32_t Mesh::push_point(const Coord3f& point) { +uint32_t Mesh::push_point(const Coord3f &point) { long hash = hashpoint(point.x, point.y, point.z); auto it = this->_mapVertices.find(hash); if (it == this->_mapVertices.end()) { @@ -85,7 +81,7 @@ uint32_t Mesh::push_point(const Coord3f& point) { return it->second; } -uint32_t Mesh::push_normal(const Coord3f& normal) { +uint32_t Mesh::push_normal(const Coord3f &normal) { long hash = hashpoint(normal.x, normal.y, normal.z); auto it = this->_mapNormals.find(hash); if (it == this->_mapNormals.end()) { @@ -97,13 +93,11 @@ uint32_t Mesh::push_normal(const Coord3f& normal) { return it->second; } -int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) -{ - +int Mesh::extractFaceMesh(const TopoDS_Face &face, bool qualityNormals) { if (face.IsNull()) { StdFail_NotDone::Raise("Face is Null"); } - auto& hashMap = this->_faceHashMap; + auto &hashMap = this->_faceHashMap; int hash = face.HashCode(std::numeric_limits::max()); // find hash in edgehash.push_back(hash); if (hashMap.end() != hashMap.find(hash)) { @@ -114,7 +108,8 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) this->_faceRanges.push_back((uint32_t)this->_triangles.size()); TopLoc_Location loc; - occHandle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(face, loc); + occHandle(Poly_Triangulation) triangulation = + BRep_Tool::Triangulation(face, loc); if (triangulation.IsNull()) { StdFail_NotDone::Raise("No triangulation created"); } @@ -130,13 +125,13 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) normalTranslationTable.reserve(nb_points); // ------------------------------------------------------------------------------ - // import face points into index + // import face points into index // ------------------------------------------------------------------------------ - const TColgp_Array1OfPnt& nodes = triangulation->Nodes(); + const TColgp_Array1OfPnt &nodes = triangulation->Nodes(); Coord3f vert; double x, y, z; for (int i = 1; i <= nb_points; i++) { - const gp_Pnt& pnt = nodes(i); + const gp_Pnt &pnt = nodes(i); x = pnt.X(); y = pnt.Y(); z = pnt.Z(); @@ -158,36 +153,33 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) for (int i = 1; i <= nb_points; i++) { local_normals.push_back(gp_Vec(0, 0, 0)); } - } - else { + } else { if (triangulation->HasNormals()) { - const TShort_Array1OfShortReal& normals = triangulation->Normals(); + const TShort_Array1OfShortReal &normals = triangulation->Normals(); for (int i = 0; i < nb_points; i++) { - const Standard_ShortReal& nx = normals( i*3 + 1); - const Standard_ShortReal& ny = normals( i*3 + 2); - const Standard_ShortReal& nz = normals( i*3 + 3); - - local_normals.push_back(gp_Vec(nx,ny,nz)); + const Standard_ShortReal &nx = normals(i * 3 + 1); + const Standard_ShortReal &ny = normals(i * 3 + 2); + const Standard_ShortReal &nz = normals(i * 3 + 3); + local_normals.push_back(gp_Vec(nx, ny, nz)); } - } - else { + } else { Handle_Geom_Surface surface = BRep_Tool::Surface(face); gp_Vec normal; if (triangulation->HasUVNodes()) { - const TColgp_Array1OfPnt2d& uvnodes = triangulation->UVNodes(); + const TColgp_Array1OfPnt2d &uvnodes = triangulation->UVNodes(); for (int i = 0; i < nb_points; i++) { - const gp_Pnt2d& uv = uvnodes(i + 1); + const gp_Pnt2d &uv = uvnodes(i + 1); double fU = uv.X(); double fV = uv.Y(); GeomLProp_SLProps faceprop(surface, fU, fV, 2, gp::Resolution()); - if (faceprop.IsNormalDefined()){ + if (faceprop.IsNormalDefined()) { normal = faceprop.Normal(); } @@ -198,23 +190,20 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) normal *= -1.0; } local_normals.push_back(normal); - } - } - else { - + } else { for (int i = 0; i < nb_points; i++) { //------------------------------------------------ - const gp_Pnt& vertex = nodes(i + 1); + const gp_Pnt &vertex = nodes(i + 1); GeomAPI_ProjectPointOnSurf SrfProp(vertex, surface); - + Standard_Real fU, fV; SrfProp.Parameters(1, fU, fV); GeomLProp_SLProps faceprop(surface, fU, fV, 2, gp::Resolution()); - if (faceprop.IsNormalDefined()){ + if (faceprop.IsNormalDefined()) { normal = faceprop.Normal(); } @@ -242,7 +231,7 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) // Navigate triangles //--------------------------------------------------------------------------------- - const Poly_Array1OfTriangle& triarr = triangulation->Triangles(); + const Poly_Array1OfTriangle &triarr = triangulation->Triangles(); this->_triangles.reserve(triangulation->NbTriangles()); Triangle3i tri; @@ -250,12 +239,11 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) int _effective_number_of_triangle = 0; for (int i = 1; i <= nb_triangles; i++) { - const Poly_Triangle& pt = triarr(i); + const Poly_Triangle &pt = triarr(i); Standard_Integer n1, n2, n3; if (reversed) { pt.Get(n2, n1, n3); - } - else { + } else { pt.Get(n1, n2, n3); } @@ -264,9 +252,9 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) continue; // Calculate face normal - const gp_Pnt& P1 = nodes(n1); - const gp_Pnt& P2 = nodes(n2); - const gp_Pnt& P3 = nodes(n3); + const gp_Pnt &P1 = nodes(n1); + const gp_Pnt &P2 = nodes(n2); + const gp_Pnt &P3 = nodes(n3); gp_Vec V1(P3.X() - P1.X(), P3.Y() - P1.Y(), P3.Z() - P1.Z()); if (V1.SquareMagnitude() < 1.0e-10) { @@ -304,15 +292,12 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) tri.k = this->push_normal(local_normals[n3 - 1]); this->_triangles_normals.push_back(tri); - - } - else { + } else { tri.i = this->push_normal(local_normals[n1 - 1]); tri.j = this->push_normal(local_normals[n2 - 1]); tri.k = this->push_normal(local_normals[n3 - 1]); this->_triangles_normals.push_back(tri); - } _effective_number_of_triangle++; @@ -325,7 +310,7 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) if (!qualityNormals) { // Normalize vertex normals for (int i = 0; i < nb_points; i++) { - gp_Vec& normal = local_normals[i]; + gp_Vec &normal = local_normals[i]; if (normal.SquareMagnitude() > 1.0e-10) { normal.Normalize(); } @@ -335,17 +320,19 @@ int Mesh::extractFaceMesh(const TopoDS_Face& face, bool qualityNormals) extractEdgeFromFace(face, triangulation, translationTable); return 1; } -int Mesh::extractEdgeFromFace(const TopoDS_Face& face, const occHandle(Poly_Triangulation)& triangulation, const std::vector& translationMap) -{ +int Mesh::extractEdgeFromFace(const TopoDS_Face &face, + const occHandle(Poly_Triangulation) & + triangulation, + const std::vector &translationMap) { TopExp_Explorer ex0, ex1; for (ex0.Init(face, TopAbs_WIRE); ex0.More(); ex0.Next()) { - const TopoDS_Wire& wire = TopoDS::Wire(ex0.Current()); + const TopoDS_Wire &wire = TopoDS::Wire(ex0.Current()); for (ex1.Init(wire, TopAbs_EDGE); ex1.More(); ex1.Next()) { - const TopoDS_Edge& edge = TopoDS::Edge(ex1.Current()); + const TopoDS_Edge &edge = TopoDS::Edge(ex1.Current()); // skip degenerated edge if (BRep_Tool::Degenerated(edge)) @@ -361,10 +348,11 @@ int Mesh::extractEdgeFromFace(const TopoDS_Face& face, const occHandle(Poly_Tria } return 0; } -int Mesh::extractEdge(const TopoDS_Edge& edge, const occHandle(Poly_Triangulation)& triangulation, const std::vector& translationMap) -{ +int Mesh::extractEdge(const TopoDS_Edge &edge, + const occHandle(Poly_Triangulation) & triangulation, + const std::vector &translationMap) { - auto& hashMap = this->_edgeHashMap; + auto &hashMap = this->_edgeHashMap; int hash = edge.HashCode(std::numeric_limits::max()); if (hashMap.end() != hashMap.find(hash)) { @@ -372,7 +360,8 @@ int Mesh::extractEdge(const TopoDS_Edge& edge, const occHandle(Poly_Triangulatio } TopLoc_Location loc; - occHandle(Poly_PolygonOnTriangulation) edgepoly = BRep_Tool::PolygonOnTriangulation(edge, triangulation, loc); + occHandle(Poly_PolygonOnTriangulation) edgepoly = + BRep_Tool::PolygonOnTriangulation(edge, triangulation, loc); if (edgepoly.IsNull()) { return 0; } @@ -381,7 +370,7 @@ int Mesh::extractEdge(const TopoDS_Edge& edge, const occHandle(Poly_Triangulatio this->_edgeRanges.push_back(lastSize); - const TColStd_Array1OfInteger& edgeind = edgepoly->Nodes(); + const TColStd_Array1OfInteger &edgeind = edgepoly->Nodes(); for (int i = edgeind.Lower(); i <= edgeind.Upper(); i++) { const unsigned int idx = (unsigned int)edgeind(i) - 1; this->_edgeIndices.push_back(translationMap[idx]); @@ -390,61 +379,68 @@ int Mesh::extractEdge(const TopoDS_Edge& edge, const occHandle(Poly_Triangulatio return 1; } -template -void UpdateExternalArray(v8::Local& pThis, const char* name, const T* data, size_t _length) -{ +template +void UpdateExternalArray(v8::Local &pThis, const char *name, + const T *data, size_t _length) { v8::MaybeLocal arr = _makeTypedArray(data, (int)_length); - Nan::Set(pThis,Nan::New(name).ToLocalChecked(), arr.ToLocalChecked()); + Nan::Set(pThis, Nan::New(name).ToLocalChecked(), arr.ToLocalChecked()); } -void Mesh::updateJavaScriptArray() -{ +void Mesh::updateJavaScriptArray() { + assert(sizeof(_triangles[0]) == sizeof(int) * 3); v8::Local pThis = NanObjectWrapHandle(this); - UpdateExternalArray(pThis, "vertices", &_vertices.data()[0].x, _vertices.size() * 3); - UpdateExternalArray(pThis, "normals", &_normals.data()[0].x, _normals.size() * 3); - UpdateExternalArray(pThis, "triangles", &_triangles.data()[0].i, _triangles.size() * 3); - UpdateExternalArray(pThis, "triangleNormals", &_triangles_normals.data()[0].i, _triangles_normals.size() * 3); - - UpdateExternalArray(pThis, "faceRanges", &_faceRanges.data()[0], _faceRanges.size()); - UpdateExternalArray(pThis, "edgeIndices", &_edgeIndices.data()[0], _edgeIndices.size()); - UpdateExternalArray(pThis, "edgeRanges", &_edgeRanges.data()[0], _edgeRanges.size()); + UpdateExternalArray(pThis, "vertices", &_vertices.data()[0].x, + _vertices.size() * 3); + UpdateExternalArray(pThis, "normals", &_normals.data()[0].x, + _normals.size() * 3); + UpdateExternalArray(pThis, "triangles", &_triangles.data()[0].i, + _triangles.size() * 3); + UpdateExternalArray(pThis, "triangleNormals", &_triangles_normals.data()[0].i, + _triangles_normals.size() * 3); + + UpdateExternalArray(pThis, "faceRanges", &_faceRanges.data()[0], + _faceRanges.size()); + UpdateExternalArray(pThis, "edgeIndices", &_edgeIndices.data()[0], + _edgeIndices.size()); + UpdateExternalArray(pThis, "edgeRanges", &_edgeRanges.data()[0], + _edgeRanges.size()); } - template -void makeTT(const std::vector& arr,uint32_t start,uint32_t length,std::vector& indexes) -{ - indexes.clear(); - indexes.reserve(length * 3); - for (uint32_t i = 0; i < length; i++) { - indexes.push_back((uintX_t)arr[start + i].i); - indexes.push_back((uintX_t)arr[start + i].j); - indexes.push_back((uintX_t)arr[start + i].k); - } +void makeTT(const std::vector &arr, uint32_t start, uint32_t length, + std::vector &indexes) { + + indexes.clear(); + indexes.reserve(length * 3); + for (uint32_t i = 0; i < length; i++) { + indexes.push_back((uintX_t)arr[start + i].i); + indexes.push_back((uintX_t)arr[start + i].j); + indexes.push_back((uintX_t)arr[start + i].k); + } } template -void makeTT(const std::vector& arr,uint32_t start,uint32_t length,std::vector& indexes) -{ - indexes.clear(); - indexes.reserve(length); - for (uint32_t i = 0; i < length; i++) { - indexes.push_back(arr[start + i]); - } +void makeTT(const std::vector &arr, uint32_t start, uint32_t length, + std::vector &indexes) { + indexes.clear(); + indexes.reserve(length); + for (uint32_t i = 0; i < length; i++) { + indexes.push_back(arr[start + i]); + } } #include "Face.h" -NAN_METHOD(Mesh::getFaceTriangles) -{ - Mesh* pThis = UNWRAP(Mesh); - Face* pFace = 0; +NAN_METHOD(Mesh::getFaceTriangles) { + Mesh *pThis = UNWRAP(Mesh); + Face *pFace = 0; if (info.Length() == 1 && info[0]->IsObject()) { - pFace = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + pFace = Nan::ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); } if (!pFace) { return Nan::ThrowError("expecting one argument : face"); } - auto& hashMap = pThis->_faceHashMap; + auto &hashMap = pThis->_faceHashMap; int hash = pFace->m_face.HashCode(std::numeric_limits::max()); // find hash in edgehash.push_back(hash); if (hashMap.end() == hashMap.find(hash)) { @@ -457,32 +453,32 @@ NAN_METHOD(Mesh::getFaceTriangles) if (pThis->numVertices() <= 255) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint8Array(indexes.data(), length * 3)); return; } if (pThis->numVertices() <= 65535) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint16Array(indexes.data(), length * 3)); return; } std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint32Array(indexes.data(), length * 3)); } -NAN_METHOD(Mesh::getFaceTriangleNormals) -{ - Mesh* pThis = UNWRAP(Mesh); - Face* pFace = 0; +NAN_METHOD(Mesh::getFaceTriangleNormals) { + Mesh *pThis = UNWRAP(Mesh); + Face *pFace = 0; if (info.Length() == 1 && info[0]->IsObject()) { - pFace = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + pFace = Nan::ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); } if (!pFace) { return Nan::ThrowError("expecting one argument : face"); } - auto& hashMap = pThis->_faceHashMap; + auto &hashMap = pThis->_faceHashMap; int hash = pFace->m_face.HashCode(std::numeric_limits::max()); // find hash in edgehash.push_back(hash); if (hashMap.end() == hashMap.find(hash)) { @@ -496,18 +492,18 @@ NAN_METHOD(Mesh::getFaceTriangleNormals) if (pThis->numNormals() <= 255) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint8Array(indexes.data(), length * 3)); return; } if (pThis->numNormals() <= 65535) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint16Array(indexes.data(), length * 3)); return; } std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint32Array(indexes.data(), length * 3)); } #include "Edge.h" @@ -515,12 +511,12 @@ NAN_METHOD(Mesh::getFaceTriangleNormals) * @param edge {Edge} the edge from which we want to get the indices * @return {Int32Array} */ -NAN_METHOD(Mesh::getEdgeIndices) -{ - Mesh* pThis = UNWRAP(Mesh); - Edge* pEdge = 0; +NAN_METHOD(Mesh::getEdgeIndices) { + Mesh *pThis = UNWRAP(Mesh); + Edge *pEdge = 0; if (info.Length() == 1 && info[0]->IsObject()) { - pEdge = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + pEdge = Nan::ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); } if (!pEdge) { return Nan::ThrowError("expecting one argument : edge"); @@ -528,7 +524,7 @@ NAN_METHOD(Mesh::getEdgeIndices) int hash = pEdge->m_edge.HashCode(std::numeric_limits::max()); - auto& hashMap = pThis->_edgeHashMap; + auto &hashMap = pThis->_edgeHashMap; // find hash in edgehash.push_back(hash); if (hashMap.end() == hashMap.find(hash)) { @@ -540,42 +536,37 @@ NAN_METHOD(Mesh::getEdgeIndices) uint32_t length = pThis->_edgeRanges[index + 1]; const auto arr = pThis->_edgeIndices; - if (pThis->numVertices() <= 255) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint8Array(indexes.data(), length)); return; } if (pThis->numVertices() <= 65535) { std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint16Array(indexes.data(), length)); return; } std::vector indexes; - makeTT(arr,start,length,indexes); + makeTT(arr, start, length, indexes); info.GetReturnValue().Set(makeUint32Array(indexes.data(), length)); - } -float square(float b) -{ - return b*b; -} +float square(float b) { return b * b; } -float distance2(const Coord3f& a, const Coord3f& b) -{ +float distance2(const Coord3f &a, const Coord3f &b) { return square(a.x - b.x) + square(a.y - b.y) + square(a.y - b.y); } -int deprecated_findPt(const std::vector& arrayPts, const Coord3f pt, double tolerance) -{ +int deprecated_findPt(const std::vector &arrayPts, const Coord3f pt, + double tolerance) { - double tolerance2 = tolerance*tolerance; + double tolerance2 = tolerance * tolerance; int i = 0; - for (std::vector::const_iterator it = arrayPts.begin(); it != arrayPts.end(); it++) { - const Coord3f& point = (*it); + for (std::vector::const_iterator it = arrayPts.begin(); + it != arrayPts.end(); it++) { + const Coord3f &point = (*it); if (distance2(point, pt) < tolerance2) { return i; } @@ -583,9 +574,6 @@ int deprecated_findPt(const std::vector& arrayPts, const Coord3f pt, do } return -1; } -void Mesh::optimize() -{ - updateJavaScriptArray(); -} +void Mesh::optimize() { updateJavaScriptArray(); } // see also : // https://github.com/FreeCAD/FreeCAD/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Adaptive1D.cpp diff --git a/src/Mesh.h b/src/Mesh.h index 0d64a87..38edc05 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -1,16 +1,17 @@ #pragma once -#include "NodeV8.h" #include "GeometryBuilder.h" -#include +#include "NodeV8.h" #include +#include struct Coord3f { - float x; - float y; - float z; - Coord3f(float _x, float _y, float _z) :x(_x), y(_y), z(_z) {} - Coord3f() :x(0.0), y(0.0), z(0.0) {} - Coord3f(const gp_Vec& vec) : x((float)vec.X()), y((float)vec.Y()), z((float)vec.Z()) {} + float x; + float y; + float z; + Coord3f(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} + Coord3f() : x(0.0), y(0.0), z(0.0) {} + Coord3f(const gp_Vec &vec) + : x((float)vec.X()), y((float)vec.Y()), z((float)vec.Z()) {} }; struct Triangle3i { @@ -18,70 +19,65 @@ struct Triangle3i { uint32_t j; uint32_t k; }; -class Mesh : public Nan::ObjectWrap { - int extractEdge(const TopoDS_Edge& edge, const occHandle(Poly_Triangulation)& triangulation, const std::vector& translationMap); - int extractEdgeFromFace(const TopoDS_Face& face, const occHandle(Poly_Triangulation)& triangulation, const std::vector& translationMap); +class Mesh : public Nan::ObjectWrap { + int extractEdge(const TopoDS_Edge &edge, + const occHandle(Poly_Triangulation) & triangulation, + const std::vector &translationMap); + int extractEdgeFromFace(const TopoDS_Face &face, + const occHandle(Poly_Triangulation) & triangulation, + const std::vector &translationMap); + public: - Mesh(); - int extractFaceMesh(const TopoDS_Face& face, bool qualityNormals); + Mesh(); + int extractFaceMesh(const TopoDS_Face &face, bool qualityNormals); - void optimize(); + void optimize(); - static NAN_METHOD(New); + static NAN_METHOD(New); - static NAN_METHOD(getEdgeIndices); - static NAN_METHOD(getFaceTriangles); - static NAN_METHOD(getFaceTriangleNormals); + static NAN_METHOD(getEdgeIndices); + static NAN_METHOD(getFaceTriangles); + static NAN_METHOD(getFaceTriangleNormals); - static void Init(v8::Local target); + static NAN_MODULE_INIT(Init); private: + // a set of points to support edges and triangles + std::vector _vertices; + // a set of normals + std::vector _normals; - // a set of points to support edges and triangles - std::vector _vertices; - // a set of normals - std::vector _normals; + std::vector _triangles; + std::vector _triangles_normals; - std::vector _triangles; - std::vector _triangles_normals; + std::vector _edgeIndices; - std::vector _edgeIndices; + // an index to quickly find the index of a vertex given its x,y,z coordinates + std::map _mapVertices; + // an index to quickly find the index of a vertex given its x,y,z coordinates + std::map _mapNormals; - // an index to quickly find the index of a vertex given its x,y,z coordinates - std::map _mapVertices; - // an index to quickly find the index of a vertex given its x,y,z coordinates - std::map _mapNormals; + // ----------------------------------------------------------------------- + std::vector _faceRanges; // [start(0),nb(0),....,start(i),nb(i)] + std::map _faceHashMap; // hash,index + std::vector _edgeRanges; // [start(0),nb(0),....,start(i),nb(i)] + std::map _edgeHashMap; // hash,index - // ----------------------------------------------------------------------- - std::vector _faceRanges; // [start(0),nb(0),....,start(i),nb(i)] - std::map _faceHashMap; // hash,index + friend class MeshOptimizer; + uint32_t push_point(const Coord3f &point); + uint32_t push_normal(const Coord3f &normal); + void updateJavaScriptArray(); - std::vector _edgeRanges; // [start(0),nb(0),....,start(i),nb(i)] - std::map _edgeHashMap; // hash,index - - friend class MeshOptimizer; - uint32_t push_point(const Coord3f& point); - uint32_t push_normal(const Coord3f& normal); - void updateJavaScriptArray(); public: - static Nan::Persistent _template; - - uint32_t numTriangles() { - return (uint32_t) _triangles.size(); - } - - int32_t numVertices() { - return (int32_t) _vertices.size(); - } - - int32_t numNormals() { - return (int32_t) _normals.size(); - } - - int32_t numEdges() { - return (int32_t) _edgeIndices.size()>>1; - } - void setErrorMessage(const char* message) { - }; + static Nan::Persistent _template; + + uint32_t numTriangles() { return (uint32_t)_triangles.size(); } + + int32_t numVertices() { return (int32_t)_vertices.size(); } + + int32_t numNormals() { return (int32_t)_normals.size(); } + + int32_t numEdges() { return (int32_t)_edgeIndices.size() >> 1; } + void setErrorMessage(const char *message){}; }; diff --git a/src/NodeV8.h b/src/NodeV8.h index 7ca1632..68a4005 100644 --- a/src/NodeV8.h +++ b/src/NodeV8.h @@ -1,9 +1,11 @@ // NodeV8 #pragma once #ifdef _MSC_VER -#pragma warning(disable:4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc -#pragma warning(disable:4506) -#pragma warning(disable:4355) // warning C4355: 'this' : used in base member initializer list +#pragma warning(disable : 4530) // C++ exception handler used, but unwind + // semantics are not enabled. Specify /EHsc +#pragma warning(disable : 4506) +#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member + // initializer list #endif @@ -12,18 +14,17 @@ #undef Handle #endif -#include -#include #include +#include +#include #ifdef Handle_was_defined -#define Handle(ClassName) Handle_##ClassName +#define Handle(ClassName) Handle_##ClassName #endif -#define occHandle(ClassName) Handle_##ClassName -//xx using namespace v8; +#define occHandle(ClassName) Handle_##ClassName +// xx using namespace v8; - -template bool IsInstanceOf(Nan::MaybeLocal obj) { +template bool IsInstanceOf(Nan::MaybeLocal obj) { if (obj.IsEmpty()) { return false; } @@ -33,92 +34,101 @@ template bool IsInstanceOf(Nan::MaybeLocal obj) { /* template bool IsInstanceOf(Nan::Local obj) { - v8::Local _template = Nan::New(T::_template); - return _template->HasInstance(obj); + v8::Local _template = Nan::New(T::_template); + return _template->HasInstance(obj); } template bool IsInstanceOf(Nan::Handle obj) { - v8::Local _template = Nan::New(T::_template); - return _template->HasInstance(obj); + v8::Local _template = Nan::New(T::_template); + return _template->HasInstance(obj); } */ +// template v8::Local c(T e) { return v8::Local(e); } +template v8::Local c(v8::Local e) { return e; } +inline v8::Local c(Nan::MaybeLocal e) { + return e.ToLocalChecked(); +} +template NAN_GETTER(ee) { + if (info.This().IsEmpty()) { + info.GetReturnValue().SetUndefined(); + return; + } -//template v8::Local c(T e) { return v8::Local(e); } -template v8::Local c(v8::Local e) { return e; } -inline v8::Local c(Nan::MaybeLocal e) { return e.ToLocalChecked(); } - - - -template -NAN_GETTER(ee) -{ - //xx NanScope(); - if (info.This().IsEmpty() ) { - info.GetReturnValue().SetUndefined(); - return; - } - - if (info.This()->InternalFieldCount() == 0 ) { - info.GetReturnValue().SetUndefined(); - return; - } - - T* obj = Nan::ObjectWrap::Unwrap(info.This()); - - try { + if (info.This()->InternalFieldCount() == 0) { + info.GetReturnValue().SetUndefined(); + return; + } - auto val = (obj->*func)(); - info.GetReturnValue().Set(c(Nan::New(val)) ); + T *obj = Nan::ObjectWrap::Unwrap(info.This()); - } catch(...) { - return Nan::ThrowError("exception caught in C++ code"); - } + try { + auto val = (obj->*func)(); + info.GetReturnValue().Set(c(Nan::New(val))); + } catch (...) { + return Nan::ThrowError("exception caught in C++ code"); + } } // proto is an ObjectTemplate -#define EXPOSE_METHOD(ClassName,staticMethod) \ - Nan::SetTemplate(proto,#staticMethod, Nan::New(staticMethod)) +#define EXPOSE_METHOD(ClassName, staticMethod) \ + Nan::SetTemplate(proto, #staticMethod, \ + Nan::New(staticMethod)) // proto->Set(#staticMethod,v8::FunctionTemplate::New(staticMethod)); // NODE_SET_PROTOTYPE_METHOD(proto,#staticMethod,staticMethod); -//FunctionTemplate::New(staticMethod)->GetFunction()); +// FunctionTemplate::New(staticMethod)->GetFunction()); // proto->Set(Nan::New(#staticMethod),FunctionTemplate::New(staticMethod)->GetFunction()); -#define __EXPOSE_READ_ONLY_PROPERTY(element,staticMethod,name) \ - Nan::SetAccessor(element,Nan::New(#name).ToLocalChecked(), &staticMethod, 0,v8::Local(),v8::DEFAULT,v8::ReadOnly) - -#define EXPOSE_READ_ONLY_PROPERTY(staticMethod,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto,staticMethod,name) - -#define EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee< ClassName, v8::Boolean, bool, &ClassName::name>) , name ) - -#define EXPOSE_READ_ONLY_PROPERTY_INTEGER(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee),name) - -#define EXPOSE_READ_ONLY_PROPERTY_UINT32(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee),name) - -#define EXPOSE_READ_ONLY_PROPERTY_DOUBLE(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee),name) - -#define EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee),name) - -#define EXPOSE_READ_ONLY_PROPERTY_OBJECT(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(proto, (ee,&ClassName::name>),name) - - -#define REXPOSE_READ_ONLY_PROPERTY_DOUBLE(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(info.This(),(ee< ClassName, v8::Number, double, &ClassName::name>) , name ) -#define REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(info.This(),(ee< ClassName, v8::Boolean, bool, &ClassName::name>) , name ) -#define REXPOSE_READ_ONLY_PROPERTY_INTEGER(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(info.This(), (ee),name) -#define REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(ClassName,name) \ - __EXPOSE_READ_ONLY_PROPERTY(info.This(), (ee),name) +#define __EXPOSE_READ_ONLY_PROPERTY(element, staticMethod, name) \ + Nan::SetAccessor(element, Nan::New(#name).ToLocalChecked(), &staticMethod, \ + 0, v8::Local(), v8::DEFAULT, v8::ReadOnly) + +#define EXPOSE_READ_ONLY_PROPERTY(staticMethod, name) \ + __EXPOSE_READ_ONLY_PROPERTY(proto, staticMethod, name) + +#define EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, (ee), name) + +#define EXPOSE_READ_ONLY_PROPERTY_INTEGER(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, (ee), name) + +#define EXPOSE_READ_ONLY_PROPERTY_UINT32(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, (ee), name) + +#define EXPOSE_READ_ONLY_PROPERTY_DOUBLE(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, (ee), name) + +#define EXPOSE_READ_ONLY_PROPERTY_CONST_STRING(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, (ee), \ + name) + +#define EXPOSE_READ_ONLY_PROPERTY_OBJECT(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + proto, \ + (ee, &ClassName::name>), \ + name) + +#define REXPOSE_READ_ONLY_PROPERTY_DOUBLE(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + info.This(), (ee), \ + name) +#define REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + info.This(), (ee), name) +#define REXPOSE_READ_ONLY_PROPERTY_INTEGER(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + info.This(), (ee), name) +#define REXPOSE_READ_ONLY_PROPERTY_CONST_STRING(ClassName, name) \ + __EXPOSE_READ_ONLY_PROPERTY( \ + info.This(), \ + (ee), name) /** * Extracts a C string from a V8 Utf8Value. * @@ -126,56 +136,54 @@ NAN_GETTER(ee) * const char* cstr = ToCString(str); * */ -inline const char* ToCString(const v8::String::Utf8Value& value) -{ - return *value ? *value : ""; +inline const char *ToCString(const v8::String::Utf8Value &value) { + return *value ? *value : ""; } // TO DO => SCRAP -#define _NAN_METHOD_ARGS const Nan::FunctionCallbackInfo& info +#define _NAN_METHOD_ARGS const Nan::FunctionCallbackInfo &info #define NanObjectWrapHandle(t) (t->handle()) - -#define CHECK_THIS_DEFINED(CLASS) \ - if ( info.This().IsEmpty()) { \ - return Nan::ThrowError("Internal error: 'this' is not defined"); \ - } \ - if (info.This()->InternalFieldCount() == 0 ) { \ - return; \ - return Nan::ThrowError("Internal error: 'this' is not a wrapped object"); \ - } \ - if (!ObjectWrap::Unwrap(info.This())) { \ - return Nan::ThrowError("Internal error: 'this' is of wrong type in"); \ +#define CHECK_THIS_DEFINED(CLASS) \ + if (info.This().IsEmpty()) { \ + return Nan::ThrowError("Internal error: 'this' is not defined"); \ + } \ + if (info.This()->InternalFieldCount() == 0) { \ + return; \ + return Nan::ThrowError("Internal error: 'this' is not a wrapped object"); \ + } \ + if (!ObjectWrap::Unwrap(info.This())) { \ + return Nan::ThrowError("Internal error: 'this' is of wrong type in"); \ } -#define UNWRAP(CLASS) \ - 0; \ - CHECK_THIS_DEFINED(CLASS) \ - v8::Local pJhis = info.This(); \ - if ( pJhis.IsEmpty() || !IsInstanceOf(pJhis)) { \ - return Nan::ThrowError("invalid object"); \ - } \ +#define UNWRAP(CLASS) \ + 0; \ + CHECK_THIS_DEFINED(CLASS) \ + v8::Local pJhis = info.This(); \ + if (pJhis.IsEmpty() || !IsInstanceOf(pJhis)) { \ + return Nan::ThrowError("invalid object"); \ + } \ pThis = Nan::ObjectWrap::Unwrap(pJhis); - // catch an open cascade exception and turn it into a Nan Execption -#define CATCH_AND_RETHROW(message) \ - catch(Standard_Failure& e) { \ - Standard_CString msg = e.GetMessageString(); \ - std::cerr << "C++ exception in OCC "<< msg << " " << message << std::endl; \ - if (msg == NULL || strlen(msg) < 1) { \ - msg = message; \ - } \ - Nan::ThrowError(msg); \ - } \ - -#define CATCH_AND_RETHROW2(message) \ - catch(Standard_Failure& ) { \ - info.GetReturnValue().Set(v8::Local()); \ - return Nan::ThrowError(""); \ +#define CATCH_AND_RETHROW(message) \ + catch (Standard_Failure & e) { \ + Standard_CString msg = e.GetMessageString(); \ + std::cerr << "C++ exception in OCC " << msg << " " << message \ + << std::endl; \ + if (msg == NULL || strlen(msg) < 1) { \ + msg = message; \ + } \ + Nan::ThrowError(msg); \ + } + +#define CATCH_AND_RETHROW2(message) \ + catch (Standard_Failure &) { \ + info.GetReturnValue().Set(v8::Local()); \ + return Nan::ThrowError(message)); \ } -#define CATCH_AND_RETHROW_NO_RETURN(message) \ - catch(Standard_Failure& ) { \ - Nan::ThrowError(message); \ +#define CATCH_AND_RETHROW_NO_RETURN(message) \ + catch (Standard_Failure &) { \ + Nan::ThrowError(message); \ } diff --git a/src/OCC.h b/src/OCC.h index 978db6e..1704f7f 100644 --- a/src/OCC.h +++ b/src/OCC.h @@ -3,57 +3,56 @@ #include -#include "BSplCLib.hxx" +#include "BSplCLib.hxx" #include -#include #include +#include -//#include -#include +// #include #include +#include -#include -#include #include #include #include +#include #include -#include #include +#include #include #include #include #include #include +#include -#include -#include #include +#include +#include #include #include #include +#include #include #include #include -#include #include -#include -#include #include -#include +#include #include +#include #include +#include - -#include #include +#include #include -//xx #include +// xx #include #include #include @@ -62,63 +61,63 @@ #include #include -#include +#include #include +#include #include -#include #include -#include #include +#include -#include #include #include #include #include +#include #include - - - -#include #include +#include #include #include #include - -#include #include +#include #include "Message_ProgressIndicator.hxx" -//xx #include +// xx #include -#include #include #include +#include -#include #include +#include #include -#include #include +#include -//xx #include +#include +#include +#include +#include +#include +// xx #include // #include #include #include -#include #include #include -//xx #include +// xx #include #include #include @@ -126,53 +125,59 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include #include +#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//xx #include -//xx #include -//xx #include -//xx #include +#include +// xx #include +// xx #include +// xx #include +// xx #include #include -#include -#include #include #include +#include +#include +#include // Compatibility 6.5 and above -#if (OCC_VERSION_MAJOR * 10 + OCC_VERSION_MINOR ) < 66 +#if (OCC_VERSION_MAJOR * 10 + OCC_VERSION_MINOR) < 66 // this makes some adjustemnts to make sure node-occ can be // build with older version of OCC. #include #define BOPAlgo_Operation BOP_Operation #define BOPAlgo_SECTION BOP_SECTION -#define BOPAlgo_COMMON BOP_COMMON -#define BOPAlgo_FUSE BOP_FUSE -#define BOPAlgo_CUT BOP_CUT -#define BOPAlgo_CUT21 BOP_CUT21 +#define BOPAlgo_COMMON BOP_COMMON +#define BOPAlgo_FUSE BOP_FUSE +#define BOPAlgo_CUT BOP_CUT +#define BOPAlgo_CUT21 BOP_CUT21 #define BOPAlgo_UNKNOWN BOP_UNKNOWN -#define OUTER_SHELL(x) BRepTools::OuterShell(x) +#define OUTER_SHELL(x) BRepTools::OuterShell(x) #else #include -#define OUTER_SHELL(x) BRepClass3d::OuterShell(x) +#define OUTER_SHELL(x) BRepClass3d::OuterShell(x) #endif +#include +#include +#include +#include + #undef Handle diff --git a/src/Point3Wrap.cc b/src/Point3Wrap.cc index 988c172..9427b00 100644 --- a/src/Point3Wrap.cc +++ b/src/Point3Wrap.cc @@ -3,18 +3,15 @@ Nan::Persistent Point3Wrap::_template; -class Point3Wrap1 : public Point3Wrap -{ +class Point3Wrap1 : public Point3Wrap { gp_XYZ _p; + public: - Point3Wrap1(double x, double y, double z) :_p(x, y, z) {}; - virtual const gp_XYZ get() const { - return _p; - } + Point3Wrap1(double x, double y, double z) : _p(x, y, z){}; + virtual const gp_XYZ get() const { return _p; } }; // Methods exposed to JavaScripts -NAN_METHOD(Point3Wrap::New) -{ +NAN_METHOD(Point3Wrap::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Point() to construct a Point"); } @@ -24,39 +21,36 @@ NAN_METHOD(Point3Wrap::New) ReadDouble(info[1], y); ReadDouble(info[2], z); - Point3Wrap* pThis = new Point3Wrap1(x,y,z); + Point3Wrap *pThis = new Point3Wrap1(x, y, z); pThis->Wrap(info.This()); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap,x); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap,y); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap,z); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap, x); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap, y); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Point3Wrap, z); info.GetReturnValue().Set(info.This()); } -NAN_METHOD(Point3Wrap::asArray) -{ - Point3Wrap* pThis = Nan::ObjectWrap::Unwrap(info.This()); +NAN_METHOD(Point3Wrap::asArray) { + Point3Wrap *pThis = Nan::ObjectWrap::Unwrap(info.This()); v8::Local arr = Nan::New(3); - Nan::Set(arr,0, Nan::New(pThis->x())); - Nan::Set(arr,1, Nan::New(pThis->y())); - Nan::Set(arr,2, Nan::New(pThis->z())); + Nan::Set(arr, 0, Nan::New(pThis->x())); + Nan::Set(arr, 1, Nan::New(pThis->y())); + Nan::Set(arr, 2, Nan::New(pThis->z())); info.GetReturnValue().Set(arr); } -NAN_METHOD(Point3Wrap::equals) -{ +NAN_METHOD(Point3Wrap::equals) { CHECK_THIS_DEFINED(Point3Wrap); - Point3Wrap* pThis = Nan::ObjectWrap::Unwrap(info.This()); + Point3Wrap *pThis = Nan::ObjectWrap::Unwrap(info.This()); if (info.Length() == 1) { gp_Pnt p1; ReadPoint(info[0], &p1); bool isEqual = gp_Pnt(pThis->get()).IsEqual(p1, 0.0000001); return info.GetReturnValue().Set(isEqual); - } - else if (info.Length() == 2) { + } else if (info.Length() == 2) { gp_Pnt p1; ReadPoint(info[0], &p1); - + double tol; ReadDouble(info[1], tol); @@ -67,14 +61,12 @@ NAN_METHOD(Point3Wrap::equals) Nan::ThrowError("Invalid"); } -// Methods exposed to JavaScripts -void Point3Wrap::Init(v8::Local target) -{ - // Prepare constructor template - v8::Local tpl = Nan::New(Point3Wrap::New); +NAN_MODULE_INIT(Point3Wrap::Init) { + v8::Local tpl = + Nan::New(Point3Wrap::New); tpl->SetClassName(Nan::New("Point3D").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -87,8 +79,7 @@ void Point3Wrap::Init(v8::Local target) EXPOSE_METHOD(Point3Wrap, equals); EXPOSE_METHOD(Point3Wrap, asArray); - - - Nan::Set(target, Nan::New("Point3D").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("Point3D").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } diff --git a/src/Point3Wrap.h b/src/Point3Wrap.h index bb15e48..fab8602 100644 --- a/src/Point3Wrap.h +++ b/src/Point3Wrap.h @@ -6,46 +6,34 @@ class Point3Wrap : public Nan::ObjectWrap { virtual const gp_XYZ get() const = 0; - double x() { - return get().X(); - } - double y() { - return get().Y(); - } - double z() { - return get().Z(); - } + double x() { return get().X(); } + double y() { return get().Y(); } + double z() { return get().Z(); } + public: // Methods exposed to JavaScript static NAN_METHOD(New); static NAN_METHOD(equals); static NAN_METHOD(asArray); - static void Init(v8::Local target); + static NAN_MODULE_INIT(Init); static Nan::Persistent _template; }; +#define TEAROFF_INIT(ACCESSOR) m_##ACCESSOR(*this) - -#define TEAROFF_INIT(ACCESSOR) m_##ACCESSOR(*this) - -template +template class Accessor : public Wrapper { // typedef Accessor<_ThisType, Wrapper,CLASS,ACCESSOR> THIS; - _ThisType& m_parent; + _ThisType &m_parent; public: + Accessor(_ThisType &parent) : m_parent(parent) {} - Accessor(_ThisType& parent) - :m_parent(parent) { - } - - ~Accessor() { - } + ~Accessor() {} - virtual const CLASS get() const { - return (m_parent.*ACCESSOR)(); - } + virtual const CLASS get() const { return (m_parent.*ACCESSOR)(); } static NAN_PROPERTY_GETTER(getter) { if (info.This().IsEmpty()) { @@ -56,36 +44,33 @@ class Accessor : public Wrapper { info.GetReturnValue().SetUndefined(); return; } - _ThisType* pThis = Nan::ObjectWrap::Unwrap<_ThisType>(info.This()); + _ThisType *pThis = Nan::ObjectWrap::Unwrap<_ThisType>(info.This()); info.GetReturnValue().Set(Accessor::NewInstance(*pThis)); } - static v8::Local NewInstance(_ThisType& parent) { + static v8::Local NewInstance(_ThisType &parent) { + Nan::EscapableHandleScope scope; auto f = Nan::GetFunction(Nan::New(Wrapper::_template)).ToLocalChecked(); v8::Local instance = Nan::NewInstance(f).ToLocalChecked(); - + // NewInstance(Nan::GetCurrentContext(),0, 0).ToLocalChecked(); - Accessor* pThis = new Accessor(parent); + Accessor *pThis = new Accessor(parent); pThis->Wrap(instance); - return instance; + return scope.Escape(instance); } }; +#define TEAROFF_POINT(THISTYPE, ACCESSOR, WRAPPER, CLASS) \ + typedef Accessor t##ACCESSOR; -#define TEAROFF_POINT(THISTYPE,ACCESSOR,WRAPPER,CLASS) \ - typedef Accessor t##ACCESSOR; \ - - - -#define EXPOSE_TEAROFF(THISTYPE,ACCESSOR) \ - Nan::SetAccessor(proto, \ - Nan::New(#ACCESSOR).ToLocalChecked(), \ - &t##ACCESSOR::getter, 0,v8::Local(),v8::DEFAULT,(v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)) - - -#define REXPOSE_TEAROFF(THISTYPE,ACCESSOR) \ - Nan::SetAccessor(info.This(), \ - Nan::New(#ACCESSOR).ToLocalChecked(), \ - &t##ACCESSOR::getter, 0,v8::Local(),v8::DEFAULT,v8::ReadOnly) +#define EXPOSE_TEAROFF(THISTYPE, ACCESSOR) \ + Nan::SetAccessor(proto, Nan::New(#ACCESSOR).ToLocalChecked(), \ + &t##ACCESSOR::getter, 0, v8::Local(), \ + v8::DEFAULT, \ + (v8::PropertyAttribute)(v8::ReadOnly | v8::DontDelete)) +#define REXPOSE_TEAROFF(THISTYPE, ACCESSOR) \ + Nan::SetAccessor(info.This(), Nan::New(#ACCESSOR).ToLocalChecked(), \ + &t##ACCESSOR::getter, 0, v8::Local(), \ + v8::DEFAULT, v8::ReadOnly) diff --git a/src/Shape.cc b/src/Shape.cc index c0f6b96..9f50f00 100644 --- a/src/Shape.cc +++ b/src/Shape.cc @@ -1,30 +1,17 @@ #include "Shape.h" -#include "Util.h" #include "Transformation.h" +#include "Util.h" #include #include using namespace std; - - - -bool operator == (v8::Local str,const char* value) -{ - return Nan::Equals(str,Nan::New(value).ToLocalChecked()).ToChecked(); +bool operator==(v8::Local str, const char *value) { + return Nan::Equals(str, Nan::New(value).ToLocalChecked()) + .ToChecked(); } +const TopoDS_Shape &Shape::shape() const { return shape_; } -const TopoDS_Shape& Shape::shape() const -{ - return shape_; -} - -void Shape::setShape( const TopoDS_Shape& shape) -{ - shape_ = shape; -} - - - +void Shape::setShape(const TopoDS_Shape &shape) { shape_ = shape; } diff --git a/src/Shape.h b/src/Shape.h index 02a3cbb..7b02c54 100644 --- a/src/Shape.h +++ b/src/Shape.h @@ -1,47 +1,41 @@ #pragma once +#include "Base.h" #include "NodeV8.h" #include "OCC.h" -#include "Base.h" class Shape : public Base { public: - Shape() {}; - virtual ~Shape() {}; + Shape(){}; + virtual ~Shape(){}; protected: - TopoDS_Shape shape_; - + TopoDS_Shape shape_; - - // static NAN_METHOD(ShapeType); - // constructors + // static NAN_METHOD(ShapeType); + // constructors public: - virtual const TopoDS_Shape& shape() const; - virtual void setShape( const TopoDS_Shape&); - - - - void setErrorMessage(const char* message) {}; + virtual const TopoDS_Shape &shape() const; + virtual void setShape(const TopoDS_Shape &); + void setErrorMessage(const char *message){}; }; template -inline v8::Local extract_shapes_as_javascript_array(SHAPE* pThis,TopAbs_ShapeEnum type) { +inline v8::Local +extract_shapes_as_javascript_array(SHAPE *pThis, TopAbs_ShapeEnum type) { + + Nan::EscapableHandleScope scope; TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(pThis->shape(), type, anIndices); - int nb =anIndices.Extent(); + int nb = anIndices.Extent(); v8::Local arr = Nan::New(nb); - for (int i=0; i obj= buildWrapper(anIndices(i+1)); // 1 based !!! - Nan::Set(arr,i,obj); + for (int i = 0; i < nb; i++) { + v8::Local obj = buildWrapper(anIndices(i + 1)); // 1 based !!! + Nan::Set(arr, i, obj); } - return arr; + return scope.Escape(arr); } - - - - diff --git a/src/ShapeFactory.cc b/src/ShapeFactory.cc index 0ced557..ddb54e5 100644 --- a/src/ShapeFactory.cc +++ b/src/ShapeFactory.cc @@ -1,36 +1,45 @@ #include "ShapeFactory.h" -#include "Solid.h" #include "Edge.h" #include "Face.h" -#include "Wire.h" +#include "Solid.h" #include "Util.h" +#include "Wire.h" - -#include #include +#include -#define Primitives_Direction BRepPrim_Direction -#define Primitives_XMin BRepPrim_XMin -#define Primitives_XMax BRepPrim_XMax -#define Primitives_YMin BRepPrim_YMin -#define Primitives_YMax BRepPrim_YMax -#define Primitives_ZMin BRepPrim_ZMin -#define Primitives_ZMax BRepPrim_ZMax +#define Primitives_Direction BRepPrim_Direction +#define Primitives_XMin BRepPrim_XMin +#define Primitives_XMax BRepPrim_XMax +#define Primitives_YMin BRepPrim_YMin +#define Primitives_YMax BRepPrim_YMax +#define Primitives_ZMin BRepPrim_ZMin +#define Primitives_ZMax BRepPrim_ZMax char m(Primitives_Direction p) { - switch (p) { - case Primitives_XMin: return 'x'; - case Primitives_YMin: return 'y'; - case Primitives_ZMin: return 'z'; - case Primitives_XMax: return 'X'; - case Primitives_YMax: return 'Y'; - case Primitives_ZMax: return 'Z'; + switch (p) + { + case Primitives_XMin: + return 'x'; + case Primitives_YMin: + return 'y'; + case Primitives_ZMin: + return 'z'; + case Primitives_XMax: + return 'X'; + case Primitives_YMax: + return 'Y'; + case Primitives_ZMax: + return 'Z'; } return 0; } -static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakeBox& tool) + +static void ReadAx1(v8::Local value, gp_Ax1 *ax1); + +static void registerMakeBoxFaces(Solid *pThis, BRepPrimAPI_MakeBox &tool) { pThis->_registerNamedShape("top", tool.TopFace()); pThis->_registerNamedShape("bottom", tool.BottomFace()); @@ -39,13 +48,16 @@ static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakeBox& tool) pThis->_registerNamedShape("front", tool.FrontFace()); pThis->_registerNamedShape("back", tool.BackFace()); - BRepPrim_GWedge& wedge = tool.Wedge(); + BRepPrim_GWedge &wedge = tool.Wedge(); - for (int _p1 = Primitives_XMin; _p1 <= Primitives_YMax; _p1++) { + for (int _p1 = Primitives_XMin; _p1 <= Primitives_YMax; _p1++) + { Primitives_Direction p1 = (Primitives_Direction)_p1; - for (int _p2 = ((_p1 >> 1) + 1) * 2; _p2 <= Primitives_ZMax; _p2++) { + for (int _p2 = ((_p1 >> 1) + 1) * 2; _p2 <= Primitives_ZMax; _p2++) + { Primitives_Direction p2 = (Primitives_Direction)_p2; - if (wedge.HasEdge(p1, p2)) { + if (wedge.HasEdge(p1, p2)) + { char name[4]; name[0] = 'E'; name[1] = m(p1); @@ -53,9 +65,11 @@ static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakeBox& tool) name[3] = 0; pThis->_registerNamedShape(name, wedge.Edge(p1, p2)); } - for (int _p3 = ((_p2 >> 1) + 1) * 2; _p3 <= Primitives_ZMax; _p3++) { + for (int _p3 = ((_p2 >> 1) + 1) * 2; _p3 <= Primitives_ZMax; _p3++) + { Primitives_Direction p3 = (Primitives_Direction)_p3; - if (wedge.HasVertex(p1, p2, p3)) { + if (wedge.HasVertex(p1, p2, p3)) + { char name[5]; name[0] = 'V'; name[1] = m(p1); @@ -69,34 +83,38 @@ static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakeBox& tool) } } - NAN_METHOD(ShapeFactory::makeBox) { // could be : // 3 numbers dx,dy,dz // 2 points p1,p2 // 1 point + 3 numbers dx,dy,dz - //TODO 1 object with { x: 1,y: 2,z: 3, dw: + // TODO 1 object with { x: 1,y: 2,z: 3, dw: v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); double dx = 10; double dy = 10; double dz = 10; - try { + try + { - if (info.Length() == 3 && info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber()) { + if (info.Length() == 3 && info[0]->IsNumber() && info[1]->IsNumber() && + info[2]->IsNumber()) + { dx = extract_double(info[0]); dy = extract_double(info[1]); dz = extract_double(info[2]); - BRepPrimAPI_MakeBox tool(dx, dy, dz); + BRepPrimAPI_MakeBox tool(dx, dy, dz); pThis->setShape(tool.Shape()); registerMakeBoxFaces(pThis, tool); } - else if (info.Length() == 2) { + else if (info.Length() == 2) + { gp_Pnt p1; ReadPoint(info[0], &p1); @@ -107,10 +125,9 @@ NAN_METHOD(ShapeFactory::makeBox) BRepPrimAPI_MakeBox tool(p1, p2); pThis->setShape(tool.Shape()); registerMakeBoxFaces(pThis, tool); - - } - else if (info.Length() == 3) { + else if (info.Length() == 3) + { gp_Pnt p1; ReadPoint(info[0], &p1); @@ -123,19 +140,19 @@ NAN_METHOD(ShapeFactory::makeBox) pThis->setShape(tool.Shape()); registerMakeBoxFaces(pThis, tool); } - else { + else + { return Nan::ThrowError("invalid arguments in makeBox"); } } - catch (Standard_Failure&) { + catch (Standard_Failure &) + { Nan::ThrowError("cannot build box"); } info.GetReturnValue().Set(pJhis); - } - -static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakePrism& tool) +static void registerMakeBoxFaces(Solid *pThis, BRepPrimAPI_MakePrism &tool) { pThis->_registerNamedShape("bottom", tool.FirstShape()); pThis->_registerNamedShape("top", tool.LastShape()); @@ -143,17 +160,315 @@ static void registerMakeBoxFaces(Solid* pThis, BRepPrimAPI_MakePrism& tool) // const TopTools_ListOfShape& list = tool.Generated(S); } -NAN_METHOD(ShapeFactory::makeVertex) +NAN_METHOD(ShapeFactory::makeVertex) { Vertex::NewInstance(info); } +NAN_METHOD(ShapeFactory::makeWire) { Wire::NewInstance(info); } +NAN_METHOD(ShapeFactory::makeFace) { Face::NewInstance(info); } + +template +void addElement(T info, BRepOffsetAPI_ThruSections &mkThruSections) +{ + Edge *edge = DynamicCast(info); + Wire *wire = DynamicCast(info); + + if (wire) + { + mkThruSections.AddWire(wire->wire()); + } + else + { + auto mesg = std::string("invalid argument: expecting a Wire or an Edge"); + Nan::ThrowError(mesg.c_str()); + } +} + +NAN_METHOD(ShapeFactory::makeSolidThruSections) +{ + v8::Local pJhis = Solid::NewInstance(); + try + { + const Standard_Boolean isSolid = true; + const Standard_Boolean ruled = true; + const Standard_Real pres3d = 1.0e-06; + BRepOffsetAPI_ThruSections thruSection(isSolid, ruled, pres3d); + + v8::Local arr = v8::Local::Cast(info[0]); + + for (int i = 0; i < arr->Length(); i++) + { + auto e = Nan::Get(arr, i).ToLocalChecked(); + Wire *wire = DynamicCast(e); + Edge *edge = DynamicCast(e); + + if (wire) + { + thruSection.AddWire(wire->wire()); + } + else if (edge) + { + auto wire_2 = BRepBuilderAPI_MakeWire(edge->edge()).Wire(); + thruSection.AddWire(wire_2); + } + else + { + auto mesg = + std::string("invalid argument: expecting a Wire or an Edge"); + Nan::ThrowError(mesg.c_str()); + } + } + thruSection.Build(); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + pThis->setShape(thruSection.Shape()); + } + CATCH_AND_RETHROW("Failed to create a solid thru sections"); + info.GetReturnValue().Set(pJhis); +} + +Base *GetBaseShape(v8::Local arg) +{ + auto vertex = DynamicCast(arg); + if (vertex) + return vertex; + auto edge = DynamicCast(arg); + if (edge) + return edge; + auto wire = DynamicCast(arg); + if (wire) + return wire; + auto face = DynamicCast(arg); + if (face) + return face; + return 0; +} +NAN_METHOD(ShapeFactory::makeRevol) { - Vertex::NewInstance(info); + v8::Local pJhis = Solid::NewInstance(); + try + { + if (info.Length() != 2 && info.Length() != 3) + { + return Nan::ThrowError( + "invalid arguments : expecting ,,[angleInDregree]"); + } + + Base *shape = GetBaseShape(info[0]); + if (!shape) + { + return Nan::ThrowError("Expecting a |||"); + } + gp_Ax1 axis; + ReadAx1(info[1], &axis); + + double angleInDegree = 360; + ReadDouble(info[2], angleInDegree); + + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + if (angleInDegree == 360) + { + BRepPrimAPI_MakeRevol tool(shape->shape(), axis); + tool.Build(); + pThis->setShape(tool.Shape()); + } + else + { + BRepPrimAPI_MakeRevol tool(shape->shape(), axis, angleInDegree); + tool.Build(); + pThis->setShape(tool.Shape()); + // registerXXXXFaces(pThis, prismMaker); + } + /** + * Vertex -> Edge. + * Edge -> Face. + * Wire -> Shell. + * Face -> Solid. + * Shell -> CompSolid. + */ + } + CATCH_AND_RETHROW("Failed to create pipe "); + info.GetReturnValue().Set(pJhis); } -NAN_METHOD(ShapeFactory::makeWire) +NAN_METHOD(ShapeFactory::makePipe) { - Wire::NewInstance(info); + if (info.Length() != 2) + { + return Nan::ThrowError("invalid arguments : expecting " + "connectionWire, wire1, wire2"); + } + v8::Local pJhis = Solid::NewInstance(); + try + { + Wire *connectionWire = DynamicCast(info[0]); + Wire *profile = DynamicCast(info[1]); + + BRepOffsetAPI_MakePipe tool(connectionWire->wire(), profile->wire()); + + tool.Build(); + + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + + // auto listOfShapes = piper.Generated(); + pThis->setShape(tool.Shape()); + // registerXXXXFaces(pThis, prismMaker); + } + CATCH_AND_RETHROW("Failed to create pipe "); + info.GetReturnValue().Set(pJhis); } -NAN_METHOD(ShapeFactory::makeFace) + +#define PARAM(paramsAsObject,prop) Nan::Get(paramsAsObject, Nan::New(prop).ToLocalChecked()).ToLocalChecked() + +NAN_METHOD(ShapeFactory::makePipeShell) { - Face::NewInstance(info); + + /** + * { + * wire: Wire | Wire[], + * spineSupport: Wiret + * transitionMode: "transformed" | "round" | "right" + * auxilaryCurve: + * solid: boolean + * // advanced + * mode: enum { + * Frenet // Boolean => SetMode(isFrenet); + * }: + * maxDegree?: number; + * maxSegment?: number; + * forceApproxC1?: boolean; + * } + */ + + std::vector auxWires; + + v8::Local params = info[0]; + if (params.IsEmpty() || !params->IsObject()) + { + return Nan::ThrowError("expecting parameters object "); + } + + Nan::HandleScope scope; + v8::Local paramsAsObject = + Nan::To(params).ToLocalChecked(); + + auto propIsFrenet = PARAM(paramsAsObject,"isFrenet"); + auto propSolid = PARAM(paramsAsObject, "solid"); + auto propAuxilaryCurve = PARAM(paramsAsObject,"auxilaryCurve"); + auto propWire = PARAM(paramsAsObject,"wire"); + auto propWires = PARAM(paramsAsObject, "wires"); + auto propSpineSupport = PARAM(paramsAsObject, "spineSupport"); + + + Wire *wire = DynamicCast(propWire); + if (!wire && propWires.IsEmpty()) + { + auto mesg = + std::string("invalid argument: expecting param.wire to be a Wire"); + Nan::ThrowError(mesg.c_str()); + } + + if (wire) + { + auxWires.push_back(wire); + } + + if (!propWires.IsEmpty() && propWires->IsArray()) + { + std::cout << " A" << std::endl; + + v8::Local arr = v8::Local::Cast(propWires); + if (!arr.IsEmpty()) + { + + for (int i = 0; i < arr->Length(); i++) + { + auto e = Nan::Get(arr, i).ToLocalChecked(); + Wire *wire2 = DynamicCast(e); + std::cout << " B" << std::endl; + if (wire2) + { + auxWires.push_back(wire2); + } + } + std::cout << " C" << std::endl; + + } + } + + bool isFrenet = extract_bool(propIsFrenet); + + bool solid = extract_bool(propSolid); + + + Wire *auxilaryCurve = DynamicCast(propAuxilaryCurve); + + // read optional spineSupport + + Wire *spineSupport = DynamicCast(propSpineSupport); + if (!spineSupport) + { + auto mesg = std::string( + "invalid argument: expecting param.spineSupport to be a Wire"); + Nan::ThrowError(mesg.c_str()); + } + // = Nan::To(_v).FromMaybe(defaultValue); + v8::Local pJhis = Solid::NewInstance(); + try + { + + auto tool = BRepOffsetAPI_MakePipeShell(spineSupport->wire()); + + if (auxilaryCurve) + { + tool.SetMode(auxilaryCurve->wire());// , true, BRepFill_TypeOfContact::BRepFill_Contact); + } + else + { + if (isFrenet) { + tool.SetMode(isFrenet); + } + } + +#define TRANSFORMED 0 +#define ROUND_CORNER 1 +#define TIGHT_CORNER 2 + + int transition = TRANSFORMED; + auto transitionMode = ([](int transition) + { + switch (transition) { + case TRANSFORMED: + return BRepBuilderAPI_Transformed; + case ROUND_CORNER: + return BRepBuilderAPI_RoundCorner; + default: + case TIGHT_CORNER: + return BRepBuilderAPI_RightCorner; + } })(transition); + + tool.SetTransitionMode(transitionMode); + + for (auto w : auxWires) + { + tool.Add(w->wire()); + } + // build a shell + tool.Build(); + + if (solid) + { + // turn it to a solid + tool.MakeSolid(); + } + + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + + // auto listOfShapes = piper.Generated(); + pThis->setShape(tool.Shape()); + // registerXXXXFaces(pThis, prismMaker); + } + CATCH_AND_RETHROW("Failed to create pipe "); + info.GetReturnValue().Set(pJhis); } NAN_METHOD(ShapeFactory::makePrism) @@ -161,54 +476,58 @@ NAN_METHOD(ShapeFactory::makePrism) // [x,y,z] // [x,y,z] [x,y,z] // OCCBase *shape, OCCStruct3d p1, OCCStruct3d p2) - Face* pFace = DynamicCast(info[0]); - if (!pFace) { + Face *pFace = DynamicCast(info[0]); + if (!pFace) + { return Nan::ThrowError("invalid arguments : expecting ,"); } v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); - + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); gp_Vec direction(0, 0, 10); ReadVector(info[1], &direction); - if (direction.IsEqual(gp_Vec(0, 0, 0), 1E-7, 1E-8)) { + if (direction.IsEqual(gp_Vec(0, 0, 0), 1E-7, 1E-8)) + { return Nan::ThrowError("invalid arguments : expecting ,"); } - - try { - const TopoDS_Shape& face = pFace->face(); + try + { + const TopoDS_Shape &face = pFace->face(); BRepPrimAPI_MakePrism prismMaker(face, direction); - pThis->setShape(prismMaker.Shape()); registerMakeBoxFaces(pThis, prismMaker); // possible fix shape - if (!pThis->fixShape()) { + if (!pThis->fixShape()) + { StdFail_NotDone::Raise("Shapes not valid"); } - } CATCH_AND_RETHROW("Failed to create prism "); info.GetReturnValue().Set(pJhis); } -static void registerOneAxisFaces(Solid* pThis, BRepPrim_OneAxis& tool) +static void registerOneAxisFaces(Solid *pThis, BRepPrim_OneAxis &tool) { pThis->_registerNamedShape("lateral", tool.LateralFace()); - if (tool.HasSides()) { + if (tool.HasSides()) + { pThis->_registerNamedShape("start", tool.StartFace()); pThis->_registerNamedShape("end", tool.EndFace()); } - if (tool.HasTop()) { + if (tool.HasTop()) + { pThis->_registerNamedShape("top", tool.TopFace()); } - if (tool.HasBottom()) { + if (tool.HasBottom()) + { pThis->_registerNamedShape("bottom", tool.BottomFace()); } /* @@ -236,8 +555,8 @@ static void registerOneAxisFaces(Solid* pThis, BRepPrim_OneAxis& tool) NAN_METHOD(ShapeFactory::makeSphere) { v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); - + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); gp_Pnt center(0, 0, 0); ReadPoint(info[0], ¢er); @@ -245,10 +564,12 @@ NAN_METHOD(ShapeFactory::makeSphere) double radius = 0.0; ReadDouble(info[1], radius); - if (radius < 1E-7) { + if (radius < 1E-7) + { return Nan::ThrowError("invalid radius"); } - try { + try + { BRepPrimAPI_MakeSphere tool(center, radius); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Sphere()); @@ -258,51 +579,88 @@ NAN_METHOD(ShapeFactory::makeSphere) info.GetReturnValue().Set(pJhis); } -void ReadAx2(const v8::Local& value, gp_Ax2* ax2) +void ReadAx2(v8::Local value, gp_Ax2 *ax2) { assert(ax2); - if (value->IsArray()) { + if (value->IsArray()) + { v8::Local arr = v8::Local::Cast(value); gp_Pnt origin; - auto element0 = Nan::Get(arr,0).ToLocalChecked(); + auto element0 = Nan::Get(arr, 0).ToLocalChecked(); ReadPoint(element0, &origin); - if (arr->Length() == 2) { + if (arr->Length() == 2) + { // variation 2 : gp_Ax2(const gp_Pnt& P,const gp_Dir& V); gp_Dir V; - auto element1 = Nan::Get(arr,1).ToLocalChecked(); + auto element1 = Nan::Get(arr, 1).ToLocalChecked(); ReadDir(element1, &V); *ax2 = gp_Ax2(origin, V); } - if (arr->Length() == 3) { + if (arr->Length() == 3) + { // variation 1 : gp_Ax2(const gp_Pnt& P,const gp_Dir& N,const gp_Dir& Vx); gp_Dir N, Vx; - auto element1 = Nan::Get(arr,1).ToLocalChecked(); - auto element2 = Nan::Get(arr,2).ToLocalChecked(); + auto element1 = Nan::Get(arr, 1).ToLocalChecked(); + auto element2 = Nan::Get(arr, 2).ToLocalChecked(); ReadDir(element1, &N); ReadDir(element2, &Vx); *ax2 = gp_Ax2(origin, N, Vx); } } - else { + else + { Nan::ThrowError("Cannot extract Axis from arrgument value"); } } +void ReadAx1(v8::Local value, gp_Ax1 *ax1) +{ + assert(ax1); + if (value->IsArray()) + { + v8::Local arr = v8::Local::Cast(value); + gp_Pnt origin; + + auto element0 = Nan::Get(arr, 0).ToLocalChecked(); + + ReadPoint(element0, &origin); + if (arr->Length() == 2) + { + // variation 2 : gp_Ax2(const gp_Pnt& P,const gp_Dir& V); + gp_Dir V; + auto element1 = Nan::Get(arr, 1).ToLocalChecked(); + ReadDir(element1, &V); + *ax1 = gp_Ax1(origin, V); + } + else + { + Nan::ThrowError("Cannot extract Axis from argument value"); + } + } + else + { + Nan::ThrowError("Cannot extract Axis from argument value"); + } +} NAN_METHOD(ShapeFactory::makeCylinder) { // gp_Ax2& Axes // gp_Ax2(const gp_Pnt& P,const gp_Dir& N,const gp_Dir& Vx); - // Standard_EXPORT BRepPrimAPI_MakeCylinder(const Standard_Real R,const Standard_Real H); - // Standard_EXPORT BRepPrimAPI_MakeCylinder(const Standard_Real R,const Standard_Real H,const Standard_Real Angle); - // Standard_EXPORT BRepPrimAPI_MakeCylinder(const gp_Ax2& Axes,const Standard_Real R,const Standard_Real H); - // Standard_EXPORT BRepPrimAPI_MakeCylinder(const gp_Ax2& Axes,const Standard_Real R,const Standard_Real H,const Standard_Real Angle); + // Standard_EXPORT BRepPrimAPI_MakeCylinder(const Standard_Real R,const + // Standard_Real H); Standard_EXPORT BRepPrimAPI_MakeCylinder(const + // Standard_Real R,const Standard_Real H,const Standard_Real Angle); + // Standard_EXPORT BRepPrimAPI_MakeCylinder(const gp_Ax2& Axes,const + // Standard_Real R,const Standard_Real H); Standard_EXPORT + // BRepPrimAPI_MakeCylinder(const gp_Ax2& Axes,const Standard_Real R,const + // Standard_Real H,const Standard_Real Angle); const double epsilon = 1E-3; gp_Ax2 axis; - if (info.Length() == 2) { + if (info.Length() == 2) + { // variation 1 // a vertical cylinder of radius R starting a (0,0,0) ending at (0,0,H) @@ -312,27 +670,32 @@ NAN_METHOD(ShapeFactory::makeCylinder) double H = 0; ReadDouble(info[1], H); - if (R < epsilon || H < epsilon) { - return Nan::ThrowError("invalid value for arguments makeCylinder(R,H)"); + if (R < epsilon || H < epsilon) + { + return Nan::ThrowError("invalid value for arguments makeCylinder(R,H)"); } v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); - try { + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + try + { pThis->setShape(BRepPrimAPI_MakeCylinder(R, H).Shape()); } CATCH_AND_RETHROW("Failed to create cylinder "); info.GetReturnValue().Set(pJhis); - } - else if (info.Length() == 3) { + else if (info.Length() == 3) + { - if (info[0]->IsArray() && info[1]->IsNumber() && info[2]->IsNumber()) { + if (info[0]->IsArray() && info[1]->IsNumber() && info[2]->IsNumber()) + { - try { + try + { // variation 2 // <[ , ,] - gp_Ax2 ax2; + gp_Ax2 ax2; ReadAx2(info[0], &ax2); double R = 0; @@ -341,21 +704,24 @@ NAN_METHOD(ShapeFactory::makeCylinder) double H = 0; ReadDouble(info[2], H); - if (R < epsilon || H < epsilon) { + if (R < epsilon || H < epsilon) + { return Nan::ThrowError("invalid value for arguments"); } v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); BRepPrimAPI_MakeCylinder tool(ax2, R, H); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Cylinder()); info.GetReturnValue().Set(pJhis); } CATCH_AND_RETHROW("Failed to create cylinder "); - } - else if (info[0]->IsArray() && info[1]->IsArray() && info[2]->IsNumber()) { + else if (info[0]->IsArray() && info[1]->IsArray() && + info[2]->IsNumber()) + { // variation 3 ( 2 points and a radius ) gp_Pnt p1; @@ -371,43 +737,52 @@ NAN_METHOD(ShapeFactory::makeCylinder) const double dy = p2.Y() - p1.Y(); const double dz = p2.Z() - p1.Z(); - const double H = sqrt(dx*dx + dy*dy + dz*dz); - if (H < epsilon) { - return Nan::ThrowError("cannot build a cylinder on two coincident points"); + const double H = sqrt(dx * dx + dy * dy + dz * dz); + if (H < epsilon) + { + return Nan::ThrowError( + "cannot build a cylinder on two coincident points"); } gp_Vec aV(dx / H, dy / H, dz / H); gp_Ax2 ax2(p1, aV); v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); - try { + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + try + { BRepPrimAPI_MakeCylinder tool(ax2, R, H); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Cylinder()); } CATCH_AND_RETHROW("Failed to create cylinder "); info.GetReturnValue().Set(pJhis); - } } - else { + else + { return Nan::ThrowError("invalid arguments"); } - } NAN_METHOD(ShapeFactory::makeCone) { v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); const double epsilon = 1E-3; - // Standard_EXPORT BRepPrimAPI_MakeCone(const Standard_Real R1,const Standard_Real R2,const Standard_Real H); - // Standard_EXPORT BRepPrimAPI_MakeCone(const Standard_Real R1,const Standard_Real R2,const Standard_Real H,const Standard_Real angle); - // Standard_EXPORT BRepPrimAPI_MakeCone(const gp_Ax2& Axes,const Standard_Real R1,const Standard_Real R2,const Standard_Real H,const Standard_Real angle); - if (info.Length() == 3 && info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber()) { + // Standard_EXPORT BRepPrimAPI_MakeCone(const Standard_Real R1,const + // Standard_Real R2,const Standard_Real H); Standard_EXPORT + // BRepPrimAPI_MakeCone(const Standard_Real R1,const Standard_Real R2,const + // Standard_Real H,const Standard_Real angle); Standard_EXPORT + // BRepPrimAPI_MakeCone(const gp_Ax2& Axes,const Standard_Real R1,const + // Standard_Real R2,const Standard_Real H,const Standard_Real angle); + if (info.Length() == 3 && info[0]->IsNumber() && info[1]->IsNumber() && + info[2]->IsNumber()) + { double R1 = 0, R2 = 0, H = 0; @@ -415,19 +790,24 @@ NAN_METHOD(ShapeFactory::makeCone) ReadDouble(info[1], R2); ReadDouble(info[2], H); - if (R1 < epsilon || R2 < epsilon || H < epsilon) { + if (R1 < epsilon || R2 < epsilon || H < epsilon) + { return Nan::ThrowError("invalid value for arguments"); } - try { + try + { BRepPrimAPI_MakeCone tool(R1, R2, H); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Cone()); } CATCH_AND_RETHROW("Failed to create Cone "); } - else if (info.Length() == 3 && info[0]->IsArray() && info[1]->IsNumber() && info[2]->IsNumber()) { + else if (info.Length() == 3 && info[0]->IsArray() && info[1]->IsNumber() && + info[2]->IsNumber()) + { - try { + try + { gp_Dir axis; ReadDir(info[0], &axis); @@ -439,10 +819,12 @@ NAN_METHOD(ShapeFactory::makeCone) } CATCH_AND_RETHROW("Failed to create Cone, with [u,v,w],angle,height"); - return Nan::ThrowError("Cone with [u,v,w],angle,height not implemented yet"); - + return Nan::ThrowError( + "Cone with [u,v,w],angle,height not implemented yet"); } - else if (info.Length() == 4 && info[0]->IsArray() && info[1]->IsNumber() && info[2]->IsArray() && info[3]->IsNumber()) { + else if (info.Length() == 4 && info[0]->IsArray() && info[1]->IsNumber() && + info[2]->IsArray() && info[3]->IsNumber()) + { // Point, point , R1,R2); // variation 3 ( 2 points and a radius ) gp_Pnt p1; @@ -451,7 +833,6 @@ NAN_METHOD(ShapeFactory::makeCone) double R1 = 10; ReadDouble(info[1], R1); - gp_Pnt p2; ReadPoint(info[2], &p2); @@ -462,31 +843,35 @@ NAN_METHOD(ShapeFactory::makeCone) const double dy = p2.Y() - p1.Y(); const double dz = p2.Z() - p1.Z(); - const double H = sqrt(dx*dx + dy*dy + dz*dz); - if (H < epsilon) { + const double H = sqrt(dx * dx + dy * dy + dz * dz); + if (H < epsilon) + { return Nan::ThrowError("cannot build a cone on two coincident points"); } gp_Vec aV(dx / H, dy / H, dz / H); gp_Ax2 ax2(p1, aV); - try { + try + { BRepPrimAPI_MakeCone tool(ax2, R1, R2, H); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Cone()); } CATCH_AND_RETHROW("Failed to create cone "); - } - else if (info.Length() == 4 && info[0]->IsArray() && info[1]->IsArray() && info[2]->IsNumber() && info[3]->IsNumber()) { - try { - // cone with a sharp apex - // apex, direction , half_angle, height + else if (info.Length() == 4 && info[0]->IsArray() && info[1]->IsArray() && + info[2]->IsNumber() && info[3]->IsNumber()) + { + try + { + // cone with a sharp apex + // apex, direction , half_angle, height gp_Pnt apex; ReadPoint(info[0], &apex); gp_Dir innerDir; ReadDir(info[1], &innerDir); - double half_angle_in_radian = atan(1.0); // default : 45° + double half_angle_in_radian = atan(1.0); // default : 45° ReadDouble(info[2], half_angle_in_radian); double height = 100; @@ -494,14 +879,16 @@ NAN_METHOD(ShapeFactory::makeCone) // r/h= tan(a); gp_Ax2 ax2(apex, innerDir); - BRepPrimAPI_MakeCone tool(ax2, 0, height*tan(half_angle_in_radian), height); + BRepPrimAPI_MakeCone tool(ax2, 0, height * tan(half_angle_in_radian), + height); pThis->setShape(tool.Shape()); registerOneAxisFaces(pThis, tool.Cone()); } - CATCH_AND_RETHROW("Failed to create cone with apex, direction , half_angle and height"); - + CATCH_AND_RETHROW( + "Failed to create cone with apex, direction , half_angle and height"); } - else { + else + { return Nan::ThrowError("invalid arguments (cone)"); } @@ -511,17 +898,20 @@ NAN_METHOD(ShapeFactory::makeCone) NAN_METHOD(ShapeFactory::makeTorus) { v8::Local pJhis = Solid::NewInstance(); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); // variation 1 - // + // // Center as // axis as // bigRadius // smallRadius - if (info.Length() == 4 && info[2]->IsNumber() && info[3]->IsNumber()) { + if (info.Length() == 4 && info[2]->IsNumber() && info[3]->IsNumber()) + { // - try { + try + { gp_Pnt center; ReadPoint(info[0], ¢er); // @@ -535,7 +925,8 @@ NAN_METHOD(ShapeFactory::makeTorus) ReadDouble(info[3], smallR); BRepPrimAPI_MakeTorus tool(gp_Ax2(center, axis), bigR, smallR); - if (tool.Shape().IsNull() || tool.Torus().LateralFace().IsNull()) { + if (tool.Shape().IsNull() || tool.Torus().LateralFace().IsNull()) + { // invalid shape return Nan::ThrowError("cannot build Torus (makeTorus) A"); } @@ -549,86 +940,80 @@ NAN_METHOD(ShapeFactory::makeTorus) return Nan::ThrowError("invalid arguments (makeTorus)"); } - - -#include #include - - - - +#include class IShapeClassifierTool { public: - virtual const TopTools_ListOfShape& getGenerated(const TopoDS_Shape& shape) = 0; - virtual const TopTools_ListOfShape& getModified(const TopoDS_Shape& shape) = 0; - virtual bool getDeleted(const TopoDS_Shape& shape) = 0; + virtual const TopTools_ListOfShape & + getGenerated(const TopoDS_Shape &shape) = 0; + virtual const TopTools_ListOfShape & + getModified(const TopoDS_Shape &shape) = 0; + virtual bool getDeleted(const TopoDS_Shape &shape) = 0; }; class IShapeNameAccessor { public: - virtual const TopoDS_Shape& shape() const = 0; - virtual std::string getShapeName(const TopoDS_Shape& oldshape) = 0; + virtual const TopoDS_Shape &shape() const = 0; + virtual std::string getShapeName(const TopoDS_Shape &oldshape) = 0; virtual int operand() const = 0; }; class IShapeNameSetter { public: - virtual void setShapeName(const TopoDS_Shape& newshape, const char* name) = 0; + virtual void setShapeName(const TopoDS_Shape &newshape, const char *name) = 0; }; class ShapeClassifier { public: - ShapeClassifier( - IShapeClassifierTool* tool, - IShapeNameAccessor* nameAccessor1, - IShapeNameAccessor* nameAccessor2, // optional : could be null - IShapeNameSetter* nameSetter, - const TopoDS_Shape& newShape); + ShapeClassifier(IShapeClassifierTool *tool, IShapeNameAccessor *nameAccessor1, + IShapeNameAccessor *nameAccessor2, // optional : could be null + IShapeNameSetter *nameSetter, const TopoDS_Shape &newShape); void classify(); private: - const TopoDS_Shape& m_newShape; - IShapeClassifierTool* m_tool; - IShapeNameAccessor* m_nameAccessor1; //to get the name of a sub-shape of the old shape - IShapeNameAccessor* m_nameAccessor2; //to get the name of a sub-shape of the old shape - IShapeNameSetter* m_nameSetter; //to set the name of a sub-shape on the new shape - + const TopoDS_Shape &m_newShape; + IShapeClassifierTool *m_tool; + IShapeNameAccessor + *m_nameAccessor1; // to get the name of a sub-shape of the old shape + IShapeNameAccessor + *m_nameAccessor2; // to get the name of a sub-shape of the old shape + IShapeNameSetter + *m_nameSetter; // to set the name of a sub-shape on the new shape // sub-shape of new shape for which we have already computed a name - TopTools_MapOfShape m_processedSubShapes; + TopTools_MapOfShape m_processedSubShapes; - enum ORIGIN { GENERATED, MODIFIED, IDENTICAL }; + enum ORIGIN + { + GENERATED, + MODIFIED, + IDENTICAL + }; - void _classify(IShapeNameAccessor* originalBody, TopAbs_ShapeEnum shapeType); + void _classify(IShapeNameAccessor *originalBody, TopAbs_ShapeEnum shapeType); void _classifyRemainingSubShape(TopAbs_ShapeEnum shapeType); - void registerShape(ORIGIN org, IShapeNameAccessor* originalBody, const TopoDS_Shape& originalShape, const TopoDS_Shape& newShape, int counter); + void registerShape(ORIGIN org, IShapeNameAccessor *originalBody, + const TopoDS_Shape &originalShape, + const TopoDS_Shape &newShape, int counter); - ShapeClassifier(const ShapeClassifier&); - void operator=(const ShapeClassifier&); + ShapeClassifier(const ShapeClassifier &); + void operator=(const ShapeClassifier &); }; -ShapeClassifier::ShapeClassifier( - IShapeClassifierTool* tool, - IShapeNameAccessor* nameAccessor1, - IShapeNameAccessor* nameAccessor2, - IShapeNameSetter* nameSetter, - const TopoDS_Shape& newShape -) - : m_newShape(newShape) - , m_tool(tool) - , m_nameAccessor1(nameAccessor1) - , m_nameAccessor2(nameAccessor2) - , m_nameSetter(nameSetter) -{ - -} - +ShapeClassifier::ShapeClassifier(IShapeClassifierTool *tool, + IShapeNameAccessor *nameAccessor1, + IShapeNameAccessor *nameAccessor2, + IShapeNameSetter *nameSetter, + const TopoDS_Shape &newShape) + : m_newShape(newShape), m_tool(tool), m_nameAccessor1(nameAccessor1), + m_nameAccessor2(nameAccessor2), m_nameSetter(nameSetter) {} -void ShapeClassifier::_classify(IShapeNameAccessor* obj, TopAbs_ShapeEnum shapeType) +void ShapeClassifier::_classify(IShapeNameAccessor *obj, + TopAbs_ShapeEnum shapeType) { TopTools_IndexedMapOfShape newShapeMap; TopExp::MapShapes(this->m_newShape, shapeType, newShapeMap); @@ -636,41 +1021,55 @@ void ShapeClassifier::_classify(IShapeNameAccessor* obj, TopAbs_ShapeEnum shapeT TopTools_IndexedMapOfShape map; TopExp::MapShapes(obj->shape(), shapeType, map); - for (int i = 0; i < map.Extent(); i++) { - const TopoDS_Shape& current = map.FindKey(i + 1); + for (int i = 0; i < map.Extent(); i++) + { + const TopoDS_Shape ¤t = map.FindKey(i + 1); int counterG = 0; int counterM = 0; - const TopTools_ListOfShape& generatedShapes = m_tool->getGenerated(current); + const TopTools_ListOfShape &generatedShapes = m_tool->getGenerated(current); { TopTools_ListIteratorOfListOfShape it(generatedShapes); - for (; it.More(); it.Next()) { - TopoDS_Shape& newShape = it.Value(); - if (!newShapeMap.Contains(newShape)) { continue; } - if (this->m_processedSubShapes.Contains(newShape)) { + for (; it.More(); it.Next()) + { + TopoDS_Shape &newShape = it.Value(); + if (!newShapeMap.Contains(newShape)) + { + continue; + } + if (this->m_processedSubShapes.Contains(newShape)) + { continue; // already processed } registerShape(GENERATED, obj, current, newShape, counterG++); } } - const TopTools_ListOfShape& modifiedShapes = m_tool->getModified(current); + const TopTools_ListOfShape &modifiedShapes = m_tool->getModified(current); { TopTools_ListIteratorOfListOfShape it(modifiedShapes); - for (; it.More(); it.Next()) { - TopoDS_Shape& newShape = it.Value(); - if (!newShapeMap.Contains(newShape)) { continue; } - if (this->m_processedSubShapes.Contains(newShape)) { + for (; it.More(); it.Next()) + { + TopoDS_Shape &newShape = it.Value(); + if (!newShapeMap.Contains(newShape)) + { + continue; + } + if (this->m_processedSubShapes.Contains(newShape)) + { continue; // already processed } registerShape(MODIFIED, obj, current, newShape, counterM++); } } - if ((counterG + counterM == 0) && !m_tool->getDeleted(current)) { - if (!newShapeMap.Contains(current)) { continue; } + if ((counterG + counterM == 0) && !m_tool->getDeleted(current)) + { + if (!newShapeMap.Contains(current)) + { + continue; + } registerShape(IDENTICAL, obj, current, current, -1); } } - } void ShapeClassifier::_classifyRemainingSubShape(TopAbs_ShapeEnum shapeType) @@ -678,33 +1077,41 @@ void ShapeClassifier::_classifyRemainingSubShape(TopAbs_ShapeEnum shapeType) TopTools_IndexedMapOfShape oldShapeMap1; TopExp::MapShapes(m_nameAccessor1->shape(), shapeType, oldShapeMap1); TopTools_IndexedMapOfShape oldShapeMap2; - if (m_nameAccessor2) { + if (m_nameAccessor2) + { TopExp::MapShapes(m_nameAccessor2->shape(), shapeType, oldShapeMap2); } TopTools_IndexedMapOfShape map; TopExp::MapShapes(m_newShape, shapeType, map); - for (int i = 0; i < map.Extent(); i++) { - const TopoDS_Shape& current = map.FindKey(i + 1); + for (int i = 0; i < map.Extent(); i++) + { + const TopoDS_Shape ¤t = map.FindKey(i + 1); - if (this->m_processedSubShapes.Contains(current)) { + if (this->m_processedSubShapes.Contains(current)) + { continue; // already processed } - if (this->m_tool->getDeleted(current)) { + if (this->m_tool->getDeleted(current)) + { continue; } - if (oldShapeMap1.Contains(current)) { + if (oldShapeMap1.Contains(current)) + { // reuse name of old shape registerShape(IDENTICAL, m_nameAccessor1, current, current, -1); } - else if (oldShapeMap2.Contains(current)) { + else if (oldShapeMap2.Contains(current)) + { // reuse name of old shape registerShape(IDENTICAL, m_nameAccessor2, current, current, -1); } - else { + else + { // provide a default name based on hashCode std::stringstream s; - s << shapeType << "tmp" << current.HashCode(std::numeric_limits::max()); + s << shapeType << "tmp" + << current.HashCode(std::numeric_limits::max()); s << std::ends; m_nameSetter->setShapeName(current, s.str().c_str()); } @@ -715,15 +1122,14 @@ void ShapeClassifier::classify() _classify(m_nameAccessor1, TopAbs_FACE); _classify(m_nameAccessor1, TopAbs_EDGE); _classify(m_nameAccessor1, TopAbs_VERTEX); - if (m_nameAccessor2) { + if (m_nameAccessor2) + { _classify(m_nameAccessor2, TopAbs_FACE); _classify(m_nameAccessor2, TopAbs_EDGE); _classify(m_nameAccessor2, TopAbs_VERTEX); } - - - // + // // now check shape of the new solid that but that have'nt been processed yet // // if the shape can be found in old solid we can reuse the name of the @@ -733,10 +1139,12 @@ void ShapeClassifier::classify() _classifyRemainingSubShape(TopAbs_FACE); _classifyRemainingSubShape(TopAbs_EDGE); _classifyRemainingSubShape(TopAbs_VERTEX); - } -void ShapeClassifier::registerShape(ORIGIN org, IShapeNameAccessor* nameAccessor, const TopoDS_Shape& originalShape, const TopoDS_Shape& newShape, int counter) +void ShapeClassifier::registerShape(ORIGIN org, + IShapeNameAccessor *nameAccessor, + const TopoDS_Shape &originalShape, + const TopoDS_Shape &newShape, int counter) { std::string original_name = nameAccessor->getShapeName(originalShape); @@ -744,7 +1152,8 @@ void ShapeClassifier::registerShape(ORIGIN org, IShapeNameAccessor* nameAccessor std::stringstream s; std::string op; - switch (org) { + switch (org) + { case GENERATED: op = "g"; break; @@ -757,15 +1166,18 @@ void ShapeClassifier::registerShape(ORIGIN org, IShapeNameAccessor* nameAccessor s << op; bool wantSep = false; - if (nameAccessor->operand() >= 0) { + if (nameAccessor->operand() >= 0) + { wantSep = true; s << nameAccessor->operand(); } - if (wantSep) { + if (wantSep) + { s << ":"; } s << original_name; - if (counter >= 0) { + if (counter >= 0) + { s << ":" << counter; } s << std::ends; @@ -774,115 +1186,109 @@ void ShapeClassifier::registerShape(ORIGIN org, IShapeNameAccessor* nameAccessor m_processedSubShapes.Add(newShape); m_nameSetter->setShapeName(newShape, newName.c_str()); - } class BRepAlgoAPI_BooleanOperation_Adaptor : public IShapeClassifierTool { public: - BRepAlgoAPI_BooleanOperation_Adaptor(BRepAlgoAPI_BooleanOperation* pTool) - :m_pTool(pTool) - { - }; - virtual const TopTools_ListOfShape& getGenerated(const TopoDS_Shape& current) + BRepAlgoAPI_BooleanOperation_Adaptor(BRepAlgoAPI_BooleanOperation *pTool) + : m_pTool(pTool){}; + virtual const TopTools_ListOfShape & + getGenerated(const TopoDS_Shape ¤t) { return m_pTool->Generated(current); }; - virtual const TopTools_ListOfShape& getModified(const TopoDS_Shape& current) + virtual const TopTools_ListOfShape &getModified(const TopoDS_Shape ¤t) { return m_pTool->Modified(current); }; - virtual bool getDeleted(const TopoDS_Shape& shape) + virtual bool getDeleted(const TopoDS_Shape &shape) { return m_pTool->IsDeleted(shape) ? true : false; }; // - BRepAlgoAPI_BooleanOperation* m_pTool; + BRepAlgoAPI_BooleanOperation *m_pTool; }; class BRepBuilderAPI_MakeShape_Adapator : public IShapeClassifierTool { public: - BRepBuilderAPI_MakeShape_Adapator(BRepBuilderAPI_MakeShape* pTool) - :m_pTool(pTool) - { - }; - virtual const TopTools_ListOfShape& getGenerated(const TopoDS_Shape& current) + BRepBuilderAPI_MakeShape_Adapator(BRepBuilderAPI_MakeShape *pTool) + : m_pTool(pTool){}; + virtual const TopTools_ListOfShape & + getGenerated(const TopoDS_Shape ¤t) { return m_pTool->Generated(current); }; - virtual const TopTools_ListOfShape& getModified(const TopoDS_Shape& current) + virtual const TopTools_ListOfShape &getModified(const TopoDS_Shape ¤t) { return m_pTool->Modified(current); }; - virtual bool getDeleted(const TopoDS_Shape& shape) + virtual bool getDeleted(const TopoDS_Shape &shape) { return m_pTool->IsDeleted(shape) ? true : false; }; // - BRepBuilderAPI_MakeShape* m_pTool; + BRepBuilderAPI_MakeShape *m_pTool; }; -class ShapeNameAccessor : public IShapeNameAccessor +class ShapeNameAccessor : public IShapeNameAccessor { public: - ShapeNameAccessor(Solid* obj, int operand = -1) :m_operand(operand), m_obj(obj) {}; - virtual const TopoDS_Shape& shape() const - { - return m_obj->shape(); - } - virtual std::string getShapeName(const TopoDS_Shape& shape) + ShapeNameAccessor(Solid *obj, int operand = -1) + : m_operand(operand), m_obj(obj){}; + virtual const TopoDS_Shape &shape() const { return m_obj->shape(); } + virtual std::string getShapeName(const TopoDS_Shape &shape) { std::string name = m_obj->_getShapeName(shape); return name; }; virtual int operand() const { return m_operand; } + private: - Solid* m_obj; + Solid *m_obj; int m_operand; }; -class ShapeNameSetter : public IShapeNameSetter +class ShapeNameSetter : public IShapeNameSetter { public: - ShapeNameSetter(Solid* obj) :m_obj(obj) {}; - virtual void setShapeName(const TopoDS_Shape& newshape, const char* name) + ShapeNameSetter(Solid *obj) : m_obj(obj){}; + virtual void setShapeName(const TopoDS_Shape &newshape, const char *name) { m_obj->_registerNamedShape(name, newshape); }; + private: - Solid* m_obj; + Solid *m_obj; }; - - - -static void registerShapes(BRepAlgoAPI_BooleanOperation* pTool, Solid* newSolid, Solid* oldSolid1, Solid* oldSolid2) +static void registerShapes(BRepAlgoAPI_BooleanOperation *pTool, Solid *newSolid, + Solid *oldSolid1, Solid *oldSolid2) { - const TopoDS_Shape& oldShape1 = oldSolid1->shape(); - const TopoDS_Shape& oldShape2 = oldSolid2->shape(); - const TopoDS_Shape& newShape = newSolid->shape(); - + const TopoDS_Shape &oldShape1 = oldSolid1->shape(); + const TopoDS_Shape &oldShape2 = oldSolid2->shape(); + const TopoDS_Shape &newShape = newSolid->shape(); BRepAlgoAPI_BooleanOperation_Adaptor tool(pTool); - ShapeNameAccessor na1(oldSolid1, 1); - ShapeNameAccessor na2(oldSolid2, 2); - ShapeNameSetter ns(newSolid); + ShapeNameAccessor na1(oldSolid1, 1); + ShapeNameAccessor na2(oldSolid2, 2); + ShapeNameSetter ns(newSolid); ShapeClassifier classifier(&tool, &na1, &na2, &ns, newShape); classifier.classify(); - } -static void registerShapes(BRepBuilderAPI_MakeShape* pTool, Solid* newSolid, Solid* oldSolid) +static void registerShapes(BRepBuilderAPI_MakeShape *pTool, Solid *newSolid, + Solid *oldSolid) { - const TopoDS_Shape& oldShape = oldSolid->shape(); - const TopoDS_Shape& newShape = newSolid->shape(); + const TopoDS_Shape &oldShape = oldSolid->shape(); + const TopoDS_Shape &newShape = newSolid->shape(); BRepBuilderAPI_MakeShape_Adapator tool(pTool); - ShapeNameAccessor na(oldSolid); - ShapeNameSetter ns(newSolid); + ShapeNameAccessor na(oldSolid); + ShapeNameSetter ns(newSolid); TopoDS_Shape empty; ShapeClassifier classifier(&tool, &na, NULL, &ns, newShape); @@ -890,126 +1296,144 @@ static void registerShapes(BRepBuilderAPI_MakeShape* pTool, Solid* newSolid, Sol classifier.classify(); } - - -static void ShapeFactory_createBoolean(_NAN_METHOD_ARGS, Solid* pSolid1, Solid* pSolid2, BOPAlgo_Operation op) +static void ShapeFactory_createBoolean(_NAN_METHOD_ARGS, Solid *pSolid1, + Solid *pSolid2, BOPAlgo_Operation op) { - const TopoDS_Shape& firstObject = pSolid1->shape(); - const TopoDS_Shape& secondObject = pSolid2->shape(); + Nan::HandleScope scope; + const TopoDS_Shape &firstObject = pSolid1->shape(); + const TopoDS_Shape &secondObject = pSolid2->shape(); std::unique_ptr pTool; - - - TopoDS_Shape shape; - try { - switch (op) { + try + { + switch (op) + { case BOPAlgo_FUSE: - pTool = std::unique_ptr(new BRepAlgoAPI_Fuse(firstObject, secondObject)); + pTool = std::unique_ptr( + new BRepAlgoAPI_Fuse(firstObject, secondObject)); break; case BOPAlgo_CUT: - pTool = std::unique_ptr(new BRepAlgoAPI_Cut(firstObject, secondObject)); + pTool = std::unique_ptr( + new BRepAlgoAPI_Cut(firstObject, secondObject)); break; case BOPAlgo_COMMON: - pTool = std::unique_ptr(new BRepAlgoAPI_Common(firstObject, secondObject)); + pTool = std::unique_ptr( + new BRepAlgoAPI_Common(firstObject, secondObject)); break; default: Standard_ConstructionError::Raise("unknown operation"); break; } - if (!pTool->IsDone()) { + if (!pTool->IsDone()) + { Standard_ConstructionError::Raise("operation failed"); } shape = pTool->Shape(); - v8::Local result(Solid::NewInstance(shape)); + v8::Local pJhis = Solid::NewInstance(shape); - Solid* pResult = Nan::ObjectWrap::Unwrap(Nan::To(result).ToLocalChecked()); + Solid *pResult = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); registerShapes(pTool.get(), pResult, pSolid1, pSolid2); - if (pTool->HasDeleted()) { + if (pTool->HasDeleted()) + { // the boolean operation causes some shape from s1 or s2 to be deleted } - if (pTool->HasGenerated()) { + if (pTool->HasGenerated()) + { // the boolean operation causes some shape from s1 or s2 to be created - } - if (pTool->HasModified()) { + if (pTool->HasModified()) + { // the boolean operation causes some shape from s1 or s2 to be created } // check for empty compound shape TopoDS_Iterator It(shape, Standard_True, Standard_True); int found = 0; - for (; It.More(); It.Next()) { + for (; It.More(); It.Next()) + { found++; } - if (found == 0) { + if (found == 0) + { Standard_ConstructionError::Raise("result object is empty compound"); } // simplify compound with one solid into a Solid - if (shape.ShapeType() == TopAbs_COMPOUND) { + if (shape.ShapeType() == TopAbs_COMPOUND) + { TopTools_IndexedMapOfShape shapeMap; TopExp::MapShapes(shape, TopAbs_SOLID, shapeMap); - if (shapeMap.Extent() == 1) { + if (shapeMap.Extent() == 1) + { pResult->setShape(shapeMap(1)); } } - return info.GetReturnValue().Set(result); - + return info.GetReturnValue().Set(pJhis); } CATCH_AND_RETHROW("Failed in boolean operation"); } - -v8::Local ShapeFactory::add(const std::vector& shapes) +v8::Local ShapeFactory::add(const std::vector &shapes) { + + Nan::EscapableHandleScope scope; + TopoDS_Compound compound; BRep_Builder builder; - v8::Local pJhis(Solid::NewInstance()); - Solid* pThis = Nan::ObjectWrap::Unwrap(Nan::To(pJhis).ToLocalChecked()); - try { + v8::Local pJhis = Solid::NewInstance(); + Solid *pThis = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); + try + { builder.MakeCompound(compound); - for (size_t i = 0; i < shapes.size(); i++) { + for (size_t i = 0; i < shapes.size(); i++) + { - const TopoDS_Shape& shape = shapes[i]->shape(); + const TopoDS_Shape &shape = shapes[i]->shape(); builder.Add(compound, shape); } pThis->setShape(compound); - } CATCH_AND_RETHROW_NO_RETURN("Failed in compound operation"); - return pJhis; - + return scope.Escape(pJhis); } NAN_METHOD(ShapeFactory::compound) { - std::vector shapes; - for (int i = 0; i < info.Length(); i++) { + std::vector shapes; + for (int i = 0; i < info.Length(); i++) + { v8::Local obj = Nan::To(info[i]).ToLocalChecked(); - if (IsInstanceOf(obj)) { - Base* pShape = Nan::ObjectWrap::Unwrap(obj); + if (IsInstanceOf(obj)) + { + Base *pShape = Nan::ObjectWrap::Unwrap(obj); shapes.push_back(pShape); } - else if (info[i]->IsArray()) { + else if (info[i]->IsArray()) + { v8::Local arr = v8::Local::Cast(info[i]); int length = arr->Length(); - for (int j = 0; j < length; j++) { - - auto elementJ = Nan::Get(arr,j).ToLocalChecked(); - - v8::Local obj1 = Nan::To(elementJ).ToLocalChecked(); - - if (IsInstanceOf(obj1)) { - Base* pShape = Nan::ObjectWrap::Unwrap(obj1); + for (int j = 0; j < length; j++) + { + + auto elementJ = Nan::Get(arr, j).ToLocalChecked(); + + v8::Local obj1 = + Nan::To(elementJ).ToLocalChecked(); + + if (IsInstanceOf(obj1)) + { + Base *pShape = Nan::ObjectWrap::Unwrap(obj1); shapes.push_back(pShape); } } @@ -1018,21 +1442,26 @@ NAN_METHOD(ShapeFactory::compound) info.GetReturnValue().Set(add(shapes)); } +void ShapeFactory::_boolean(_NAN_METHOD_ARGS, BOPAlgo_Operation op) +{ -void ShapeFactory::_boolean(_NAN_METHOD_ARGS, BOPAlgo_Operation op) { - - if (!IsInstanceOf(info[0]) || !IsInstanceOf(info[1])) { - return Nan::ThrowError("Wrong arguments for boolean operation : expecting two solids"); + if (!IsInstanceOf(info[0]) || !IsInstanceOf(info[1])) + { + return Nan::ThrowError( + "Wrong arguments for boolean operation : expecting two solids"); } - Solid* pSolid1 = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + Solid *pSolid1 = Nan::ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); - Solid* pSolid2 = Nan::ObjectWrap::Unwrap(Nan::To(info[1]).ToLocalChecked()); + Solid *pSolid2 = Nan::ObjectWrap::Unwrap( + Nan::To(info[1]).ToLocalChecked()); /* std::vector other_solids; for (int i=1; iHasInstance(info[i])) { - Solid* pSolid2 = Nan::ObjectWrap::Unwrap(Nan::To(info[i]); + Solid* pSolid2 = + Nan::ObjectWrap::Unwrap(Nan::To(info[i]); other_solids.push_back(pSolid2); } } @@ -1041,114 +1470,115 @@ void ShapeFactory::_boolean(_NAN_METHOD_ARGS, BOPAlgo_Operation op) { */ return ShapeFactory_createBoolean(info, pSolid1, pSolid2, op); - -} - -NAN_METHOD(ShapeFactory::fuse) -{ - return _boolean(info, BOPAlgo_FUSE); } -NAN_METHOD(ShapeFactory::cut) -{ - return _boolean(info, BOPAlgo_CUT); -} - -NAN_METHOD(ShapeFactory::common) -{ - return _boolean(info, BOPAlgo_COMMON); -} +NAN_METHOD(ShapeFactory::fuse) { return _boolean(info, BOPAlgo_FUSE); } +NAN_METHOD(ShapeFactory::cut) { return _boolean(info, BOPAlgo_CUT); } +NAN_METHOD(ShapeFactory::common) { return _boolean(info, BOPAlgo_COMMON); } -bool extractListOfFaces(v8::Local value, TopTools_ListOfShape& faces) +bool extractListOfFaces(v8::Local value, + TopTools_ListOfShape &faces) { - if (value->IsArray()) { + Nan::HandleScope scope; + + if (value->IsArray()) + { v8::Local arr = v8::Local::Cast(value); int length = arr->Length(); - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) + { - auto elementI = Nan::Get(arr,i).ToLocalChecked(); - Face* pFace = 0; - if (extractArg(elementI, pFace)) { + auto elementI = Nan::Get(arr, i).ToLocalChecked(); + Face *pFace = 0; + if (extractArg(elementI, pFace)) + { faces.Append(pFace->face()); } } } - else { - // could be a single face - Face* pFace = 0; - if (!extractArg(value, pFace)) { + else + { + // could be a single face + Face *pFace = 0; + if (!extractArg(value, pFace)) + { return false; } faces.Append(pFace->face()); } - return faces.Extent() > 0; } - NAN_METHOD(ShapeFactory::makeThickSolid) { // variation 1 : ,,thickness // variation 2 : ,[ ... ],thickness - Solid* pSolid = 0; + Solid *pSolid = 0; - try { + try + { - if (!extractArg(info[0], pSolid)) { - return Nan::ThrowError("Wrong arguments for makeThickSolid , first argument must be a solid"); + if (!extractArg(info[0], pSolid)) + { + return Nan::ThrowError("Wrong arguments for makeThickSolid , first " + "argument must be a solid"); } - TopTools_ListOfShape faces; - if (!extractListOfFaces(info[1], faces)) { - return Nan::ThrowError("Wrong arguments for makeThickSolid, second argument must be a list of faces or a single face"); + if (!extractListOfFaces(info[1], faces)) + { + return Nan::ThrowError( + "Wrong arguments for makeThickSolid, second argument must be a list " + "of faces or a single face"); } double offset = 0; ReadDouble(info[2], offset); - BRepOffset_Mode mode = BRepOffset_Skin; Standard_Boolean bIntersection = Standard_False; Standard_Boolean bSelfInter = Standard_False; GeomAbs_JoinType joinType = GeomAbs_Arc; double tol = 0.01; BRepOffsetAPI_MakeThickSolid tool; - tool.MakeThickSolidByJoin(pSolid->solid(), faces, offset, tol, mode, bIntersection, bSelfInter, joinType); + tool.MakeThickSolidByJoin(pSolid->solid(), faces, offset, tol, mode, + bIntersection, bSelfInter, joinType); TopoDS_Shape shape = tool.Shape(); - v8::Local result(Solid::NewInstance(shape)); - - Solid* pResult = Nan::ObjectWrap::Unwrap(Nan::To(result).ToLocalChecked()); + v8::Local pJhis = Solid::NewInstance(shape); + Solid *pResult = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); registerShapes(&tool, pResult, pSolid); - info.GetReturnValue().Set(result); - - }CATCH_AND_RETHROW("Failed in makeThickSolid operation"); + info.GetReturnValue().Set(pJhis); + } + CATCH_AND_RETHROW("Failed in makeThickSolid operation"); } - -bool ReadPlane(const v8::Local& value, gp_Pln& plane) +bool ReadPlane(v8::Local value, gp_Pln &plane) { - if (value.IsEmpty()) { + if (value.IsEmpty()) + { return false; } // could be a planar face - Face* pFace = 0; - if (!extractArg(value, pFace)) { + Face *pFace = 0; + if (!extractArg(value, pFace)) + { return false; } Handle_Geom_Surface surf = BRep_Tool::Surface(pFace->face()); GeomLib_IsPlanarSurface tool(surf); - if (!tool.IsPlanar()) { + if (!tool.IsPlanar()) + { return false; } plane = tool.Plan(); @@ -1160,17 +1590,21 @@ NAN_METHOD(ShapeFactory::makeDraftAngle) { // ,(|[...]),, - try { - if (info.Length() < 4) { + try + { + if (info.Length() < 4) + { return Nan::ThrowError("Wrong arguments for makeDraftAngle"); } - Solid* pSolid = 0; - if (!extractArg(info[0], pSolid)) { + Solid *pSolid = 0; + if (!extractArg(info[0], pSolid)) + { return Nan::ThrowError("Wrong arguments for makeDraftAngle"); } TopTools_ListOfShape faces; - if (!extractListOfFaces(info[1], faces)) { + if (!extractListOfFaces(info[1], faces)) + { return Nan::ThrowError("Wrong arguments for makeDraftAngle"); } @@ -1181,19 +1615,20 @@ NAN_METHOD(ShapeFactory::makeDraftAngle) // ReadDir(info[3],&direction); gp_Pln neutralPlane; - if (!ReadPlane(info[3], neutralPlane)) { + if (!ReadPlane(info[3], neutralPlane)) + { return Nan::ThrowError("Wrong arguments for makeDraftAngle"); } - BRepOffsetAPI_DraftAngle tool(pSolid->shape()); Standard_Boolean flag = Standard_False; int counter = 0; TopTools_ListIteratorOfListOfShape it(faces); - for (; it.More(); it.Next()) { - TopoDS_Face& face = TopoDS::Face(it.Value()); + for (; it.More(); it.Next()) + { + TopoDS_Face &face = TopoDS::Face(it.Value()); gp_Dir direction = neutralPlane.Axis().Direction(); tool.Add(face, direction, angle, neutralPlane, flag); @@ -1201,68 +1636,72 @@ NAN_METHOD(ShapeFactory::makeDraftAngle) TopoDS_Shape shape = tool.Shape(); - v8::Local result(Solid::NewInstance(shape)); - - Solid* pResult = Nan::ObjectWrap::Unwrap(Nan::To(result).ToLocalChecked()); + v8::Local pJhis = Solid::NewInstance(shape); + Solid *pResult = Nan::ObjectWrap::Unwrap( + Nan::To(pJhis).ToLocalChecked()); registerShapes(&tool, pResult, pSolid); - info.GetReturnValue().Set(result); - - } CATCH_AND_RETHROW("Failed in compound operation"); - + info.GetReturnValue().Set(pJhis); + } + CATCH_AND_RETHROW("Failed in compound operation"); } - -static int chamfer(Solid* pNewSolid, Solid* pSolid, const std::vector& edges, const std::vector& distances) +static int chamfer(Solid *pNewSolid, Solid *pSolid, + const std::vector &edges, + const std::vector &distances) { size_t edges_size = edges.size(); size_t distances_size = distances.size(); - try { + try + { BRepFilletAPI_MakeChamfer CF(pSolid->shape()); TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(pSolid->shape(), TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - - for (size_t i = 0; i < edges.size(); i++) { + TopExp::MapShapesAndAncestors(pSolid->shape(), TopAbs_EDGE, TopAbs_FACE, + mapEdgeFace); + for (size_t i = 0; i < edges.size(); i++) + { - const TopoDS_Edge& edge = edges[i]->edge(); + const TopoDS_Edge &edge = edges[i]->edge(); // skip degenerated edge if (BRep_Tool::Degenerated(edge)) continue; - const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); + const TopoDS_Face &face = + TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); // skip edge if it is a seam if (BRep_Tool::IsClosed(edge, face)) continue; - - if (distances_size == 1) { + if (distances_size == 1) + { // single distance -#if (OCC_VERSION_MAJOR ==7 && OCC_VERSION_MINOR <=3) +#if (OCC_VERSION_MAJOR == 7 && OCC_VERSION_MINOR <= 3) CF.Add(distances[0], edge, face); -#else +#else CF.Add(edge); #endif - } - else if (distances_size == edges_size) { + else if (distances_size == edges_size) + { // distance given for each edge -#if (OCC_VERSION_MAJOR ==7 && OCC_VERSION_MINOR <=3) +#if (OCC_VERSION_MAJOR == 7 && OCC_VERSION_MINOR <= 3) CF.Add(distances[i], edge, face); -#else +#else CF.Add(edge); #endif - } - else { - StdFail_NotDone::Raise("size of distances argument not correct");; + else + { + StdFail_NotDone::Raise("size of distances argument not correct"); + ; } } @@ -1271,7 +1710,7 @@ static int chamfer(Solid* pNewSolid, Solid* pSolid, const std::vector& ed if (!CF.IsDone()) StdFail_NotDone::Raise("Failed to chamfer solid"); - const TopoDS_Shape& tmp = CF.Shape(); + const TopoDS_Shape &tmp = CF.Shape(); if (tmp.IsNull()) StdFail_NotDone::Raise("Chamfer operaton return Null shape"); @@ -1281,122 +1720,126 @@ static int chamfer(Solid* pNewSolid, Solid* pSolid, const std::vector& ed // possible fix shape if (!pNewSolid->fixShape()) StdFail_NotDone::Raise("Shapes not valid"); - } CATCH_AND_RETHROW_NO_RETURN("Failed to chamfer solid "); return 0; } -static int fillet(Solid* pNewSolid, Solid* pSolid, const std::vector& edges, const std::vector& radius) +static int fillet(Solid *pNewSolid, Solid *pSolid, + const std::vector &edges, + const std::vector &radius) { size_t edges_size = edges.size(); size_t radius_size = radius.size(); - try { + try + { BRepFilletAPI_MakeFillet tool(pSolid->shape()); TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(pSolid->shape(), TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapesAndAncestors(pSolid->shape(), TopAbs_EDGE, TopAbs_FACE, + mapEdgeFace); - for (size_t i = 0; i < edges.size(); i++) { + for (size_t i = 0; i < edges.size(); i++) + { - const TopoDS_Edge& edge = edges[i]->edge(); + const TopoDS_Edge &edge = edges[i]->edge(); // skip degenerated edge if (BRep_Tool::Degenerated(edge)) continue; - const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); + const TopoDS_Face &face = + TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); // skip edge if it is a seam if (BRep_Tool::IsClosed(edge, face)) continue; - if (radius_size == 1) { + if (radius_size == 1) + { // single radius tool.Add(radius[0], edge); } - else if (radius_size == edges_size) { + else if (radius_size == edges_size) + { // radius given for each edge tool.Add(radius[i], edge); } - else if (radius_size == 2 * edges_size) { + else if (radius_size == 2 * edges_size) + { // variable radius tool.Add(radius[2 * i + 0], radius[2 * i + 1], edge); } - else { - StdFail_NotDone::Raise("radius argument size not valid");; + else + { + StdFail_NotDone::Raise("radius argument size not valid"); + ; } } tool.Build(); - if (!tool.IsDone()) { + if (!tool.IsDone()) + { StdFail_NotDone::Raise("Fillet operation has failed"); } - const TopoDS_Shape& tmp = tool.Shape(); + const TopoDS_Shape &tmp = tool.Shape(); - if (tmp.IsNull()) { + if (tmp.IsNull()) + { StdFail_NotDone::Raise("Fillet operation resulted in Null shape"); } pNewSolid->setShape(tmp); // possible fix shape - //xx if (!pNewSolid->fixShape()) { - //xx StdFail_NotDone::Raise("Shapes not valid"); - //xx } + // xx if (!pNewSolid->fixShape()) { + // xx StdFail_NotDone::Raise("Shapes not valid"); + // xx } registerShapes(&tool, pNewSolid, pSolid); - } CATCH_AND_RETHROW_NO_RETURN("Failed to fillet solid "); return 1; - } - NAN_METHOD(ShapeFactory::makeFillet) { // , | [edges...], radius | [ radii ] - Solid* pSolid = 0; - if (!extractArg(info[0], pSolid)) { + Solid *pSolid = 0; + if (!extractArg(info[0], pSolid)) + { return Nan::ThrowError("Wrong arguments for makeFillet"); } - std::vector edges; - if (!_extractArray(info[1], edges) || edges.size() == 0) { - return Nan::ThrowError("invalid arguments makeFillet: no edges provided: expecting [...],radius"); + std::vector edges; + if (!_extractArray(info[1], edges) || edges.size() == 0) + { + return Nan::ThrowError("invalid arguments makeFillet: no edges provided: " + "expecting [...],radius"); } std::vector radii; - if (info[2]->IsNumber()) { + if (info[2]->IsNumber()) + { double radius = 0.0; ReadDouble(info[2], radius); - if (radius < 1E-7) { - //TODO + if (radius < 1E-7) + { + // TODO } radii.push_back(radius); } - v8::Local pNew = pSolid->Clone(); + v8::Local pNew = pSolid->Clone(); - Solid* pNewSolid = Nan::ObjectWrap::Unwrap(pNew); + Solid *pNewSolid = Nan::ObjectWrap::Unwrap(pNew); fillet(pNewSolid, pSolid, edges, radii); info.GetReturnValue().Set(pNew); - } - -NAN_METHOD(ShapeFactory::makePipe) -{ - return Nan::ThrowError("makePipe is currently unimplemented"); -} - - - - diff --git a/src/ShapeFactory.h b/src/ShapeFactory.h index 29d5428..81cdd94 100644 --- a/src/ShapeFactory.h +++ b/src/ShapeFactory.h @@ -3,44 +3,45 @@ #include "OCC.h" #include - - class Solid; class Base; class ShapeFactory { public: - // vertex - static NAN_METHOD(makeVertex); - //xx // edges - //xx static NAN_METHOD(makeLine); - //xx static NAN_METHOD(makeCircle); - //xx static NAN_METHOD(makeArc3P); + // vertex + static NAN_METHOD(makeVertex); + // xx // edges + // xx static NAN_METHOD(makeLine); + // xx static NAN_METHOD(makeCircle); + // xx static NAN_METHOD(makeArc3P); - // wires - static NAN_METHOD(makeWire); + // wires + static NAN_METHOD(makeWire); - // faces - static NAN_METHOD(makeFace); + // faces + static NAN_METHOD(makeFace); - // boolean operation - static NAN_METHOD(fuse); - static NAN_METHOD(cut); - static NAN_METHOD(common); - static NAN_METHOD(compound); - // primitive constructions - static NAN_METHOD(makeBox); - static NAN_METHOD(makePrism); - static NAN_METHOD(makeCylinder); - static NAN_METHOD(makeCone); - static NAN_METHOD(makeSphere); - static NAN_METHOD(makeTorus); - static NAN_METHOD(makePipe); - // - static NAN_METHOD(makeThickSolid); - static NAN_METHOD(makeDraftAngle); - static NAN_METHOD(makeFillet); -private: - static void _boolean(_NAN_METHOD_ARGS,BOPAlgo_Operation op); - static v8::Local add(const std::vector& shapes); + // boolean operation + static NAN_METHOD(fuse); + static NAN_METHOD(cut); + static NAN_METHOD(common); + static NAN_METHOD(compound); + // primitive constructions + static NAN_METHOD(makeBox); + static NAN_METHOD(makePrism); + static NAN_METHOD(makeCylinder); + static NAN_METHOD(makeCone); + static NAN_METHOD(makeSphere); + static NAN_METHOD(makeTorus); + static NAN_METHOD(makeRevol); + static NAN_METHOD(makePipe); + static NAN_METHOD(makePipeShell); + static NAN_METHOD(makeSolidThruSections); + // + static NAN_METHOD(makeThickSolid); + static NAN_METHOD(makeDraftAngle); + static NAN_METHOD(makeFillet); +private: + static void _boolean(_NAN_METHOD_ARGS, BOPAlgo_Operation op); + static v8::Local add(const std::vector &shapes); }; diff --git a/src/ShapeIterator.cc b/src/ShapeIterator.cc index d88aef9..de07e1f 100644 --- a/src/ShapeIterator.cc +++ b/src/ShapeIterator.cc @@ -1,18 +1,16 @@ #include "ShapeIterator.h" -#include "Solid.h" -#include "Face.h" -#include "Wire.h" #include "Edge.h" -#include "Vertex.h" +#include "Face.h" #include "Shell.h" +#include "Solid.h" +#include "Vertex.h" +#include "Wire.h" - -v8::Local buildEmptyWrapper(TopAbs_ShapeEnum type) -{ +v8::Local buildEmptyWrapper(TopAbs_ShapeEnum type) { switch (type) { - case TopAbs_COMPOUND: - case TopAbs_COMPSOLID: - case TopAbs_SOLID: + case TopAbs_COMPOUND: + case TopAbs_COMPSOLID: + case TopAbs_SOLID: return makeInstance(Solid::_template); case TopAbs_SHELL: return makeInstance(Shell::_template); @@ -30,62 +28,52 @@ v8::Local buildEmptyWrapper(TopAbs_ShapeEnum type) } return v8::Local(); } -v8::Local buildWrapper(const TopoDS_Shape shape) -{ - v8::Local obj = v8::Local(buildEmptyWrapper(shape.ShapeType())); - Base* pShape = Nan::ObjectWrap::Unwrap(obj); +v8::Local buildWrapper(const TopoDS_Shape shape) { + Nan::EscapableHandleScope scope; + v8::Local obj = + v8::Local(buildEmptyWrapper(shape.ShapeType())); + Base *pShape = Nan::ObjectWrap::Unwrap(obj); pShape->setShape(shape); - return obj; + return scope.Escape(obj); } -bool ShapeIterator::more() -{ - return ex.More() ? true : false; -} +bool ShapeIterator::more() { return ex.More() ? true : false; } -v8::Local ShapeIterator::next() -{ +v8::Local ShapeIterator::next() { + Nan::EscapableHandleScope scope; if (ex.More()) { - v8::Local obj = buildWrapper(ex.Current()); + v8::Local obj = buildWrapper(ex.Current()); Nan::Set(this->handle(), Nan::New("current").ToLocalChecked(), obj); ex.Next(); - return obj; - } - else { - return Nan::Undefined(); + return scope.Escape(obj); + } else { + return scope.Escape(Nan::Undefined()); } } -NAN_METHOD(ShapeIterator::next) -{ - ShapeIterator* pThis = UNWRAP(ShapeIterator); +NAN_METHOD(ShapeIterator::next) { + ShapeIterator *pThis = UNWRAP(ShapeIterator); info.GetReturnValue().Set(pThis->next()); } +void ShapeIterator::reset() { ex.ReInit(); } -void ShapeIterator::reset() -{ - ex.ReInit(); -} - - -NAN_METHOD(ShapeIterator::reset) -{ - ShapeIterator* pThis = UNWRAP(ShapeIterator); +NAN_METHOD(ShapeIterator::reset) { + ShapeIterator *pThis = UNWRAP(ShapeIterator); pThis->reset(); info.GetReturnValue().Set(info.This()); } Nan::Persistent ShapeIterator::_template; -void ShapeIterator::Init(v8::Local target) -{ +NAN_MODULE_INIT(ShapeIterator::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(ShapeIterator::New); + v8::Local tpl = + Nan::New(ShapeIterator::New); tpl->SetClassName(Nan::New("ShapeIterator").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -100,13 +88,12 @@ void ShapeIterator::Init(v8::Local target) EXPOSE_METHOD(ShapeIterator, next); EXPOSE_METHOD(ShapeIterator, reset); - Nan::Set(target,Nan::New("ShapeIterator").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); - + Nan::Set(target, Nan::New("ShapeIterator").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } +TopAbs_ShapeEnum getShapeEnum(v8::Local arg) { -TopAbs_ShapeEnum getShapeEnum(const v8::Local arg) -{ if (arg->IsString()) { v8::Local str = Nan::To(arg).ToLocalChecked(); @@ -139,28 +126,29 @@ TopAbs_ShapeEnum getShapeEnum(const v8::Local arg) return TopAbs_SHAPE; }; -NAN_METHOD(ShapeIterator::New) -{ +NAN_METHOD(ShapeIterator::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.ShapeIterator() to construct a ShapeIterator"); + return Nan::ThrowError( + " use new occ.ShapeIterator() to construct a ShapeIterator"); } if (info.Length() != 2) { - return Nan::ThrowError(" expecting two arguments : ,<'VERTEX'|'WIRE'|'SOLID'|'FACE'...>"); + return Nan::ThrowError(" expecting two arguments : " + ",<'VERTEX'|'WIRE'|'SOLID'|'FACE'...>"); } // TODO (check that the object info[0] has the correct type) - Base* pShape = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); + Base *pShape = Nan::ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); TopAbs_ShapeEnum type = getShapeEnum(info[1]); - ShapeIterator* pThis = new ShapeIterator(pShape, type); + ShapeIterator *pThis = new ShapeIterator(pShape, type); - Nan::Set(info.This(),Nan::New("current").ToLocalChecked(), Nan::Undefined()); + Nan::Set(info.This(), Nan::New("current").ToLocalChecked(), Nan::Undefined()); pThis->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } - diff --git a/src/ShapeIterator.h b/src/ShapeIterator.h index d04aeea..c284478 100644 --- a/src/ShapeIterator.h +++ b/src/ShapeIterator.h @@ -4,31 +4,29 @@ #include "Base.h" - class ShapeIterator : public Nan::ObjectWrap { public: - TopExp_Explorer ex; - TopAbs_ShapeEnum m_toFind; - - ShapeIterator(Base *arg,TopAbs_ShapeEnum type) { - m_toFind = type; - ex.Init(arg->shape(), m_toFind); - } + TopExp_Explorer ex; + TopAbs_ShapeEnum m_toFind; - bool more(); + ShapeIterator(Base *arg, TopAbs_ShapeEnum type) { + m_toFind = type; + ex.Init(arg->shape(), m_toFind); + } - void reset(); - static NAN_METHOD(reset); + bool more(); - v8::Local next(); - static NAN_METHOD(next); + void reset(); + static NAN_METHOD(reset); - // Methods exposed to JavaScripts - static void Init(v8::Local target); + v8::Local next(); + static NAN_METHOD(next); - static NAN_METHOD(NewInstance); - static NAN_METHOD(New); + // Methods exposed to JavaScripts + static NAN_MODULE_INIT(Init); - static Nan::Persistent _template; + static NAN_METHOD(NewInstance); + static NAN_METHOD(New); + static Nan::Persistent _template; }; diff --git a/src/Shell.cc b/src/Shell.cc index 05e5703..ad110de 100644 --- a/src/Shell.cc +++ b/src/Shell.cc @@ -1,38 +1,29 @@ #include "Shell.h" -#include "Face.h" -#include "Wire.h" #include "Edge.h" +#include "Face.h" #include "Util.h" +#include "Wire.h" +const TopoDS_Shape &Shell::shape() const { return shell(); } -const TopoDS_Shape& Shell::shape() const -{ - return shell(); -} - -void Shell::setShape(const TopoDS_Shape& shape) -{ +void Shell::setShape(const TopoDS_Shape &shape) { m_shell = TopoDS::Shell(shape); } -int Shell::numFaces() -{ - if (shape().IsNull()) return 0; +int Shell::numFaces() { + if (shape().IsNull()) + return 0; TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(shape(), TopAbs_FACE, anIndices); return anIndices.Extent(); } - - -double Shell::area() -{ +double Shell::area() { GProp_GProps prop; BRepGProp::SurfaceProperties(shape(), prop); return prop.Mass(); } - // DVec Face::inertia() { // DVec ret; // GProp_GProps prop; @@ -47,7 +38,7 @@ double Shell::area() // return ret; //} // -//OCCStruct3d Face::centreOfMass() { +// OCCStruct3d Face::centreOfMass() { // OCCStruct3d ret; // GProp_GProps prop; // BRepGProp::SurfaceProperties(this->getShape(), prop); @@ -59,38 +50,36 @@ double Shell::area() //} // - Nan::Persistent Shell::_template; - -NAN_METHOD(Shell::New) -{ +NAN_METHOD(Shell::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Shell() to construct a Shell"); } - Shell* pThis = new Shell(); + Shell *pThis = new Shell(); pThis->Wrap(info.This()); pThis->InitNew(info); info.GetReturnValue().Set(info.This()); } -v8::Local Shell::Clone() const -{ - Shell* obj = new Shell(); +v8::Local Shell::Clone() const { + Nan::EscapableHandleScope scope; + v8::Local instance = makeInstance(_template); + Shell *obj = new Shell(); obj->Wrap(instance); obj->setShape(this->shape()); - return instance; + return scope.Escape(instance); } -void Shell::Init(v8::Local target) -{ +NAN_MODULE_INIT(Shell::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(Shell::New); + v8::Local tpl = + Nan::New(Shell::New); tpl->SetClassName(Nan::New("Shell").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -102,5 +91,6 @@ void Shell::Init(v8::Local target) EXPOSE_READ_ONLY_PROPERTY_INTEGER(Shell, numFaces); EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Shell, area); - Nan::Set(target, Nan::New("Shell").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("Shell").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } diff --git a/src/Shell.h b/src/Shell.h index d724160..ab5b8da 100644 --- a/src/Shell.h +++ b/src/Shell.h @@ -1,31 +1,30 @@ #pragma once -#include "OCC.h" #include "NodeV8.h" - +#include "OCC.h" + #include "Base.h" #include class Face; -class Shell: public Base { +class Shell : public Base { - TopoDS_Shell m_shell; -public: - int numFaces(); - - double area(); + TopoDS_Shell m_shell; +public: + int numFaces(); + double area(); - virtual const TopoDS_Shape& shape() const; - const TopoDS_Shell& shell() const { - return m_shell; - } - virtual void setShape(const TopoDS_Shape&); + virtual const TopoDS_Shape &shape() const; + const TopoDS_Shell &shell() const { return m_shell; } + virtual void setShape(const TopoDS_Shape &); - virtual Base* Unwrap(v8::Local obj) const { return Nan::ObjectWrap::Unwrap(obj); } - virtual v8::Local Clone() const ; + virtual Base *Unwrap(v8::Local obj) const { + return Nan::ObjectWrap::Unwrap(obj); + } + virtual v8::Local Clone() const; - static void Init(v8::Local target); - static NAN_METHOD(New); - static Nan::Persistent _template; + static NAN_METHOD(New); + static NAN_MODULE_INIT(Init); + static Nan::Persistent _template; }; \ No newline at end of file diff --git a/src/Solid.cc b/src/Solid.cc index f91359b..537855c 100644 --- a/src/Solid.cc +++ b/src/Solid.cc @@ -1,23 +1,19 @@ #include "Solid.h" -#include "Util.h" -#include "Face.h" -#include "Edge.h" #include "BoundingBox.h" - +#include "Edge.h" +#include "Face.h" +#include "Util.h" Nan::Persistent Solid::_template; -/*static*/ -void Solid::Init(v8::Local target) -{ - - +NAN_MODULE_INIT(Solid::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(Solid::New); + v8::Local tpl = + Nan::New(Solid::New); tpl->SetClassName(Nan::New("Solid").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -27,149 +23,133 @@ void Solid::Init(v8::Local target) Base::InitProto(proto); - EXPOSE_METHOD(Solid,getEdges); - EXPOSE_METHOD(Solid,getVertices); - EXPOSE_METHOD(Solid,getFaces); - EXPOSE_METHOD(Solid,getOuterShell); - EXPOSE_METHOD(Solid,getShells); - EXPOSE_METHOD(Solid,getSolids); - EXPOSE_METHOD(Solid,getShapeName); - EXPOSE_METHOD(Solid,getAdjacentFaces); - EXPOSE_METHOD(Solid,getCommonEdges); - EXPOSE_METHOD(Solid,createMesh); - - - EXPOSE_READ_ONLY_PROPERTY_DOUBLE (Solid,area); - EXPOSE_READ_ONLY_PROPERTY_DOUBLE (Solid,volume); - - EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numFaces); - EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numSolids); - EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numShells); - - EXPOSE_READ_ONLY_PROPERTY(_mesh,mesh); - EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Solid,hasMesh); - - Nan::Set(target, Nan::New("Solid").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); - + EXPOSE_METHOD(Solid, getEdges); + EXPOSE_METHOD(Solid, getVertices); + EXPOSE_METHOD(Solid, getFaces); + EXPOSE_METHOD(Solid, getOuterShell); + EXPOSE_METHOD(Solid, getShells); + EXPOSE_METHOD(Solid, getSolids); + EXPOSE_METHOD(Solid, getShapeName); + EXPOSE_METHOD(Solid, getAdjacentFaces); + EXPOSE_METHOD(Solid, getCommonEdges); + EXPOSE_METHOD(Solid, createMesh); + + EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid, area); + EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid, volume); + + EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numFaces); + EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numSolids); + EXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numShells); + + EXPOSE_READ_ONLY_PROPERTY(_mesh, mesh); + EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Solid, hasMesh); + + Nan::Set(target, Nan::New("Solid").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } - -NAN_METHOD(Solid::InitNew) -{ +NAN_METHOD(Solid::InitNew) { Shape::InitNew(info); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid,area); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid,volume); - REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numFaces); - REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numSolids); - REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid,numShells); - REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Solid,hasMesh); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid, area); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Solid, volume); + REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numFaces); + REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numSolids); + REXPOSE_READ_ONLY_PROPERTY_INTEGER(Solid, numShells); + REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Solid, hasMesh); } - -NAN_METHOD(Solid::New) -{ +NAN_METHOD(Solid::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Solid() to construct a Solid"); } - Solid* pThis = new Solid(); + Solid *pThis = new Solid(); pThis->Wrap(info.This()); pThis->InitNew(info); Nan::DefineOwnProperty( - info.This(), - Nan::New("faces").ToLocalChecked(), - Nan::New() , - (v8::PropertyAttribute)(v8::DontDelete|v8::ReadOnly)); + info.This(), Nan::New("faces").ToLocalChecked(), Nan::New(), + (v8::PropertyAttribute)(v8::DontDelete | v8::ReadOnly)); Nan::DefineOwnProperty( - info.This(), - Nan::New("_reversedMap").ToLocalChecked(), - Nan::New(), - (v8::PropertyAttribute)(v8::DontEnum|v8::DontDelete|v8::ReadOnly)); + info.This(), Nan::New("_reversedMap").ToLocalChecked(), + Nan::New(), + (v8::PropertyAttribute)(v8::DontEnum | v8::DontDelete | v8::ReadOnly)); - /// args.This()->SetAccessor(NanSymbol("_area"),ee< Solid, Number, double, &Solid::area>,0,Number::New(12),DEFAULT,None); + /// args.This()->SetAccessor(NanSymbol("_area"),ee< Solid, Number, double, + /// &Solid::area>,0,Number::New(12),DEFAULT,None); // return scope.Close(args.This()); info.GetReturnValue().Set(info.This()); } -v8::Local Solid::Clone() const -{ - v8::Local instance = Nan::To(Solid::NewInstance()).ToLocalChecked(); - Solid* pClone = Nan::ObjectWrap::Unwrap(instance); +v8::Local Solid::Clone() const { + + Nan::EscapableHandleScope scope; + v8::Local instance = makeInstance(_template); + Solid *pClone = Nan::ObjectWrap::Unwrap(instance); pClone->setShape(this->shape()); if (!this->shape().IsNull()) { TopTools_IndexedMapOfShape shapeMap; TopExp::MapShapes(this->shape(), TopAbs_FACE, shapeMap); - int nbSubShapes =shapeMap.Extent(); - + int nbSubShapes = shapeMap.Extent(); - for (int i=0; i::max()); + for (int i = 0; i < nbSubShapes; i++) { + int hc = shapeMap(i + 1).HashCode(std::numeric_limits::max()); // TODO pClone->_registerNamedShape(name, } } - - return instance; + return scope.Escape(instance); } -v8::Local Solid::NewInstance() -{ - v8::Local instance = makeInstance(Solid::_template); - Solid* pThis = Nan::ObjectWrap::Unwrap(instance); +v8::Local Solid::NewInstance() { + v8::Local instance = makeInstance(_template); + Solid *pThis = Nan::ObjectWrap::Unwrap(instance); return instance; } -v8::Local Solid::NewInstance(TopoDS_Shape shape) -{ - v8::Local instance = makeInstance(Solid::_template); - Solid* pThis = Nan::ObjectWrap::Unwrap(instance); +v8::Local Solid::NewInstance(TopoDS_Shape shape) { + v8::Local instance = makeInstance(_template); + Solid *pThis = Nan::ObjectWrap::Unwrap(instance); pThis->setShape(shape); return instance; } -NAN_METHOD(Solid::NewInstance) -{ +NAN_METHOD(Solid::NewInstance) { TopoDS_Shape shape; info.GetReturnValue().Set(NewInstance(shape)); } +NAN_METHOD(Solid::getEdges) { -NAN_METHOD(Solid::getEdges) -{ - - Solid* pThis = UNWRAP(Solid); + Solid *pThis = UNWRAP(Solid); TopTools_IndexedMapOfShape map; - // TopExp::MapShapes(pThis->shape(), TopAbs_EDGE, map); BRepTools::Map3DEdges(pThis->shape(), map); - int nbShape =map.Extent(); + int nbShape = map.Extent(); v8::Local arr = Nan::New(nbShape); - for (int i=0; i obj= buildWrapper(map(i+1)); // 1 based !!! - Nan::Set(arr,i,obj); + for (int i = 0; i < nbShape; i++) { + v8::Local obj = buildWrapper(map(i + 1)); // 1 based !!! + Nan::Set(arr, i, obj); } info.GetReturnValue().Set(arr); } -NAN_METHOD(Solid::getVertices) -{ - Solid* pThis = UNWRAP(Solid); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_VERTEX); +NAN_METHOD(Solid::getVertices) { + Solid *pThis = UNWRAP(Solid); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_VERTEX); info.GetReturnValue().Set(arr); } -NAN_METHOD(Solid::getOuterShell) -{ - Solid* pThis = UNWRAP(Solid); +NAN_METHOD(Solid::getOuterShell) { + Solid *pThis = UNWRAP(Solid); if (pThis->shape().ShapeType() == TopAbs_COMPOUND) { return; @@ -181,66 +161,58 @@ NAN_METHOD(Solid::getOuterShell) return info.GetReturnValue().Set(buildWrapper(shell)); } CATCH_AND_RETHROW("Failed to extract Outer Shell "); - } -NAN_METHOD(Solid::getFaces) -{ - Solid* pThis = UNWRAP(Solid); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_FACE); +NAN_METHOD(Solid::getFaces) { + Solid *pThis = UNWRAP(Solid); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_FACE); info.GetReturnValue().Set(arr); } - -NAN_METHOD(Solid::getSolids) -{ - Solid* pThis = UNWRAP(Solid); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_SOLID); +NAN_METHOD(Solid::getSolids) { + Solid *pThis = UNWRAP(Solid); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_SOLID); info.GetReturnValue().Set(arr); } -NAN_METHOD(Solid::getShells) -{ - Solid* pThis = UNWRAP(Solid); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_SHELL); +NAN_METHOD(Solid::getShells) { + Solid *pThis = UNWRAP(Solid); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_SHELL); info.GetReturnValue().Set(arr); } - /** * getAdjacentFace * returns an array of all faces that are adjacents to the given face */ -NAN_METHOD(Solid::getAdjacentFaces) -{ - Solid* pThis = UNWRAP(Solid); +NAN_METHOD(Solid::getAdjacentFaces) { + Solid *pThis = UNWRAP(Solid); - Face* pFace = 0 ; - if (!extractArg(info[0],pFace)) { + Face *pFace = 0; + if (!extractArg(info[0], pFace)) { return Nan::ThrowError("invalid arguments : expecting "); } assert(pFace); - TopTools_IndexedDataMapOfShapeListOfShape map; - TopExp::MapShapesAndAncestors(pThis->shape(),TopAbs_EDGE,TopAbs_FACE,map); - TopExp::MapShapesAndAncestors(pThis->shape(),TopAbs_EDGE,TopAbs_FACE,map); + TopExp::MapShapesAndAncestors(pThis->shape(), TopAbs_EDGE, TopAbs_FACE, map); + TopExp::MapShapesAndAncestors(pThis->shape(), TopAbs_EDGE, TopAbs_FACE, map); TopTools_MapOfShape auxmap; - TopExp_Explorer edgeExplorer(pFace->shape(),TopAbs_EDGE); + TopExp_Explorer edgeExplorer(pFace->shape(), TopAbs_EDGE); for (; edgeExplorer.More(); edgeExplorer.Next()) { TopoDS_Edge edge = TopoDS::Edge(edgeExplorer.Current()); - const TopTools_ListOfShape& list = map.FindFromKey(edge); + const TopTools_ListOfShape &list = map.FindFromKey(edge); // list of faces sh TopTools_ListIteratorOfListOfShape it(list); for (; it.More(); it.Next()) { - if (pFace->shape() != it.Value()) { - if(!auxmap.Contains(it.Value())) { + if (pFace->shape() != it.Value()) { + if (!auxmap.Contains(it.Value())) { auxmap.Add(it.Value()); } } @@ -253,29 +225,29 @@ NAN_METHOD(Solid::getAdjacentFaces) v8::Local arr = Nan::New(nbFaces); TopTools_MapIteratorOfMapOfShape it(auxmap); - int i=0; + int i = 0; for (; it.More(); it.Next()) { - const TopoDS_Shape& shape= it.Key(); - v8::Local obj= buildWrapper(shape); // 1 based !!! - Nan::Set(arr,i,obj); + const TopoDS_Shape &shape = it.Key(); + v8::Local obj = buildWrapper(shape); // 1 based !!! + Nan::Set(arr, i, obj); i++; } info.GetReturnValue().Set(arr); } +const char *getCommonEdges_Doc = "Solid.getCommonEdges(,);"; -const char* getCommonEdges_Doc = "Solid.getCommonEdges(,);"; - -NAN_METHOD(Solid::getCommonEdges) -{ - Solid* pThis = UNWRAP(Solid); +NAN_METHOD(Solid::getCommonEdges) { + Solid *pThis = UNWRAP(Solid); // , - Face* pFace1 = 0 ; - Face* pFace2 = 0 ; + Face *pFace1 = 0; + Face *pFace2 = 0; - if (info.Length()<2 || !extractArg(info[0],pFace1) || !extractArg(info[1],pFace2) ) { - return Nan::ThrowError("invalid arguments getCommonEdges : expecting ,"); + if (info.Length() < 2 || !extractArg(info[0], pFace1) || + !extractArg(info[1], pFace2)) { + return Nan::ThrowError( + "invalid arguments getCommonEdges : expecting ,"); } TopTools_IndexedDataMapOfShapeListOfShape map; @@ -284,58 +256,62 @@ NAN_METHOD(Solid::getCommonEdges) TopTools_MapOfShape edgeList; - TopExp_Explorer edgeExplorer(pThis->shape(),TopAbs_EDGE); + TopExp_Explorer edgeExplorer(pThis->shape(), TopAbs_EDGE); for (; edgeExplorer.More(); edgeExplorer.Next()) { TopoDS_Edge edge = TopoDS::Edge(edgeExplorer.Current()); - const TopTools_ListOfShape& list = map.FindFromKey(edge); + const TopTools_ListOfShape &list = map.FindFromKey(edge); TopTools_ListIteratorOfListOfShape it(list); int nbFound = 0; for (; it.More(); it.Next()) { - if (pFace1->shape() == it.Value()) { nbFound++; continue; } - if (pFace2->shape() == it.Value()) { nbFound++; continue; } + if (pFace1->shape() == it.Value()) { + nbFound++; + continue; + } + if (pFace2->shape() == it.Value()) { + nbFound++; + continue; + } } if (nbFound == 2) { // this is the common edge edgeList.Add(edge); } - } v8::Local arr = Nan::New(edgeList.Extent()); TopTools_MapIteratorOfMapOfShape it(edgeList); - int i=0; + int i = 0; for (; it.More(); it.Next()) { - const TopoDS_Edge& edge = TopoDS::Edge(it.Key()); - v8::Local obj= buildWrapper(edge); // 1 based !!! - Nan::Set(arr,i++,obj); + const TopoDS_Edge &edge = TopoDS::Edge(it.Key()); + v8::Local obj = buildWrapper(edge); // 1 based !!! + Nan::Set(arr, i++, obj); } info.GetReturnValue().Set(arr); } - -const char* getCommonVertices_Doc = "Solid.getCommonVertices(,);\n" -"Solid.getCommonVertices(,,);\n" -"Solid.getCommonVertices(,);\n"; - -NAN_METHOD(Solid::getCommonVertices) -{ - Face* pFace1 = 0 ; - Face* pFace2 = 0 ; - if (info.Length()<2 || !extractArg(info[0],pFace1) || !extractArg(info[1],pFace2) ) { - return Nan::ThrowError("invalid arguments getCommonEdges : expecting ,"); - } +const char *getCommonVertices_Doc = + "Solid.getCommonVertices(,);\n" + "Solid.getCommonVertices(,,);\n" + "Solid.getCommonVertices(,);\n"; + +NAN_METHOD(Solid::getCommonVertices) { + Face *pFace1 = 0; + Face *pFace2 = 0; + if (info.Length() < 2 || !extractArg(info[0], pFace1) || + !extractArg(info[1], pFace2)) { + return Nan::ThrowError( + "invalid arguments getCommonEdges : expecting ,"); + } v8::Local arr = v8::Array::New(0); Nan::ThrowError("Not Implemented "); info.GetReturnValue().Set(arr); } - -int Solid::numSolids() -{ - const TopoDS_Shape& shp = this->shape(); +int Solid::numSolids() { + const TopoDS_Shape &shp = this->shape(); if (shp.IsNull()) { return 0; } @@ -354,40 +330,33 @@ int Solid::numSolids() } } - -int Solid::numFaces() -{ +int Solid::numFaces() { TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(this->shape(), TopAbs_FACE, anIndices); return anIndices.Extent(); } -int Solid::numShells() -{ +int Solid::numShells() { TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(this->shape(), TopAbs_SHELL, anIndices); return anIndices.Extent(); } -double Solid::area() -{ +double Solid::area() { GProp_GProps prop; BRepGProp::SurfaceProperties(this->shape(), prop); return prop.Mass(); } -double Solid::volume() -{ +double Solid::volume() { GProp_GProps prop; BRepGProp::VolumeProperties(this->shape(), prop); return prop.Mass(); } -bool Solid::hasMesh() { - return !m_cacheMesh.IsEmpty(); -} +bool Solid::hasMesh() { return !m_cacheMesh.IsEmpty(); } -//DVec Solid::inertia() { +// DVec Solid::inertia() { // DVec ret; // GProp_GProps prop; // BRepGProp::VolumeProperties(this->shape(), prop); @@ -401,7 +370,7 @@ bool Solid::hasMesh() { // return ret; //} -//OCCStruct3d OCCSolid::centreOfMass() { +// OCCStruct3d OCCSolid::centreOfMass() { // OCCStruct3d ret; // GProp_GProps prop; // BRepGProp::VolumeProperties(this->getSolid(), prop); @@ -412,18 +381,15 @@ bool Solid::hasMesh() { // return ret; //} - -NAN_PROPERTY_GETTER(Solid::_mesh) -{ - Solid* pThis = UNWRAP(Solid); +NAN_PROPERTY_GETTER(Solid::_mesh) { + Solid *pThis = UNWRAP(Solid); if (pThis->m_cacheMesh.IsEmpty()) { - pThis->m_cacheMesh.Reset(pThis->createMesh(1,0.5,true)); + pThis->m_cacheMesh.Reset(pThis->createMesh(1, 0.5, true)); } info.GetReturnValue().Set(Nan::New(pThis->m_cacheMesh)); } - -//void Solid::Mesh() +// void Solid::Mesh() //{ // TopExp_Explorer Ex; // int numFaces = 0; @@ -435,145 +401,152 @@ NAN_PROPERTY_GETTER(Solid::_mesh) // BRepMesh().Mesh(shape_, 1.0); // } //} -v8::Local Solid::createMesh(double factor, double angle, bool qualityNormals) -{ +v8::Local Solid::createMesh(double factor, double angle, + bool qualityNormals) { Nan::EscapableHandleScope scope; const unsigned argc = 0; - v8::Local argv[1] = { }; + v8::Local argv[1] = {}; v8::Local theMesh = makeInstance(Mesh::_template); - Mesh *mesh = Mesh::Unwrap(theMesh); + Mesh *mesh = Mesh::Unwrap(theMesh); - const TopoDS_Shape& shape = this->shape(); + const TopoDS_Shape &shape = this->shape(); try { - if (angle == 0.0) { - BRepMesh_IncrementalMesh m1(shape,factor,Standard_True); - } else { - BRepMesh_IncrementalMesh m2(shape,factor,Standard_True,angle, Standard_True); - } - + if (angle == 0.0) { + BRepMesh_IncrementalMesh m1(shape, factor, Standard_True); + } else { + BRepMesh_IncrementalMesh m2(shape, factor, Standard_True, angle, + Standard_True); + } - if (shape.ShapeType() == TopAbs_COMPSOLID || shape.ShapeType() == TopAbs_COMPOUND) { - TopExp_Explorer exSolid, exFace; - for (exSolid.Init(shape, TopAbs_SOLID); exSolid.More(); exSolid.Next()) { - const TopoDS_Solid& solid = TopoDS::Solid(exSolid.Current()); - for (exFace.Init(solid, TopAbs_FACE); exFace.More(); exFace.Next()) { - const TopoDS_Face& face = TopoDS::Face(exFace.Current()); - if (face.IsNull()) continue; - mesh->extractFaceMesh(face, qualityNormals); - } - } - } else { - TopExp_Explorer exFace; - for (exFace.Init(shape, TopAbs_FACE); exFace.More(); exFace.Next()) { - - const TopoDS_Face& face = TopoDS::Face(exFace.Current()); - if (face.IsNull()) continue; - try { - mesh->extractFaceMesh(face, qualityNormals); - } catch(Standard_Failure const& anException) { - Standard_SStream aMsg; - aMsg << "EXCEPTION in mesh->extractFaceMesh" << endl; - aMsg << anException << endl; - Nan::ThrowError(aMsg.str().c_str()); - } - } + if (shape.ShapeType() == TopAbs_COMPSOLID || + shape.ShapeType() == TopAbs_COMPOUND) { + TopExp_Explorer exSolid, exFace; + for (exSolid.Init(shape, TopAbs_SOLID); exSolid.More(); exSolid.Next()) { + const TopoDS_Solid &solid = TopoDS::Solid(exSolid.Current()); + for (exFace.Init(solid, TopAbs_FACE); exFace.More(); exFace.Next()) { + const TopoDS_Face &face = TopoDS::Face(exFace.Current()); + if (face.IsNull()) + continue; + mesh->extractFaceMesh(face, qualityNormals); } + } + } else { + TopExp_Explorer exFace; + for (exFace.Init(shape, TopAbs_FACE); exFace.More(); exFace.Next()) { + + const TopoDS_Face &face = TopoDS::Face(exFace.Current()); + if (face.IsNull()) + continue; + try { + mesh->extractFaceMesh(face, qualityNormals); + } catch (Standard_Failure const &anException) { + Standard_SStream aMsg; + aMsg << "EXCEPTION in mesh->extractFaceMesh" << endl; + aMsg << anException << endl; + Nan::ThrowError(aMsg.str().c_str()); + } + } + } - mesh->optimize(); - - - } catch(Standard_Failure const& anException) { - Standard_SStream aMsg; - aMsg << "EXCEPTION in Solid::createMesh" << endl; - aMsg << anException << endl; - Nan::ThrowError(aMsg.str().c_str()); - } + mesh->optimize(); + } catch (Standard_Failure const &anException) { + Standard_SStream aMsg; + aMsg << "EXCEPTION in Solid::createMesh" << endl; + aMsg << anException << endl; + Nan::ThrowError(aMsg.str().c_str()); + } return scope.Escape(theMesh); } - -NAN_METHOD(Solid::getShapeName) -{ - Solid* pThis = UNWRAP(Solid); - pThis; +NAN_METHOD(Solid::getShapeName) { + Solid *pThis = UNWRAP(Solid); + // pThis; v8::Local pShape = Nan::To(info[0]).ToLocalChecked(); if (!pShape.IsEmpty()) { - v8::Local hashCode = Nan::Get(pShape, Nan::New("hashCode").ToLocalChecked()).ToLocalChecked(); - - auto _rm = Nan::Get(pJhis,Nan::New("_reversedMap").ToLocalChecked()).ToLocalChecked(); - v8::Local reversedMap = Nan::To(_rm).ToLocalChecked(); + v8::Local hashCode = + Nan::Get(pShape, Nan::New("hashCode").ToLocalChecked()) + .ToLocalChecked(); - v8::Local value = Nan::Get(reversedMap, hashCode).ToLocalChecked(); + auto _rm = Nan::Get(pJhis, Nan::New("_reversedMap").ToLocalChecked()) + .ToLocalChecked(); + v8::Local reversedMap = + Nan::To(_rm).ToLocalChecked(); + + v8::Local value = + Nan::Get(reversedMap, hashCode).ToLocalChecked(); info.GetReturnValue().Set(value); - } + } } -std::string Solid::_getShapeName(const TopoDS_Shape& shape) -{ - v8::Local pJhis = this->handle();// NanObjectWrapHandle(this); - - auto _rm = Nan::Get(pJhis,Nan::New("_reversedMap").ToLocalChecked()).ToLocalChecked(); - v8::Local reversedMap = Nan::To(_rm).ToLocalChecked(); +std::string Solid::_getShapeName(const TopoDS_Shape &shape) { - v8::Local hashCode = Nan::New(shape.HashCode(std::numeric_limits::max())); - v8::Local value = Nan::Get(reversedMap,hashCode).ToLocalChecked(); + v8::Local pJhis = this->handle(); // NanObjectWrapHandle(this); + + auto _rm = Nan::Get(pJhis, Nan::New("_reversedMap").ToLocalChecked()) + .ToLocalChecked(); + v8::Local reversedMap = Nan::To(_rm).ToLocalChecked(); + + v8::Local hashCode = + Nan::New(shape.HashCode(std::numeric_limits::max())); + v8::Local value = Nan::Get(reversedMap, hashCode).ToLocalChecked(); Nan::Utf8String s(value); std::string res(*s); return res; } -void Solid::_registerNamedShape(const char* name,const TopoDS_Shape& shape) -{ - if (shape.ShapeType() == TopAbs_FACE) { +void Solid::_registerNamedShape(const char *name, const TopoDS_Shape &shape) { + Nan::HandleScope scope; - v8::Local obj = - Nan::To( - Nan::Get(NanObjectWrapHandle(this), Nan::New("faces").ToLocalChecked()).ToLocalChecked() - ).ToLocalChecked(); - - Nan::Set(obj,Nan::New(name).ToLocalChecked(), Face::NewInstance(TopoDS::Face(shape))); - } + if (shape.ShapeType() == TopAbs_FACE) { + v8::Local obj = + Nan::To(Nan::Get(NanObjectWrapHandle(this), + Nan::New("faces").ToLocalChecked()) + .ToLocalChecked()) + .ToLocalChecked(); + + Nan::Set(obj, Nan::New(name).ToLocalChecked(), + Face::NewInstance(TopoDS::Face(shape))); + } - v8::Local pJhis = this->handle();// NanObjectWrapHandle(this); + v8::Local pJhis = this->handle(); // NanObjectWrapHandle(this); - auto _rm = Nan::Get(pJhis,Nan::New("_reversedMap").ToLocalChecked()).ToLocalChecked(); + auto _rm = Nan::Get(pJhis, Nan::New("_reversedMap").ToLocalChecked()) + .ToLocalChecked(); v8::Local reversedMap = Nan::To(_rm).ToLocalChecked(); - Nan::Set(reversedMap,shape.HashCode(std::numeric_limits::max()),Nan::New(name).ToLocalChecked()); + Nan::Set(reversedMap, shape.HashCode(std::numeric_limits::max()), + Nan::New(name).ToLocalChecked()); } - - -NAN_METHOD(Solid::createMesh) -{ - Solid* pThis = UNWRAP(Solid); +NAN_METHOD(Solid::createMesh) { + Solid *pThis = UNWRAP(Solid); double factor = 0.5; double angle = 0.0; - if (info.Length()>=1 && info[0]->IsNumber()) { - ReadDouble(info[0], factor); + if (info.Length() >= 1 && info[0]->IsNumber()) { + ReadDouble(info[0], factor); } - if (info.Length()>=2 && info[1]->IsNumber()) { - ReadDouble(info[1], angle); - //xx angle = angle*3.14159/180.0; + if (info.Length() >= 2 && info[1]->IsNumber()) { + ReadDouble(info[1], angle); + // xx angle = angle*3.14159/180.0; } - if (info.Length()>=3) { + if (info.Length() >= 3) { return Nan::ThrowError("invalid arguments ( factor|double, angle|degree)"); - } + } - v8::Local mesh = pThis->createMesh(factor,angle,true); + v8::Local mesh = pThis->createMesh(factor, angle, true); if (pThis->m_cacheMesh.IsEmpty()) { - pThis->m_cacheMesh.Reset(mesh); + pThis->m_cacheMesh.Reset(mesh); } info.GetReturnValue().Set(mesh); diff --git a/src/Solid.h b/src/Solid.h index b657a6d..836c7b2 100644 --- a/src/Solid.h +++ b/src/Solid.h @@ -1,26 +1,24 @@ #pragma once -#include "Shape.h" #include "Mesh.h" +#include "Shape.h" class Edge; // a multi body shape class Solid : public Shape { protected: - Solid() {}; - virtual ~Solid() { - m_cacheMesh.Reset(); - }; + Solid(){}; + virtual ~Solid() { m_cacheMesh.Reset(); }; public: - virtual v8::Local Clone() const; - virtual Base* Unwrap(v8::Local obj) const { return Nan::ObjectWrap::Unwrap(obj); } + virtual v8::Local Clone() const; + virtual Base *Unwrap(v8::Local obj) const { + return Nan::ObjectWrap::Unwrap(obj); + } Nan::Persistent m_cacheMesh; - const TopoDS_Solid& solid() const { - return TopoDS::Solid(shape()); - } + const TopoDS_Solid &solid() const { return TopoDS::Solid(shape()); } int numSolids(); int numFaces(); @@ -32,7 +30,8 @@ class Solid : public Shape { virtual void InitNew(_NAN_METHOD_ARGS); - v8::Local createMesh(double factor, double angle, bool qualityNormals = true); + v8::Local createMesh(double factor, double angle, + bool qualityNormals = true); typedef enum BoolOpType { BOOL_FUSE, @@ -41,10 +40,11 @@ class Solid : public Shape { } BoolOpType; int boolean(Solid *tool, BoolOpType op); - //xx int chamfer(const std::vector& edges, const std::vector& distances); - //xx int fillet(const std::vector& edges, const std::vector& distances); + // xx int chamfer(const std::vector& edges, const std::vector& + // distances); xx int fillet(const std::vector& edges, const + // std::vector& distances); -// static Handle fillet(const v8::Arguments& args); + // static Handle fillet(const v8::Arguments& args); // static Handle chamfer(const v8::Arguments& args); // default mesh @@ -63,19 +63,15 @@ class Solid : public Shape { static NAN_METHOD(getCommonEdges); static NAN_METHOD(getCommonVertices); - // Methods exposed to JavaScripts - static void Init(v8::Local target); - + static NAN_MODULE_INIT(Init); static NAN_METHOD(New); static NAN_METHOD(NewInstance); - static v8::Local NewInstance(TopoDS_Shape shape); - static v8::Local NewInstance(); + static v8::Local NewInstance(TopoDS_Shape shape); + static v8::Local NewInstance(); static Nan::Persistent _template; - void _registerNamedShape(const char* name, const TopoDS_Shape& shape); - std::string _getShapeName(const TopoDS_Shape& shape); - + void _registerNamedShape(const char *name, const TopoDS_Shape &shape); + std::string _getShapeName(const TopoDS_Shape &shape); }; - diff --git a/src/Tools.cc b/src/Tools.cc index 1734d1a..5d01b0f 100644 --- a/src/Tools.cc +++ b/src/Tools.cc @@ -5,35 +5,32 @@ #include "Shape.h" #include "Solid.h" +#include "AsyncWorkerWithProgress.h" #include #include -#include "AsyncWorkerWithProgress.h" // // ref : http://nikhilm.github.io/uvbook/threads.html // -void extractShapes(v8::Local value, std::list& shapes) -{ +void extractShapes(v8::Local value, std::list &shapes) { + if (value->IsArray()) { v8::Local arr = v8::Local::Cast(value); for (uint32_t i = 0; i < arr->Length(); i++) { - auto elementI = Nan::Get(arr,i).ToLocalChecked(); + auto elementI = Nan::Get(arr, i).ToLocalChecked(); extractShapes(elementI, shapes); } - } - else if (value->IsObject()) { + } else if (value->IsObject()) { // it must be of type v8::Local obj = Nan::To(value).ToLocalChecked(); if (IsInstanceOf(obj)) { shapes.push_back(Nan::ObjectWrap::Unwrap(obj)); } - } } -static bool extractFileName(const v8::Local& value, std::string& filename) -{ +static bool extractFileName(v8::Local value, std::string &filename) { // first argument is filename if (!value->IsString()) { return false; @@ -43,24 +40,73 @@ static bool extractFileName(const v8::Local& value, std::string& file return true; } -static bool extractCallback(const v8::Local& value, v8::Local& callback) -{ - if (!value->IsFunction()) { +static bool extractCallback(v8::Local value, + v8::Local &callback) { + if (value.IsEmpty() || !value->IsFunction()) { return false; } callback = Nan::To(value).ToLocalChecked(); return true; } +NAN_METHOD(writeGLTF) { + std::string filename; + if (!extractFileName(info[0], filename)) { + return Nan::ThrowError("expecting a file name"); + } + + std::list shapes; + for (int i = 1; i < info.Length(); i++) { + extractShapes(info[i], shapes); + } + + if (shapes.size() == 0) { + return info.GetReturnValue().Set(Nan::New(false)); + } + + // make a coumpound + BRep_Builder B; + TopoDS_Compound compound; + B.MakeCompound(compound); + for (std::list::iterator it = shapes.begin(); it != shapes.end(); + it++) { + TopoDS_Shape shape = (*it)->shape(); + B.Add(compound, shape); + } + + TColStd_IndexedDataMapOfStringString aMetadata; + + occHandle(XCAFApp_Application) app = XCAFApp_Application::GetApplication(); + occHandle(TDocStd_Document) doc = + new TDocStd_Document(TCollection_ExtendedString("XmlOcaf")); + app->InitDocument(doc); -NAN_METHOD(writeSTEP) -{ + auto tool = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); + tool->SetAutoNaming(false); + + auto label = tool->NewShape(); + + const double tolerance = 0.001; + const double angularTolerance = 0.1; + if (!BRepTools::Triangulation(compound, tolerance)) { + BRepMesh_IncrementalMesh(compound, tolerance, true, angularTolerance); + } + tool->SetShape(label, compound); + + bool isBinary = true; + RWGltf_CafWriter writer(filename.c_str(), isBinary); + auto ret = writer.Perform(doc, TColStd_IndexedDataMapOfStringString(), + Message_ProgressRange()); + + info.GetReturnValue().Set(Nan::New(true)); +} +NAN_METHOD(writeSTEP) { std::string filename; if (!extractFileName(info[0], filename)) { return Nan::ThrowError("expecting a file name"); } - std::list shapes; + std::list shapes; for (int i = 1; i < info.Length(); i++) { extractShapes(info[i], shapes); } @@ -73,28 +119,29 @@ NAN_METHOD(writeSTEP) STEPControl_Writer writer; IFSelect_ReturnStatus status; - //xx Interface_Static::SetCVal("xstep.cascade.unit","M"); - //xx Interface_Static::SetIVal("read.step.nonmanifold", 1); + // xx Interface_Static::SetCVal("xstep.cascade.unit","M"); + // xx Interface_Static::SetIVal("read.step.nonmanifold", 1); - for (std::list::iterator it = shapes.begin(); it != shapes.end(); it++) { + for (std::list::iterator it = shapes.begin(); it != shapes.end(); + it++) { status = writer.Transfer((*it)->shape(), STEPControl_AsIs); if (status != IFSelect_RetDone) { return Nan::ThrowError("Failed to write STEP file"); } } status = writer.Write(filename.c_str()); - } CATCH_AND_RETHROW("Failed to write STEP file "); + } + CATCH_AND_RETHROW("Failed to write STEP file "); info.GetReturnValue().Set(Nan::New(true)); } -NAN_METHOD(writeBREP) -{ +NAN_METHOD(writeBREP) { std::string filename; if (!extractFileName(info[0], filename)) { return Nan::ThrowError("expecting a file name"); } - std::list shapes; + std::list shapes; for (int i = 1; i < info.Length(); i++) { extractShapes(info[i], shapes); } @@ -107,22 +154,23 @@ NAN_METHOD(writeBREP) BRep_Builder B; TopoDS_Compound C; B.MakeCompound(C); - for (std::list::iterator it = shapes.begin(); it != shapes.end(); it++) { + for (std::list::iterator it = shapes.begin(); it != shapes.end(); + it++) { TopoDS_Shape shape = (*it)->shape(); B.Add(C, shape); } BRepTools::Write(C, filename.c_str()); - } CATCH_AND_RETHROW("Failed to write BREP file "); + } + CATCH_AND_RETHROW("Failed to write BREP file "); info.GetReturnValue().Set(Nan::New(true)); } -NAN_METHOD(writeSTL) -{ +NAN_METHOD(writeSTL) { std::string filename; if (!extractFileName(info[0], filename)) { return Nan::ThrowError("expecting a file name"); } - std::list shapes; + std::list shapes; for (int i = 1; i < info.Length(); i++) { extractShapes(info[i], shapes); } @@ -134,7 +182,8 @@ NAN_METHOD(writeSTL) BRep_Builder B; TopoDS_Compound C; B.MakeCompound(C); - for (std::list::iterator it = shapes.begin(); it != shapes.end(); it++) { + for (std::list::iterator it = shapes.begin(); it != shapes.end(); + it++) { TopoDS_Shape shape = (*it)->shape(); B.Add(C, shape); } @@ -142,42 +191,35 @@ NAN_METHOD(writeSTL) StlAPI_Writer writer; writer.ASCIIMode() = Standard_False; writer.Write(C, filename.c_str()); - - } CATCH_AND_RETHROW("Failed to write STL file "); + } + CATCH_AND_RETHROW("Failed to write STL file "); info.GetReturnValue().Set(Nan::New(true)); } - - -static int extractSubShape(const TopoDS_Shape& shape, std::list >& shapes) -{ +static int extractSubShape(const TopoDS_Shape &shape, + std::list> &shapes) { TopAbs_ShapeEnum type = shape.ShapeType(); - switch (type) - { + switch (type) { case TopAbs_COMPOUND: return 0; case TopAbs_COMPSOLID: - case TopAbs_SOLID: - { - shapes.push_back(Nan::To(Solid::NewInstance(shape)).ToLocalChecked()); + case TopAbs_SOLID: { + shapes.push_back( + Nan::To(Solid::NewInstance(shape)).ToLocalChecked()); break; } case TopAbs_FACE: - case TopAbs_SHELL: - { + case TopAbs_SHELL: { break; } - case TopAbs_WIRE: - { + case TopAbs_WIRE: { break; } - case TopAbs_EDGE: - { + case TopAbs_EDGE: { break; } - case TopAbs_VERTEX: - { + case TopAbs_VERTEX: { break; } default: @@ -186,8 +228,9 @@ static int extractSubShape(const TopoDS_Shape& shape, std::list >& shapes) -{ +static int extractShape(const TopoDS_Shape &shape, + std::list> &shapes) { + TopAbs_ShapeEnum type = shape.ShapeType(); if (type != TopAbs_COMPOUND) { @@ -229,91 +272,74 @@ static int extractShape(const TopoDS_Shape& shape, std::list convert(std::list > & shapes) { +static v8::Local convert(std::list> &shapes) { + Nan::EscapableHandleScope scope; + v8::Local arr = Nan::New((int)shapes.size()); int i = 0; - for (std::list >::iterator it = shapes.begin(); it != shapes.end(); it++) { - Nan::Set(arr,i, *it); + for (std::list>::iterator it = shapes.begin(); + it != shapes.end(); it++) { + Nan::Set(arr, i, *it); i++; } - return arr; + return scope.Escape(arr); } - bool mutex_initialised = false; -uv_mutex_t stepOperation_mutex = { 0 }; +uv_mutex_t stepOperation_mutex = {0}; + +class MutexLocker { + uv_mutex_t &m_mutex; -class MutexLocker -{ - uv_mutex_t& m_mutex; public: - MutexLocker(uv_mutex_t& mutex) - :m_mutex(mutex) - { - uv_mutex_lock(&m_mutex); - } - ~MutexLocker() - { - uv_mutex_unlock(&m_mutex); - } + MutexLocker(uv_mutex_t &mutex) : m_mutex(mutex) { uv_mutex_lock(&m_mutex); } + ~MutexLocker() { uv_mutex_unlock(&m_mutex); } }; +class MyProgressIndicator : public Message_ProgressIndicator { + ProgressData *m_data; + AsyncWorkerWithProgress *_worker; - - -class MyProgressIndicator : public Message_ProgressIndicator -{ - ProgressData* m_data; - AsyncWorkerWithProgress* _worker; public: - MyProgressIndicator(AsyncWorkerWithProgress* worker); + MyProgressIndicator(AsyncWorkerWithProgress *worker); void notify_progress(); - virtual void Show( - const Message_ProgressScope& theScope, - const Standard_Boolean isForce); + virtual void Show(const Message_ProgressScope &theScope, + const Standard_Boolean isForce); }; - -MyProgressIndicator::MyProgressIndicator(AsyncWorkerWithProgress* worker) - :Message_ProgressIndicator(), _worker(worker) -{ +MyProgressIndicator::MyProgressIndicator(AsyncWorkerWithProgress *worker) + : Message_ProgressIndicator(), _worker(worker) { m_data = &_worker->m_data; } - -void MyProgressIndicator::Show(const Message_ProgressScope& scope, const Standard_Boolean force) -{ +void MyProgressIndicator::Show(const Message_ProgressScope &scope, + const Standard_Boolean force) { double value = this->GetPosition(); double delta = (value - this->m_data->m_lastValue); if (delta > 0.01) { this->m_data->m_percent = value; - this->m_data->m_progress = int(delta * 1000);// this->GetPosition(); + this->m_data->m_progress = int(delta * 1000); // this->GetPosition(); this->m_data->m_lastValue = value; this->_worker->send_notify_progress(); - } } - - - - -//http://free-cad.sourceforge.net/SrcDocu/df/d7b/ImportStep_8cpp_source.html - +// http://free-cad.sourceforge.net/SrcDocu/df/d7b/ImportStep_8cpp_source.html class StepBrepAsyncReadWorker : public AsyncWorkerWithProgress { protected: - StepBrepAsyncReadWorker(Nan::Callback *callback, Nan::Callback* progressCallback, std::string* pfilename) - : AsyncWorkerWithProgress(callback, progressCallback, pfilename) - { - } + StepBrepAsyncReadWorker(Nan::Callback *callback, + Nan::Callback *progressCallback, + std::string *pfilename) + : AsyncWorkerWithProgress(callback, progressCallback, pfilename) {} virtual void WorkComplete(); + protected: int _retValue; - std::list shapes; + std::list shapes; }; void StepBrepAsyncReadWorker::WorkComplete() { @@ -323,64 +349,56 @@ void StepBrepAsyncReadWorker::WorkComplete() { try { - std::list > jsshapes; + std::list> jsshapes; - for (std::list::iterator it = shapes.begin(); it != shapes.end(); it++) { - const TopoDS_Shape& aShape = (*it); + for (std::list::iterator it = shapes.begin(); + it != shapes.end(); it++) { + const TopoDS_Shape &aShape = (*it); extractShape(aShape, jsshapes); } v8::Local arr = convert(jsshapes); - v8::Local err = Nan::Null(); - v8::Local argv[2] = { err, arr }; + v8::Local err = Nan::Null(); + v8::Local argv[2] = {err, arr}; callback->Call(2, argv, async_resource); - - } - catch (...) { + } catch (...) { this->SetErrorMessage(" exception in trying to build shapes"); return this->AsyncWorkerWithProgress::WorkComplete(); } - } - else { + } else { return this->AsyncWorkerWithProgress::WorkComplete(); } } class StepAsyncReadWorker : public StepBrepAsyncReadWorker { public: - StepAsyncReadWorker(Nan::Callback *callback, Nan::Callback* progressCallback, std::string* pfilename) - : StepBrepAsyncReadWorker(callback, progressCallback, pfilename) - { - } - ~StepAsyncReadWorker() { - } + StepAsyncReadWorker(Nan::Callback *callback, Nan::Callback *progressCallback, + std::string *pfilename) + : StepBrepAsyncReadWorker(callback, progressCallback, pfilename) {} + ~StepAsyncReadWorker() {} virtual void Execute(); }; - - // https://unlimited3d.wordpress.com/2020/10/17/progress-indication-changes-in-occt-7-5-0/ void StepAsyncReadWorker::Execute() { MutexLocker _locker(stepOperation_mutex); - void* data = request.data; + void *data = request.data; this->_retValue = 0; try { STEPControl_Reader aReader; - - Interface_Static::SetCVal("xstep.cascade.unit", "mm"); - Interface_Static::SetIVal("read.step.nonmanifold", 1); + Interface_Static::SetCVal("xstep.cascade.unit", "mm"); + Interface_Static::SetIVal("read.step.nonmanifold", 1); Interface_Static::SetIVal("read.step.product.mode", 1); - if (aReader.ReadFile(_filename.c_str()) != IFSelect_RetDone) { std::stringstream str; @@ -393,12 +411,9 @@ void StepAsyncReadWorker::Execute() { // progress->EndScope(); this->_retValue = 1; return; - } - - // aReader.WS()->MapReader()->SetProgress(progress); - + // aReader.WS()->MapReader()->SetProgress(progress); // Root transfers int nbr = aReader.NbRootsForTransfer(); @@ -415,11 +430,10 @@ void StepAsyncReadWorker::Execute() { if (!ok || nbs == 0) { continue; // skip empty root } - // if ((n + 1) % mod == 0) { progress->Increment(); } + // if ((n + 1) % mod == 0) { progress->Increment(); } } - // aReader.WS()->MapReader()->SetProgress(0); - + // aReader.WS()->MapReader()->SetProgress(0); TopoDS_Shape aResShape; BRep_Builder B; @@ -428,11 +442,10 @@ void StepAsyncReadWorker::Execute() { int nbs = aReader.NbShapes(); for (int i = 1; i <= nbs; i++) { - const TopoDS_Shape& aShape = aReader.Shape(i); - + const TopoDS_Shape &aShape = aReader.Shape(i); if (aShape.ShapeType() == TopAbs_SOLID) { - ShapeFix_Solid fix((const TopoDS_Solid&)aShape); + ShapeFix_Solid fix((const TopoDS_Solid &)aShape); fix.Perform(); } B.Add(compound, aShape); @@ -450,13 +463,15 @@ void StepAsyncReadWorker::Execute() { if (!TR.IsNull()) { occHandle(Transfer_TransientProcess) TP = TR->TransientProcess(); occHandle(Standard_Type) tPD = STANDARD_TYPE(StepBasic_ProductDefinition); - occHandle(Standard_Type) tNAUO = STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence); - occHandle(Standard_Type) tShape = STANDARD_TYPE(StepShape_TopologicalRepresentationItem); - occHandle(Standard_Type) tGeom = STANDARD_TYPE(StepGeom_GeometricRepresentationItem); + occHandle(Standard_Type) tNAUO = + STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence); + occHandle(Standard_Type) tShape = + STANDARD_TYPE(StepShape_TopologicalRepresentationItem); + occHandle(Standard_Type) tGeom = + STANDARD_TYPE(StepGeom_GeometricRepresentationItem); Standard_Integer nb = Model->NbEntities(); - for (Standard_Integer ie = 1; ie <= nb; ie++) { occHandle(Standard_Transient) enti = Model->Value(ie); @@ -464,45 +479,52 @@ void StepAsyncReadWorker::Execute() { occHandle(TCollection_HAsciiString) aName; if (enti->DynamicType() == tNAUO) { - occHandle(StepRepr_NextAssemblyUsageOccurrence) NAUO = occHandle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(enti); - if (NAUO.IsNull()) continue; - - // Interface_EntityIterator subs = aReader.WS()->Graph().Sharings(NAUO); - auto subs = aReader.WS()->Graph().Sharings(NAUO); + occHandle(StepRepr_NextAssemblyUsageOccurrence) NAUO = + occHandle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(enti); + if (NAUO.IsNull()) + continue; + + // Interface_EntityIterator subs = + // aReader.WS()->Graph().Sharings(NAUO); + auto subs = aReader.WS()->Graph().Sharings(NAUO); for (subs.Start(); subs.More(); subs.Next()) { - occHandle(StepRepr_ProductDefinitionShape) PDS = occHandle(StepRepr_ProductDefinitionShape)::DownCast(subs.Value()); - if (PDS.IsNull()) continue; - occHandle(StepBasic_ProductDefinitionRelationship) PDR = PDS->Definition().ProductDefinitionRelationship(); - if (PDR.IsNull()) continue; + occHandle(StepRepr_ProductDefinitionShape) PDS = occHandle( + StepRepr_ProductDefinitionShape)::DownCast(subs.Value()); + if (PDS.IsNull()) + continue; + occHandle(StepBasic_ProductDefinitionRelationship) PDR = + PDS->Definition().ProductDefinitionRelationship(); + if (PDR.IsNull()) + continue; if (PDR->HasDescription() && PDR->Description()->Length() > 0) { aName = PDR->Description(); - } - else if (PDR->Name()->Length() > 0) { + } else if (PDR->Name()->Length() > 0) { aName = PDR->Name(); - } - else { + } else { aName = PDR->Id(); } } // find proper label TCollection_ExtendedString str(aName->String()); - } - else if (enti->IsKind(tShape) || enti->IsKind(tGeom)) { - aName = occHandle(StepRepr_RepresentationItem)::DownCast(enti)->Name(); - } - else if (enti->DynamicType() == tPD) { - occHandle(StepBasic_ProductDefinition) PD = occHandle(StepBasic_ProductDefinition)::DownCast(enti); - if (PD.IsNull()) continue; + } else if (enti->IsKind(tShape) || enti->IsKind(tGeom)) { + aName = + occHandle(StepRepr_RepresentationItem)::DownCast(enti)->Name(); + } else if (enti->DynamicType() == tPD) { + occHandle(StepBasic_ProductDefinition) PD = + occHandle(StepBasic_ProductDefinition)::DownCast(enti); + if (PD.IsNull()) + continue; occHandle(StepBasic_Product) Prod = PD->Formation()->OfProduct(); aName = Prod->Name(); - } - else { + } else { continue; } if (aName->UsefullLength() < 1) continue; // skip 'N0NE' name - if (aName->UsefullLength() == 4 && toupper(aName->Value(1)) == 'N' &&toupper(aName->Value(2)) == 'O' && toupper(aName->Value(3)) == 'N' && toupper(aName->Value(4)) == 'E') + if (aName->UsefullLength() == 4 && toupper(aName->Value(1)) == 'N' && + toupper(aName->Value(2)) == 'O' && + toupper(aName->Value(3)) == 'N' && toupper(aName->Value(4)) == 'E') continue; /* // special check to pass names like "Open CASCADE STEP translator 6.3 1" @@ -517,10 +539,12 @@ void StepAsyncReadWorker::Execute() { // find target shape occHandle(Transfer_Binder) binder = TP->Find(enti); - if (binder.IsNull()) continue; + if (binder.IsNull()) + continue; TopoDS_Shape S = TransferBRep::ShapeResult(binder); - if (S.IsNull()) continue; + if (S.IsNull()) + continue; // as PRODUCT can be included in the main shape // several times, we look here for all inclusions. Standard_Integer isub, nbSubs = anIndices.Extent(); @@ -528,7 +552,8 @@ void StepAsyncReadWorker::Execute() { TopoDS_Shape aSub = anIndices.FindKey(isub); if (aSub.IsPartner(S)) { - //xx cout << " name of part =" << aName->ToCString() << " shape " << HashCode(aSub, -1) << " " << aSub.ShapeType() << endl; + // xx cout << " name of part =" << aName->ToCString() << " shape " + // << HashCode(aSub, -1) << " " << aSub.ShapeType() << endl; #if 0 // create label and set shape if (L.IsNull()) { @@ -543,46 +568,50 @@ void StepAsyncReadWorker::Execute() { #endif } } - } // END: Store names } - } - catch (...) { + } catch (...) { std::cerr << " EXCEPTION in READ STEP" << std::endl; this->SetErrorMessage("2 - caught C++ exception in readStep"); this->_retValue = 2; return; } - } -void readStepAsync(const std::string& filename, v8::Local _callback, v8::Local _progressCallback) -{ - Nan::Callback* callback = new Nan::Callback(_callback); - Nan::Callback* progressCallback = _progressCallback.IsEmpty() ? nullptr : new Nan::Callback(_progressCallback); - std::string* pfilename = new std::string(filename); - Nan::AsyncQueueWorker(new StepAsyncReadWorker(callback, progressCallback, pfilename)); +void readStepAsync(const std::string &filename, + v8::Local _callback, + v8::Local _progressCallback) { + Nan::Callback *callback = new Nan::Callback(_callback); + Nan::Callback *progressCallback = _progressCallback.IsEmpty() + ? nullptr + : new Nan::Callback(_progressCallback); + std::string *pfilename = new std::string(filename); + Nan::AsyncQueueWorker( + new StepAsyncReadWorker(callback, progressCallback, pfilename)); } -NAN_METHOD(readSTEP) -{ - if (!mutex_initialised) { uv_mutex_init(&stepOperation_mutex); mutex_initialised = true; } +NAN_METHOD(readSTEP) { + if (!mutex_initialised) { + uv_mutex_init(&stepOperation_mutex); + mutex_initialised = true; + } std::string filename; if (!extractFileName(info[0], filename)) { return Nan::ThrowError("expecting a file name"); } - v8::Local callback; if (!extractCallback(info[1], callback)) { return Nan::ThrowError("expecting a callback function"); } - v8::Local progressCallback; - if (!extractCallback(info[2], progressCallback)) { + + if (!extractCallback(info[2], progressCallback)) + + { // OPTIONAL !!! // Nan::ThrowError("expecting a callback function"); } @@ -590,26 +619,17 @@ NAN_METHOD(readSTEP) readStepAsync(filename, callback, progressCallback); } - - class BRepAsyncReadWorker : public StepBrepAsyncReadWorker { public: - BRepAsyncReadWorker(Nan::Callback *callback, Nan::Callback* progressCallback, std::string* pfilename) - : StepBrepAsyncReadWorker(callback, progressCallback, pfilename) - { - } - ~BRepAsyncReadWorker() { - - } + BRepAsyncReadWorker(Nan::Callback *callback, Nan::Callback *progressCallback, + std::string *pfilename) + : StepBrepAsyncReadWorker(callback, progressCallback, pfilename) {} + ~BRepAsyncReadWorker() {} void Execute(); - }; - -void BRepAsyncReadWorker::Execute() -{ - +void BRepAsyncReadWorker::Execute() { this->_retValue = 0; std::string filename = this->_filename; @@ -630,37 +650,43 @@ void BRepAsyncReadWorker::Execute() return; } this->shapes.push_back(shape); - } - catch (...) { + } catch (...) { this->SetErrorMessage("2 ( caught C++ exception in _readBREPAsync"); this->_retValue = 2; return; } } -void readBREPAsync(const std::string& filename, v8::Local _callback, v8::Local _progressCallback) -{ - Nan::Callback* callback = new Nan::Callback(_callback); - Nan::Callback* progressCallback = _progressCallback.IsEmpty() ? nullptr : new Nan::Callback(_progressCallback); - std::string* pfilename = new std::string(filename); - - Nan::AsyncQueueWorker(new BRepAsyncReadWorker(callback, progressCallback, pfilename)); - +void readBREPAsync(const std::string &filename, + v8::Local _callback, + v8::Local _progressCallback) { + Nan::Callback *callback = new Nan::Callback(_callback); + Nan::Callback *progressCallback = _progressCallback.IsEmpty() + ? nullptr + : new Nan::Callback(_progressCallback); + std::string *pfilename = new std::string(filename); + + Nan::AsyncQueueWorker( + new BRepAsyncReadWorker(callback, progressCallback, pfilename)); } +NAN_METHOD(readBREP) { -NAN_METHOD(readBREP) -{ - + if (info.Length() == 0 || info[0].IsEmpty()) { + return Nan::ThrowError("expecting one argument"); + } std::string filename; if (!extractFileName(info[0], filename)) { return Nan::ThrowError("expecting a file name"); } + v8::Local callback; + if (!extractCallback(info[1], callback)) { return Nan::ThrowError("expecting a callback function"); } v8::Local progressCallback; + if (!extractCallback(info[2], progressCallback)) { // OPTIONAL !!! // return Nan::ThrowError("expecting a callback function"); @@ -669,6 +695,3 @@ NAN_METHOD(readBREP) info.GetReturnValue().SetUndefined(); } - - - diff --git a/src/Tools.h b/src/Tools.h index 43d9df3..6a83a8a 100644 --- a/src/Tools.h +++ b/src/Tools.h @@ -1,5 +1,5 @@ -#include "OCC.h" #include "NodeV8.h" +#include "OCC.h" NAN_METHOD(writeSTEP); NAN_METHOD(readSTEP); diff --git a/src/Transform.cc b/src/Transform.cc index f3ed1bb..9b8c66d 100644 --- a/src/Transform.cc +++ b/src/Transform.cc @@ -3,17 +3,17 @@ //#include "Transform.h" //#include "Util.h" // -//using namespace std; +// using namespace std; // // //// -//Transform::Transform(TopoDS_Shape shape) +// Transform::Transform(TopoDS_Shape shape) //{ // shape_ = shape; //} // // -//TopoDS_Shape RotateTransform::apply( +// TopoDS_Shape RotateTransform::apply( // double multiplier, // Handle origin, // Handle parameters) @@ -41,7 +41,7 @@ // return BRepBuilderAPI_Transform(shape_, transformation).Shape(); //} -//TopoDS_Shape Scale::apply(double multiplier, +// TopoDS_Shape Scale::apply(double multiplier, // Handle origin, // Handle parameters) { // @@ -57,7 +57,7 @@ // //} -//TopoDS_Shape AxisMirror::apply(double multiplier, +// TopoDS_Shape AxisMirror::apply(double multiplier, // Handle origin, // Handle parameters) { // @@ -73,7 +73,7 @@ // return BRepBuilderAPI_Transform(shape_, transformation).Shape(); // //} -//TopoDS_Shape PlaneMirror::apply(double multiplier, +// TopoDS_Shape PlaneMirror::apply(double multiplier, // Handle origin, // Handle parameters) { // @@ -90,7 +90,7 @@ // //} -//TopoDS_Shape TranslateTransform::apply(double multiplier, +// TopoDS_Shape TranslateTransform::apply(double multiplier, // Handle origin, // Handle parameters) { // diff --git a/src/Transform.h b/src/Transform.h index 15498c8..546ed41 100644 --- a/src/Transform.h +++ b/src/Transform.h @@ -3,13 +3,13 @@ // //#include "OCC.h" // -//using namespace std; +// using namespace std; // // -//template -//class Transformer { +// template +// class Transformer { // -//public: +// public: // Transformer(TopoDS_Shape shape, // Handle origin, // Handle parameters) @@ -23,7 +23,7 @@ // } // // -//private: +// private: // TopoDS_Shape transformed_shape_; // // template @@ -54,9 +54,11 @@ // TopoDS_Shape shape_to_copy = copies[group_index]; // // auto_ptr transform(new T(shape_to_copy)); -// TopoDS_Shape transformedShape = transform->apply(multiplier, origin, parameters); +// TopoDS_Shape transformedShape = transform->apply(multiplier, +// origin, parameters); // -// copies[index] = BRepAlgoAPI_Fuse(transformedShape, copies[index - 1]).Shape(); +// copies[index] = BRepAlgoAPI_Fuse(transformedShape, copies[index - +// 1]).Shape(); // // multiplier = multiplier + grouping; // remaining = remaining - grouping; @@ -75,10 +77,10 @@ // //}; // -//class Transform { -//protected: +// class Transform { +// protected: // TopoDS_Shape shape_; -//public: +// public: // Transform(TopoDS_Shape shape); // virtual ~Transform() {}; // @@ -87,9 +89,9 @@ // Handle parameters) = 0; //}; // -//class RotateTransform : public Transform { +// class RotateTransform : public Transform { // -//public: +// public: // RotateTransform(TopoDS_Shape shape) : Transform(shape) {} // virtual ~RotateTransform() {}; // @@ -99,9 +101,9 @@ //}; // // -//class Scale : public Transform { +// class Scale : public Transform { // -//public: +// public: // Scale(TopoDS_Shape shape) : Transform(shape) {} // virtual ~Scale() {}; // @@ -110,9 +112,9 @@ // Handle parameters); //}; // -//class AxisMirror : public Transform { +// class AxisMirror : public Transform { // -//public: +// public: // AxisMirror(TopoDS_Shape shape) : Transform(shape) {} // virtual ~AxisMirror() {}; // @@ -121,9 +123,9 @@ // Handle parameters); //}; // -//class PlaneMirror : public Transform { +// class PlaneMirror : public Transform { // -//public: +// public: // PlaneMirror(TopoDS_Shape shape) : Transform(shape) {} // virtual ~PlaneMirror() {}; // @@ -132,9 +134,9 @@ // Handle parameters); //}; // -//class TranslateTransform : public Transform { +// class TranslateTransform : public Transform { // -//public: +// public: // TranslateTransform(TopoDS_Shape shape) : Transform(shape) {} // virtual ~TranslateTransform() {}; // diff --git a/src/Transformation.cc b/src/Transformation.cc index c993e35..991017d 100644 --- a/src/Transformation.cc +++ b/src/Transformation.cc @@ -1,154 +1,140 @@ #include "Transformation.h" #include "Util.h" -template -Transformation* prepare(T& info) { - Transformation* pThis = DynamicCast(info.This()); +// Methods exposed to JavaScripts +Nan::Persistent Transformation::_template; + +template Transformation *prepare(T &info) { + Nan::HandleScope scope; + + Transformation *pThis = DynamicCast(info.This()); if (pThis) { info.GetReturnValue().Set(info.This()); - } - else { - v8::Local instance = Nan::NewInstance(Constructor()).ToLocalChecked(); + } else { + v8::Local instance = makeInstance(Transformation::_template); pThis = Transformation::Unwrap(instance); info.GetReturnValue().Set(instance); } return pThis; } -NAN_METHOD(Transformation::makeTranslation) -{ - if( info.Length()!=1) { +NAN_METHOD(Transformation::makeTranslation) { + if (info.Length() != 1) { return Nan::ThrowError("Wrong arguments"); } - Transformation* pThis = prepare(info); + Transformation *pThis = prepare(info); - double x=0,y=0,z=0; - ReadPoint(info[0],&x,&y,&z); + double x = 0, y = 0, z = 0; + ReadPoint(info[0], &x, &y, &z); - pThis->m_trsf.SetTranslation(gp_Vec(x,y,z)); + pThis->m_trsf.SetTranslation(gp_Vec(x, y, z)); } #include "Base.h" - -NAN_METHOD(Transformation::makePlaneMirror) -{ +NAN_METHOD(Transformation::makePlaneMirror) { if (info.Length() != 2) { return Nan::ThrowError("Wrong arguments"); } - Transformation* pThis = prepare(info); + Transformation *pThis = prepare(info); - double x=0,y=0,z=0; - ReadPoint(info[0],&x,&y,&z); + double x = 0, y = 0, z = 0; + ReadPoint(info[0], &x, &y, &z); - double u=0,v=0,w=0; - ReadPoint(info[1],&u,&v,&w); + double u = 0, v = 0, w = 0; + ReadPoint(info[1], &u, &v, &w); -std::cout << " pThis->m_trsf ) "<< x << y << z << u << v << w << "\n"; - - Standard_Real D = sqrt (u * u + v * v + w * w); + Standard_Real D = sqrt(u * u + v * v + w * w); if (D <= gp::Resolution()) { return Nan::ThrowError("Plane Axis direction is null"); } pThis->m_trsf.SetMirror(gp_Ax2(gp_Pnt(x, y, z), gp_Dir(u, v, w))); - } - -NAN_METHOD(Transformation::makeAxisMirror) -{ +NAN_METHOD(Transformation::makeAxisMirror) { if (info.Length() != 2) { return Nan::ThrowError("Wrong arguments"); } - Transformation* pThis = prepare(info); + Transformation *pThis = prepare(info); - double x=0,y=0,z=0; - ReadPoint(info[0],&x,&y,&z); + double x = 0, y = 0, z = 0; + ReadPoint(info[0], &x, &y, &z); - double u=0,v=0,w=0; - ReadPoint(info[1],&u,&v,&w); + double u = 0, v = 0, w = 0; + ReadPoint(info[1], &u, &v, &w); - Standard_Real D = sqrt (u * u + v * v + w * w); + Standard_Real D = sqrt(u * u + v * v + w * w); if (D <= gp::Resolution()) { return Nan::ThrowError("Lirror Axis direction is null"); } pThis->m_trsf.SetMirror(gp_Ax1(gp_Pnt(x, y, z), gp_Dir(u, v, w))); - } -NAN_METHOD(Transformation::makeScale) -{ +NAN_METHOD(Transformation::makeScale) { if (info.Length() != 2) { return Nan::ThrowError("Wrong arguments"); } - Transformation* pThis = prepare(info); + Transformation *pThis = prepare(info); - double factor= Nan::To(info[0]).FromJust(); - double x=0,y=0,z=0; - ReadPoint(info[1],&x,&y,&z); + double factor = Nan::To(info[0]).FromJust(); + double x = 0, y = 0, z = 0; + ReadPoint(info[1], &x, &y, &z); pThis->m_trsf.SetScale(gp_Pnt(x, y, z), factor); - } - - -NAN_METHOD(Transformation::makeRotation) -{ - if(info.Length()!=3) { +NAN_METHOD(Transformation::makeRotation) { + if (info.Length() != 3) { return Nan::ThrowError("Wrong arguments in makeRotation"); } - Transformation* pThis = prepare(info); + Transformation *pThis = prepare(info); ReadRotationFromArgs(info, pThis->m_trsf); } -// Methods exposed to JavaScripts -Nan::Persistent Transformation::_template; +NAN_MODULE_INIT(Transformation::Init) { -void Transformation::Init(v8::Local target) -{ - v8::Local tpl = Nan::New(Transformation::New); + v8::Local tpl = + Nan::New(Transformation::New); // Prepare constructor template tpl->SetClassName(Nan::New("Transformation").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); - //xx NanAssignPersistent(_template,tpl); + // xx NanAssignPersistent(_template,tpl); _template.Reset(tpl); // Prototype v8::Local proto = tpl->PrototypeTemplate(); - EXPOSE_METHOD(Transformation,makeRotation); - EXPOSE_METHOD(Transformation,makeTranslation); - EXPOSE_METHOD(Transformation,makePlaneMirror); - EXPOSE_METHOD(Transformation,makeAxisMirror); - EXPOSE_METHOD(Transformation,makeScale); - EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Transformation,scaleFactor); + EXPOSE_METHOD(Transformation, makeRotation); + EXPOSE_METHOD(Transformation, makeTranslation); + EXPOSE_METHOD(Transformation, makePlaneMirror); + EXPOSE_METHOD(Transformation, makeAxisMirror); + EXPOSE_METHOD(Transformation, makeScale); + EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Transformation, scaleFactor); - Nan::Set(target,Nan::New("Transformation").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("Transformation").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } -NAN_METHOD(Transformation::New) -{ +NAN_METHOD(Transformation::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.Transformation() to construct a transformation"); + return Nan::ThrowError( + " use new occ.Transformation() to construct a transformation"); } - Transformation* pThis = new Transformation(); + Transformation *pThis = new Transformation(); pThis->Wrap(info.This()); info.GetReturnValue().Set(info.This()); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Transformation,scaleFactor); - + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Transformation, scaleFactor); } -NAN_METHOD(Transformation::NewInstance) -{ +NAN_METHOD(Transformation::NewInstance) { v8::Local instance = makeInstance(_template); info.GetReturnValue().Set(instance); } diff --git a/src/Transformation.h b/src/Transformation.h index 23c0900..c217967 100644 --- a/src/Transformation.h +++ b/src/Transformation.h @@ -5,42 +5,32 @@ #include "Point3Wrap.h" - - class Transformation : public Nan::ObjectWrap { public: - typedef class Transformation _ThisType ; - Transformation() - {} - static NAN_METHOD(makeTranslation); - static NAN_METHOD(makePlaneMirror); - static NAN_METHOD(makeAxisMirror); - static NAN_METHOD(makeScale); - static NAN_METHOD(makeRotation); - - double scaleFactor() { - return m_trsf.ScaleFactor(); - } - - const gp_XYZ translationPart() const { - return m_trsf.TranslationPart(); - } - - TEAROFF_POINT(Transformation,translationPart,Point3Wrap,gp_XYZ); + typedef class Transformation _ThisType; + Transformation() {} + static NAN_METHOD(makeTranslation); + static NAN_METHOD(makePlaneMirror); + static NAN_METHOD(makeAxisMirror); + static NAN_METHOD(makeScale); + static NAN_METHOD(makeRotation); - gp_Trsf m_trsf; + double scaleFactor() { return m_trsf.ScaleFactor(); } + const gp_XYZ translationPart() const { return m_trsf.TranslationPart(); } + TEAROFF_POINT(Transformation, translationPart, Point3Wrap, gp_XYZ); + gp_Trsf m_trsf; - // Methods exposed to JavaScripts - static void Init(v8::Local target); - static NAN_METHOD(NewInstance); - static NAN_METHOD(New); + // Methods exposed to JavaScripts + static NAN_MODULE_INIT(Init); + static NAN_METHOD(NewInstance); + static NAN_METHOD(New); - static Nan::Persistent _template; + static Nan::Persistent _template; private: - Transformation(const Transformation&); - void operator=(const Transformation&); + Transformation(const Transformation &); + void operator=(const Transformation &); }; \ No newline at end of file diff --git a/src/Util.cc b/src/Util.cc index 3af5044..89d6e61 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -4,30 +4,27 @@ using namespace std; +void ReadPropertyPointFromArray(v8::Local arr, double *x, double *y, + double *z) { -void ReadPropertyPointFromArray(v8::Local arr, double* x, double* y, double*z) -{ - Nan::HandleScope scope; - - double defaultValue =0.0; + double defaultValue = 0.0; int length = arr->Length(); if (length >= 1) { - auto element0 = Nan::Get(arr,0).ToLocalChecked(); + auto element0 = Nan::Get(arr, 0).ToLocalChecked(); *x = Nan::To(element0).FromMaybe(defaultValue); } if (length >= 2) { - auto element1 = Nan::Get(arr,1).ToLocalChecked(); + auto element1 = Nan::Get(arr, 1).ToLocalChecked(); *y = Nan::To(element1).FromMaybe(defaultValue); } if (length >= 3) { - auto element2 = Nan::Get(arr,2).ToLocalChecked(); + auto element2 = Nan::Get(arr, 2).ToLocalChecked(); *z = Nan::To(element2).FromMaybe(defaultValue); } - } - -//void ReadPropertyPoint(Handle obj,const char* name,double* x,double* y, double*z ) +// void ReadPropertyPoint(Handle obj,const char* name,double* x,double* +// y, double*z ) //{ // if (!obj.IsEmpty()) { // // for exemple a THREE.Vector3 @@ -40,42 +37,47 @@ void ReadPropertyPointFromArray(v8::Local arr, double* x, double* y, // //xx } //} -void ReadDouble(const v8::Local& _v, double& value) -{ +void ReadDouble(v8::Local _v, double &value, double defaultValue) { - value = 0.0; + value = defaultValue; if (_v->IsNumber()) { value = extract_double(_v); } } -void ReadDouble(v8::Local value, const char* name, double* retValue,double defaultValue) -{ - Nan::HandleScope scope; + +void ReadBoolean(v8::Local _v, bool &value, bool defaultValue) { + + value = defaultValue; + if (_v->IsBoolean()) { + value = extract_bool(_v); + } +} +void ReadDouble(v8::Local value, const char *name, double *retValue, + double defaultValue) { auto propertyName = Nan::New(name).ToLocalChecked(); v8::Local _v = Nan::Get(value, propertyName).ToLocalChecked(); - *retValue= Nan::To(_v).FromMaybe(defaultValue); + *retValue = Nan::To(_v).FromMaybe(defaultValue); } -void ReadInt(v8::Local value, const char* name,int* retValue, int defaultValue) -{ +void ReadInt(v8::Local value, const char *name, int *retValue, + int defaultValue) { Nan::HandleScope scope; - auto o =Nan::To(value).ToLocalChecked(); + auto o = Nan::To(value).ToLocalChecked(); - v8::Local _v = Nan::Get(o,Nan::New(name).ToLocalChecked()).ToLocalChecked(); + v8::Local _v = + Nan::Get(o, Nan::New(name).ToLocalChecked()).ToLocalChecked(); - *retValue = Nan::To(_v).FromMaybe(defaultValue); + *retValue = Nan::To(_v).FromMaybe(defaultValue); } -void ReadXYZ(v8::Local obj, double* x, double* y, double* z) -{ +void ReadXYZ(v8::Local obj, double *x, double *y, double *z) { ReadDouble(obj, "x", x, 0.0); ReadDouble(obj, "y", y, 0.0); ReadDouble(obj, "z", z, 0.0); } -void ReadPoint(v8::Local value, double* x, double* y, double*z) -{ +void ReadPoint(v8::Local value, double *x, double *y, double *z) { if (value->IsArray()) { v8::Local arr = v8::Local::Cast(value); @@ -85,41 +87,35 @@ void ReadPoint(v8::Local value, double* x, double* y, double*z) v8::Local obj = v8::Local::Cast(value); ReadXYZ(obj, x, y, z); } else { - Nan::ThrowError("Invalid Point or Vector ( must be a [] or a {x:..,y:.., z:...} )"); + Nan::ThrowError( + "Invalid Point or Vector ( must be a [] or a {x:..,y:.., z:...} )"); } } -void ReadUVW(v8::Local obj, double* x, double* y, double* z) -{ +void ReadUVW(v8::Local obj, double *x, double *y, double *z) { ReadDouble(obj, "u", x, 0.0); ReadDouble(obj, "v", y, 0.0); ReadDouble(obj, "w", z, 0.0); } - -void ReadPoint(v8::Local value, gp_Pnt* pt) -{ +void ReadPoint(v8::Local value, gp_Pnt *pt) { double x = 0, y = 0, z = 0; ReadPoint(value, &x, &y, &z); pt->SetCoord(x, y, z); } -void ReadDir(v8::Local value, gp_Dir* pt) -{ +void ReadDir(v8::Local value, gp_Dir *pt) { double x = 0, y = 0, z = 1.0; ReadPoint(value, &x, &y, &z); pt->SetCoord(x, y, z); } -void ReadVector(v8::Local value, gp_Vec* pt) -{ +void ReadVector(v8::Local value, gp_Vec *pt) { double x = 0, y = 0, z = 0; ReadPoint(value, &x, &y, &z); pt->SetCoord(x, y, z); } -void ReadRotationFromArgs(_NAN_METHOD_ARGS, gp_Trsf& trans) -{ - +void ReadRotationFromArgs(_NAN_METHOD_ARGS, gp_Trsf &trans) { double x = 0, y = 0, z = 0; ReadPoint(info[0], &x, &y, &z); @@ -128,5 +124,6 @@ void ReadRotationFromArgs(_NAN_METHOD_ARGS, gp_Trsf& trans) double angle = extract_double(info[2]); - trans.SetRotation(gp_Ax1(gp_Pnt(x, y, z), gp_Dir(u, v, w)), angle / 180.0*M_PI); + trans.SetRotation(gp_Ax1(gp_Pnt(x, y, z), gp_Dir(u, v, w)), + angle / 180.0 * M_PI); } diff --git a/src/Util.h b/src/Util.h index 1c91465..b08ffc5 100644 --- a/src/Util.h +++ b/src/Util.h @@ -1,50 +1,86 @@ #pragma once -#include "OCC.h" #include "NodeV8.h" +#include "OCC.h" +inline v8::Local +makeInstance(Nan::Persistent &_template) { -inline v8::Local makeInstance(Nan::Persistent& _template) { - return Nan::NewInstance(Nan::GetFunction(Nan::New(_template)).ToLocalChecked()).ToLocalChecked(); + v8::Local o = + Nan::NewInstance(Nan::GetFunction(Nan::New(_template)).ToLocalChecked()) + .ToLocalChecked(); + return o; } -template inline double extract_double(const v8::Local& a) { +template inline double extract_double(v8::Local a) { return Nan::To(a).FromJust(); } +template inline bool extract_bool(v8::Local a) { + return Nan::To(a).FromJust(); +} -void ReadDouble(const v8::Local& _v,double& value); - -void ReadInt(v8::Local obj,const char* name,int* retValue,int defaultValue); -void ReadDouble(v8::Local obj,const char* name,double* retValue,double defaultValue=0.0); +void ReadDouble(v8::Local _v, double &value, + double defaultValue = 0.0); +void ReadBoolean(v8::Local _v, bool &value, + bool defaultValue = false); -void ReadPropertyPointFromArray(v8::Local value,double* x,double* y, double*z ); -// void ReadPropertyPoint( Handle value,const char* name,double* x,double* y, double*z ); +void ReadInt(v8::Local obj, const char *name, int *retValue, + int defaultValue); +void ReadDouble(v8::Local obj, const char *name, double *retValue, + double defaultValue = 0.0); -void ReadXYZ(v8::Local value,double* x,double* y,double* z); -void ReadUVW(v8::Local value,double* x,double* y,double* z); +void ReadPropertyPointFromArray(v8::Local value, double *x, + double *y, double *z); +// void ReadPropertyPoint( Handle value,const char* name,double* +// x,double* y, double*z ); -void ReadPoint(v8::Local value,double* x,double* y, double*z); -void ReadPoint(v8::Local value,gp_Pnt* pt); -void ReadDir(v8::Local value,gp_Dir* pt); -void ReadVector(v8::Local value,gp_Vec* pt); +void ReadXYZ(v8::Local value, double *x, double *y, double *z); +void ReadUVW(v8::Local value, double *x, double *y, double *z); -void ReadRotationFromArgs(_NAN_METHOD_ARGS,gp_Trsf& trans); +void ReadPoint(v8::Local value, double *x, double *y, double *z); +void ReadPoint(v8::Local value, gp_Pnt *pt); +void ReadDir(v8::Local value, gp_Dir *pt); +void ReadVector(v8::Local value, gp_Vec *pt); +void ReadRotationFromArgs(_NAN_METHOD_ARGS, gp_Trsf &trans); enum ArrayType { - A_SByte, A_UInt8, A_Int16, A_UInt16, A_Int32, A_UInt32, A_Float32, A_Float64 + A_SByte, + A_UInt8, + A_Int16, + A_UInt16, + A_Int32, + A_UInt32, + A_Float32, + A_Float64 }; -inline const char* ArrayTypeToString(ArrayType type) { - const char* name = 0; +inline const char *ArrayTypeToString(ArrayType type) { + const char *name = 0; switch (type) { - case A_SByte: name = "Uint8Array"; break; - case A_UInt8: name = "Uint8Array"; break; - case A_Int16: name = "Int16Array"; break; - case A_UInt16: name = "Uint16Array"; break; - case A_Int32: name = "Int32Array"; break; - case A_UInt32: name = "Uint32Array"; break; - case A_Float32: name = "Float32Array"; break; - case A_Float64: name = "Float64Array"; break; + case A_SByte: + name = "Uint8Array"; + break; + case A_UInt8: + name = "Uint8Array"; + break; + case A_Int16: + name = "Int16Array"; + break; + case A_UInt16: + name = "Uint16Array"; + break; + case A_Int32: + name = "Int32Array"; + break; + case A_UInt32: + name = "Uint32Array"; + break; + case A_Float32: + name = "Float32Array"; + break; + case A_Float64: + name = "Float64Array"; + break; default: name = 0; } @@ -53,155 +89,206 @@ inline const char* ArrayTypeToString(ArrayType type) { inline int ArrayTypeSize(ArrayType type) { switch (type) { - case A_SByte: return 1; break; - case A_UInt8: return 1; break; - case A_Int16: return 2; break; - case A_UInt16: return 2; break; - case A_Int32: return 4; break; - case A_UInt32: return 4; break; - case A_Float32: return 4; break; - case A_Float64: return 8; break; + case A_SByte: + return 1; + break; + case A_UInt8: + return 1; + break; + case A_Int16: + return 2; + break; + case A_UInt16: + return 2; + break; + case A_Int32: + return 4; + break; + case A_UInt32: + return 4; + break; + case A_Float32: + return 4; + break; + case A_Float64: + return 8; + break; default: return 0; } } inline v8::Local makeArrayBuffer(int length) { + Nan::EscapableHandleScope scope; v8::Local val = Nan::New("ArrayBuffer").ToLocalChecked(); if (val.IsEmpty() || !val->IsFunction()) { Nan::ThrowError("Error getting ArrayBuffer constructor"); - return val; + return scope.Escape(val); } v8::Local constructor = val.As(); v8::Local size = Nan::New(length); - Nan::MaybeLocal array_buffer = Nan::CallAsConstructor(constructor, 1, &size); - return array_buffer.ToLocalChecked(); + Nan::MaybeLocal array_buffer = + Nan::CallAsConstructor(constructor, 1, &size); + return scope.Escape(array_buffer.ToLocalChecked()); } -template T* getArrayData(V&& value) { - #if (V8_MAJOR_VERSION >= 8) - return (T*)(static_cast(value->Buffer()->GetBackingStore()->Data()) + value->ByteOffset()); - #else - return (T*)(static_cast(value->Buffer()->GetContents().Data()) + value->ByteOffset()); - #endif +template T *getArrayData(V &&value) { +#if (V8_MAJOR_VERSION >= 8) + return (T *)(static_cast(value->Buffer()->GetBackingStore()->Data()) + + value->ByteOffset()); +#else + return (T *)(static_cast(value->Buffer()->GetContents().Data()) + + value->ByteOffset()); +#endif } -#define IS_FLOAT32ARRAY(value) (value->IsFloat32Array() && (value.As()->Length() == 2)) -#define GET_FLOAT32ARRAY_DATA(value) getArrayData(value.As()) -#define IS_FLOAT32ARRAY_ARRAY(value) (value->IsFloat32Array() && ((value.As()->Length() % 2) == 0)) -#define GET_FLOAT32ARRAY_ARRAY_DATA(value) GET_FLOAT32ARRAY_DATA(value) -#define GET_FLOAT32ARRAY_ARRAY_LENGTH(value) (value.As()->Length()) - - -#define IS_INT32ARRAY(value) (value->IsInt32Array() && (value.As()->Length() == 2)) -#define GET_INT32ARRAY_DATA(value) getArrayData(value.As()) -#define IS_INT32ARRAY_ARRAY(value) (value->IsInt32Array() && ((value.As()->Length() % 2) == 0)) -#define GET_INT32ARRAY_ARRAY_DATA(value) GET_INT32ARRAY_DATA(value) -#define GET_INT32ARRAY_ARRAY_LENGTH(value) (value.As()->Length()) - -#define IS_UINT32ARRAY(value) (value->IsUint32Array() && (value.As()->Length() == 2)) -#define GET_UINT32ARRAY_DATA(value) getArrayData(value.As()) -#define IS_UINT32ARRAY_ARRAY(value) (value->IsUint32Array() && ((value.As()->Length() % 2) == 0)) -#define GET_UINT32ARRAY_ARRAY_DATA(value) GET_UINT32ARRAY_DATA(value) -#define GET_UINT32ARRAY_ARRAY_LENGTH(value) (value.As()->Length()) - - -#define IS_UINT16ARRAY(value) (value->IsUint16Array() && (value.As()->Length() == 2)) -#define GET_UINT16ARRAY_DATA(value) getArrayData(value.As()) -#define IS_UINT16ARRAY_ARRAY(value) (value->IsUint32Array() && ((value.As()->Length() % 2) == 0)) -#define GET_UINT16ARRAY_ARRAY_DATA(value) GET_UINT16ARRAY_DATA(value) -#define GET_UINT16ARRAY_ARRAY_LENGTH(value) (value.As()->Length()) - -#define IS_UINT8ARRAY(value) (value->IsUint8Array() && (value.As()->Length() == 2)) -#define GET_UINT8ARRAY_DATA(value) getArrayData(value.As()) -#define IS_UINT8ARRAY_ARRAY(value) (value->IsUint8Array() && ((value.As()->Length() % 2) == 0)) -#define GET_UINT8ARRAY_ARRAY_DATA(value) GET_UINT8ARRAY_DATA(value) -#define GET_UINT8ARRAY_ARRAY_LENGTH(value) (value.As()->Length()) - +#define IS_FLOAT32ARRAY(value) \ + (value->IsFloat32Array() && (value.As()->Length() == 2)) +#define GET_FLOAT32ARRAY_DATA(value) \ + getArrayData(value.As()) +#define IS_FLOAT32ARRAY_ARRAY(value) \ + (value->IsFloat32Array() && \ + ((value.As()->Length() % 2) == 0)) +#define GET_FLOAT32ARRAY_ARRAY_DATA(value) GET_FLOAT32ARRAY_DATA(value) +#define GET_FLOAT32ARRAY_ARRAY_LENGTH(value) \ + (value.As()->Length()) + +#define IS_INT32ARRAY(value) \ + (value->IsInt32Array() && (value.As()->Length() == 2)) +#define GET_INT32ARRAY_DATA(value) \ + getArrayData(value.As()) +#define IS_INT32ARRAY_ARRAY(value) \ + (value->IsInt32Array() && ((value.As()->Length() % 2) == 0)) +#define GET_INT32ARRAY_ARRAY_DATA(value) GET_INT32ARRAY_DATA(value) +#define GET_INT32ARRAY_ARRAY_LENGTH(value) \ + (value.As()->Length()) + +#define IS_UINT32ARRAY(value) \ + (value->IsUint32Array() && (value.As()->Length() == 2)) +#define GET_UINT32ARRAY_DATA(value) \ + getArrayData(value.As()) +#define IS_UINT32ARRAY_ARRAY(value) \ + (value->IsUint32Array() && ((value.As()->Length() % 2) == 0)) +#define GET_UINT32ARRAY_ARRAY_DATA(value) GET_UINT32ARRAY_DATA(value) +#define GET_UINT32ARRAY_ARRAY_LENGTH(value) \ + (value.As()->Length()) + +#define IS_UINT16ARRAY(value) \ + (value->IsUint16Array() && (value.As()->Length() == 2)) +#define GET_UINT16ARRAY_DATA(value) \ + getArrayData(value.As()) +#define IS_UINT16ARRAY_ARRAY(value) \ + (value->IsUint32Array() && ((value.As()->Length() % 2) == 0)) +#define GET_UINT16ARRAY_ARRAY_DATA(value) GET_UINT16ARRAY_DATA(value) +#define GET_UINT16ARRAY_ARRAY_LENGTH(value) \ + (value.As()->Length()) + +#define IS_UINT8ARRAY(value) \ + (value->IsUint8Array() && (value.As()->Length() == 2)) +#define GET_UINT8ARRAY_DATA(value) \ + getArrayData(value.As()) +#define IS_UINT8ARRAY_ARRAY(value) \ + (value->IsUint8Array() && ((value.As()->Length() % 2) == 0)) +#define GET_UINT8ARRAY_ARRAY_DATA(value) GET_UINT8ARRAY_DATA(value) +#define GET_UINT8ARRAY_ARRAY_LENGTH(value) \ + (value.As()->Length()) inline v8::Local makeTypedArray(ArrayType type, uint32_t length) { + Nan::EscapableHandleScope scope; + const char *name = ArrayTypeToString(type); if (!name) { Nan::ThrowError("Unsupported array type"); - return Nan::New(); + return scope.Escape(Nan::New()); } - auto typedArrayConstructor = Nan::Get(Nan::GetCurrentContext()->Global(),Nan::New(name).ToLocalChecked()).ToLocalChecked(); - + auto typedArrayConstructor = Nan::Get(Nan::GetCurrentContext()->Global(), + Nan::New(name).ToLocalChecked()) + .ToLocalChecked(); + if (typedArrayConstructor.IsEmpty() || !typedArrayConstructor->IsFunction()) { Nan::ThrowError("Error getting typed array constructor"); - return Nan::New(); + return scope.Escape(Nan::New()); } - v8::Local constructor = Nan::To(typedArrayConstructor).ToLocalChecked(); - + v8::Local constructor = + Nan::To(typedArrayConstructor).ToLocalChecked(); + const int argc = 1; - v8::Local argv[1] = { Nan::New(length) }; - v8::Local array = constructor->NewInstance(Nan::GetCurrentContext(),argc, argv).ToLocalChecked(); + v8::Local argv[1] = {Nan::New(length)}; + v8::Local array = + constructor->NewInstance(Nan::GetCurrentContext(), argc, argv) + .ToLocalChecked(); if (array.IsEmpty() || !array->IsObject()) { Nan::ThrowError("Error creating TypedArray"); - return v8::Local(); + return scope.Escape(v8::Local()); } - return array; + return scope.Escape(array); } - -inline v8::Local makeFloat32Array(const float* data, uint32_t length) { +inline v8::Local makeFloat32Array(const float *data, + uint32_t length) { + Nan::EscapableHandleScope scope; v8::Local array = makeTypedArray(A_Float32, length); - float* dest = GET_FLOAT32ARRAY_ARRAY_DATA(array); + float *dest = GET_FLOAT32ARRAY_ARRAY_DATA(array); memcpy(dest, data, length * sizeof(data[0])); - return array; + return scope.Escape(array); } -inline v8::Local makeInt32Array(const int* data, uint32_t length) { +inline v8::Local makeInt32Array(const int *data, uint32_t length) { + Nan::EscapableHandleScope scope; v8::Local array = makeTypedArray(A_Int32, length); - int* dest = GET_INT32ARRAY_ARRAY_DATA(array); + int *dest = GET_INT32ARRAY_ARRAY_DATA(array); memcpy(dest, data, length * sizeof(data[0])); - return array; + return scope.Escape(array); } -inline v8::Local makeUint32Array(const unsigned int* data, uint32_t length) { +inline v8::Local makeUint32Array(const unsigned int *data, + uint32_t length) { + Nan::EscapableHandleScope scope; v8::Local array = makeTypedArray(A_UInt32, length); - unsigned int* dest = GET_UINT32ARRAY_ARRAY_DATA(array); + unsigned int *dest = GET_UINT32ARRAY_ARRAY_DATA(array); memcpy(dest, data, length * sizeof(data[0])); - return array; + return scope.Escape(array); } -inline v8::Local makeUint16Array(const unsigned short* data, uint32_t length) { +inline v8::Local makeUint16Array(const unsigned short *data, + uint32_t length) { + Nan::EscapableHandleScope scope; v8::Local array = makeTypedArray(A_UInt16, length); - unsigned short* dest = GET_UINT16ARRAY_ARRAY_DATA(array); + unsigned short *dest = GET_UINT16ARRAY_ARRAY_DATA(array); memcpy(dest, data, length * sizeof(data[0])); - return array; + return scope.Escape(array); } -inline v8::Local makeUint8Array(const unsigned char* data, uint32_t length) { +inline v8::Local makeUint8Array(const unsigned char *data, + uint32_t length) { + Nan::EscapableHandleScope scope; v8::Local array = makeTypedArray(A_UInt8, length); - unsigned char* dest = GET_UINT8ARRAY_ARRAY_DATA(array); + unsigned char *dest = GET_UINT8ARRAY_ARRAY_DATA(array); memcpy(dest, data, length * sizeof(data[0])); - return array; + return scope.Escape(array); } - - -inline v8::Local _makeTypedArray(const float* data, int length) { +inline v8::Local _makeTypedArray(const float *data, int length) { return makeFloat32Array(data, length); } -inline v8::Local _makeTypedArray(const int* data, int length) { +inline v8::Local _makeTypedArray(const int *data, int length) { return makeInt32Array(data, length); } -inline v8::Local _makeTypedArray(const unsigned int* data, int length) { +inline v8::Local _makeTypedArray(const unsigned int *data, + int length) { return makeUint32Array(data, length); } - -template -OBJECT* DynamicCast(const v8::Local& value) -{ - if (value.IsEmpty()) return 0; - if (!value->IsObject()) return 0; +template OBJECT *DynamicCast(v8::Local value) { + if (value.IsEmpty()) + return 0; + if (!value->IsObject()) + return 0; auto o = Nan::To(value).ToLocalChecked(); if (IsInstanceOf(o)) { @@ -210,26 +297,26 @@ OBJECT* DynamicCast(const v8::Local& value) return 0; } template -ObjType2* DynamicCast(const v8::Local& value) -{ - ObjType1* obj = DynamicCast(value); - if (obj) return obj; +ObjType2 *DynamicCast(v8::Local value) { + ObjType1 *obj = DynamicCast(value); + if (obj) + return obj; return DynamicCast(value); } -template v8::Local Constructor() { - +template v8::Local Constructor() { auto f = Nan::GetFunction(Nan::New(T::_template)).ToLocalChecked(); return f; } -template NAN_METHOD(_NewInstance) { - int argc =info.Length(); - auto argv = new v8::Local[argc];// = new v8::Local[argc]; - for (int i=0;i(),argc,argv); - delete [] argv; - info.GetReturnValue().Set(instance.ToLocalChecked()); +template NAN_METHOD(_NewInstance) { + int argc = info.Length(); + auto argv = + new v8::Local[argc]; // = new v8::Local[argc]; + for (int i = 0; i < argc; i++) { + argv[i] = info[i]; + } + auto instance = Nan::NewInstance(Constructor(), argc, argv); + delete[] argv; + info.GetReturnValue().Set(instance.ToLocalChecked()); } diff --git a/src/V8Wrapper.cc b/src/V8Wrapper.cc index 5232cf7..4c41364 100644 --- a/src/V8Wrapper.cc +++ b/src/V8Wrapper.cc @@ -1,88 +1,87 @@ -#include "NodeV8.h" -#include "Util.h" -#include "GeometryBuilder.h" +#include "BooleanOperation.h" #include "BoundingBox.h" -#include "Solid.h" -#include "Mesh.h" #include "Edge.h" -#include "Vertex.h" -#include "Wire.h" #include "Face.h" -#include "Transformation.h" -#include "ShapeIterator.h" -#include "Tools.h" +#include "GeometryBuilder.h" +#include "Mesh.h" +#include "NodeV8.h" #include "ShapeFactory.h" +#include "ShapeIterator.h" #include "Shell.h" -#include "BooleanOperation.h" - - - -NAN_METHOD(ForceGC) -{ - Nan::IdleNotification(100); -} - -void Initialize(v8::Local target) -{ - - BoundingBox::Init(target); - Edge::Init(target); - Face::Init(target); - Mesh::Init(target); - Point3Wrap::Init(target); - ShapeIterator::Init(target); - Shell::Init(target); - Solid::Init(target); - Transformation::Init(target); - Vertex::Init(target); - Wire::Init(target); - BooleanOperation::Init(target); - - - Nan::SetMethod(target,"makePlaneMirror", Transformation::makePlaneMirror); - - // Vertex - Nan::SetMethod(target,"makeVertex", ShapeFactory::makeVertex); - - - // edges - Nan::SetMethod(target,"makeLine", Edge::static_createLine); - Nan::SetMethod(target,"makeCircle", Edge::static_createCircle); - Nan::SetMethod(target,"makeArc3P", Edge::static_createArc3P); - - //xx Nan::SetMethod(target,"makeEdge", ShapeFactory::makeEdge); - - Nan::SetMethod(target,"makeWire", ShapeFactory::makeWire); - Nan::SetMethod(target,"makeFace", ShapeFactory::makeFace); - - //---------------------------------------------------------- - Nan::SetMethod(target,"makeBox", ShapeFactory::makeBox); - Nan::SetMethod(target,"makeCylinder", ShapeFactory::makeCylinder); - Nan::SetMethod(target,"makeCone", ShapeFactory::makeCone); - Nan::SetMethod(target,"makeSphere", ShapeFactory::makeSphere); - Nan::SetMethod(target,"makeTorus", ShapeFactory::makeTorus); - Nan::SetMethod(target,"makePrism", ShapeFactory::makePrism); - Nan::SetMethod(target,"makeThickSolid",ShapeFactory::makeThickSolid); - Nan::SetMethod(target,"makeDraftAngle",ShapeFactory::makeDraftAngle); - Nan::SetMethod(target,"makeFillet", ShapeFactory::makeFillet); - // target->Set(NanSymbol("makeChamfer")NanNew(ShapeFactory::makeDraftAngle); - - Nan::SetMethod(target,"fuse", ShapeFactory::fuse); - Nan::SetMethod(target,"cut", ShapeFactory::cut); - Nan::SetMethod(target,"common", ShapeFactory::common); - Nan::SetMethod(target,"compound", ShapeFactory::compound); - - Nan::SetMethod(target,"writeSTL", writeSTL); - Nan::SetMethod(target,"writeSTEP", writeSTEP); - Nan::SetMethod(target,"writeBREP", writeBREP); - Nan::SetMethod(target,"readSTEP", readSTEP); - Nan::SetMethod(target,"readBREP", readBREP); - - //xx Nan::SetMethod(target,"oceVersion",NanNew("0.13")); - Nan::Set(target,Nan::New("oceVersion").ToLocalChecked(), Nan::New("0.13").ToLocalChecked()); - - Nan::SetMethod(target,"gc",ForceGC); - +#include "Solid.h" +#include "Tools.h" +#include "Transformation.h" +#include "Util.h" +#include "Vertex.h" +#include "Wire.h" +NAN_METHOD(ForceGC) { Nan::IdleNotification(100); } + +NAN_MODULE_INIT(Init) { + BoundingBox::Init(target); + Edge::Init(target); + Face::Init(target); + Mesh::Init(target); + Point3Wrap::Init(target); + ShapeIterator::Init(target); + Shell::Init(target); + Solid::Init(target); + Transformation::Init(target); + Vertex::Init(target); + Wire::Init(target); + BooleanOperation::Init(target); + + Nan::SetMethod(target, "makePlaneMirror", Transformation::makePlaneMirror); + + // Vertex + Nan::SetMethod(target, "makeVertex", ShapeFactory::makeVertex); + + // edges + Nan::SetMethod(target, "makeLine", Edge::static_makeLine); + Nan::SetMethod(target, "makeCircle", Edge::static_makeCircle); + Nan::SetMethod(target, "makeArc3P", Edge::static_makeArc3P); + + // xx Nan::SetMethod(target,"makeEdge", ShapeFactory::makeEdge); + + Nan::SetMethod(target, "makeWire", ShapeFactory::makeWire); + Nan::SetMethod(target, "makeFace", ShapeFactory::makeFace); + + //---------------------------------------------------------- + Nan::SetMethod(target, "makeBox", ShapeFactory::makeBox); + Nan::SetMethod(target, "makeCylinder", ShapeFactory::makeCylinder); + Nan::SetMethod(target, "makeCone", ShapeFactory::makeCone); + Nan::SetMethod(target, "makeSphere", ShapeFactory::makeSphere); + Nan::SetMethod(target, "makeTorus", ShapeFactory::makeTorus); + Nan::SetMethod(target, "makePrism", ShapeFactory::makePrism); + Nan::SetMethod(target, "makeThickSolid", ShapeFactory::makeThickSolid); + Nan::SetMethod(target, "makeDraftAngle", ShapeFactory::makeDraftAngle); + Nan::SetMethod(target, "makeFillet", ShapeFactory::makeFillet); + Nan::SetMethod(target, "makeRevol", ShapeFactory::makeRevol); + Nan::SetMethod(target, "makePipe", ShapeFactory::makePipe); + Nan::SetMethod(target, "makePipeShell", ShapeFactory::makePipeShell); + // Nan::SetMethod(target, "makePipeSolid", ShapeFactory::makePipeSolid); + Nan::SetMethod(target, "makeSolidThruSections", + ShapeFactory::makeSolidThruSections); + + // target->Set(NanSymbol("makeChamfer")NanNew(ShapeFactory::makeDraftAngle); + + Nan::SetMethod(target, "fuse", ShapeFactory::fuse); + Nan::SetMethod(target, "cut", ShapeFactory::cut); + Nan::SetMethod(target, "common", ShapeFactory::common); + Nan::SetMethod(target, "compound", ShapeFactory::compound); + + Nan::SetMethod(target, "writeSTL", writeSTL); + Nan::SetMethod(target, "writeSTEP", writeSTEP); + Nan::SetMethod(target, "writeBREP", writeBREP); + Nan::SetMethod(target, "writeGLTF", writeGLTF); + + Nan::SetMethod(target, "readSTEP", readSTEP); + Nan::SetMethod(target, "readBREP", readBREP); + + // xx Nan::SetMethod(target,"oceVersion",NanNew("0.13")); + Nan::Set(target, Nan::New("oceVersion").ToLocalChecked(), + Nan::New("0.13").ToLocalChecked()); + + Nan::SetMethod(target, "gc", ForceGC); } -NODE_MODULE(occ, Initialize) +NODE_MODULE(occ, Init) diff --git a/src/Vertex.cc b/src/Vertex.cc index fe26745..f650f14 100644 --- a/src/Vertex.cc +++ b/src/Vertex.cc @@ -2,46 +2,30 @@ #include "Util.h" -const TopoDS_Shape& Vertex::shape() const -{ - return vertex(); -} +const TopoDS_Shape &Vertex::shape() const { return vertex(); } -void Vertex::setShape(const TopoDS_Shape& shape) -{ +void Vertex::setShape(const TopoDS_Shape &shape) { m_vertex = TopoDS::Vertex(shape); } -gp_Pnt Vertex::point() const -{ +gp_Pnt Vertex::point() const { gp_Pnt pnt = BRep_Tool::Pnt(vertex()); return pnt; } -double Vertex::x() -{ - return point().X(); -} -double Vertex::y() -{ - return point().Y(); -} -double Vertex::z() -{ - return point().Z(); -} +double Vertex::x() { return point().X(); } +double Vertex::y() { return point().Y(); } +double Vertex::z() { return point().Z(); } Nan::Persistent Vertex::_template; - NAN_METHOD(Vertex::NewInstance) { _NewInstance(info); } -NAN_METHOD(Vertex::New) -{ +NAN_METHOD(Vertex::New) { if (!info.IsConstructCall()) { - return Nan::ThrowError(" use new occ.Vertex() to construct a Vertex"); + return Nan::ThrowError(" use occ.makeVertex() to construct a Vertex"); } - Vertex* pThis = new Vertex(); + Vertex *pThis = new Vertex(); pThis->Wrap(info.This()); pThis->InitNew(info); @@ -51,48 +35,43 @@ NAN_METHOD(Vertex::New) ReadDouble(info[0], x); ReadDouble(info[1], y); ReadDouble(info[2], z); - } - else if (info.Length() == 1) { + } else if (info.Length() == 1) { ReadPoint(info[0], &x, &y, &z); - } - else if (info.Length() == 0) { - } - else { + } else if (info.Length() == 0) { + } else { return Nan::ThrowError("Wrong Arguments"); } - gp_Pnt aPnt; - aPnt = gp_Pnt(x, y, z); + gp_Pnt aPnt(x, y, z); BRepBuilderAPI_MakeVertex mkVertex(aPnt); pThis->setShape(mkVertex.Vertex()); info.GetReturnValue().Set(info.This()); } - -v8::Local Vertex::Clone() const -{ - Vertex* obj = new Vertex(); +v8::Local Vertex::Clone() const { + Nan::EscapableHandleScope scope; + Vertex *obj = new Vertex(); v8::Local instance = makeInstance(_template); obj->Wrap(instance); obj->setShape(this->shape()); - return instance; + return scope.Escape(instance); } -void Vertex::InitNew(_NAN_METHOD_ARGS) -{ +void Vertex::InitNew(_NAN_METHOD_ARGS) { Base::InitNew(info); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex,x); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex,y); - REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex,z); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex, x); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex, y); + REXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex, z); } -void Vertex::Init(v8::Local target) -{ +NAN_MODULE_INIT(Vertex::Init) { + // Prepare constructor template - v8::Local tpl = Nan::New(Vertex::New); + v8::Local tpl = + Nan::New(Vertex::New); tpl->SetClassName(Nan::New("Vertex").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -106,6 +85,6 @@ void Vertex::Init(v8::Local target) EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex, y); EXPOSE_READ_ONLY_PROPERTY_DOUBLE(Vertex, z); - Nan::Set(target,Nan::New("Vertex").ToLocalChecked(),Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("Vertex").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } - diff --git a/src/Vertex.h b/src/Vertex.h index e516261..b8b3232 100644 --- a/src/Vertex.h +++ b/src/Vertex.h @@ -3,31 +3,27 @@ class Vertex : public Shape { private: - TopoDS_Vertex m_vertex; -public: - - double x() ; - double y() ; - double z() ; - - gp_Pnt point() const; - - virtual const TopoDS_Shape& shape() const; - const TopoDS_Vertex& vertex() const { - return m_vertex; - } - virtual void setShape( const TopoDS_Shape&); - virtual v8::Local Clone() const ; - virtual Base* Unwrap(v8::Local obj) const { - return Nan::ObjectWrap::Unwrap(obj); - } + TopoDS_Vertex m_vertex; - - virtual void InitNew(_NAN_METHOD_ARGS); - - - static void Init(v8::Local target); - static NAN_METHOD(NewInstance); - static NAN_METHOD(New); - static Nan::Persistent _template; +public: + double x(); + double y(); + double z(); + + gp_Pnt point() const; + + virtual const TopoDS_Shape &shape() const; + const TopoDS_Vertex &vertex() const { return m_vertex; } + virtual void setShape(const TopoDS_Shape &); + virtual v8::Local Clone() const; + virtual Base *Unwrap(v8::Local obj) const { + return Nan::ObjectWrap::Unwrap(obj); + } + + virtual void InitNew(_NAN_METHOD_ARGS); + + static NAN_MODULE_INIT(Init); + static NAN_METHOD(NewInstance); + static NAN_METHOD(New); + static Nan::Persistent _template; }; diff --git a/src/Wire.cc b/src/Wire.cc index 4d7c469..6a2f190 100644 --- a/src/Wire.cc +++ b/src/Wire.cc @@ -1,25 +1,25 @@ #include "Wire.h" - -int Wire::numVertices() -{ - if (this->wire().IsNull()) return 0; +int Wire::numVertices() { + if (this->wire().IsNull()) + return 0; TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(this->wire(), TopAbs_VERTEX, anIndices); return anIndices.Extent(); } -int Wire::numEdges() -{ - if (this->wire().IsNull()) return 0; +int Wire::numEdges() { + if (this->wire().IsNull()) + return 0; TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(this->wire(), TopAbs_EDGE, anIndices); return anIndices.Extent(); } -bool Wire::isClosed() -{ - if (this->wire().IsNull()) return false; +bool Wire::isClosed() { + if (this->wire().IsNull()) + return false; + TopoDS_Vertex aV1, aV2; TopExp::Vertices(this->wire(), aV1, aV2); if (!aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2)) @@ -27,22 +27,12 @@ bool Wire::isClosed() return false; } - -const TopoDS_Shape& Wire::shape() const -{ - return m_wire; -} -void Wire::setShape(const TopoDS_Shape& shape) -{ - - m_wire = TopoDS::Wire(shape); -} +const TopoDS_Shape &Wire::shape() const { return m_wire; } +void Wire::setShape(const TopoDS_Shape &shape) { m_wire = TopoDS::Wire(shape); } Nan::Persistent Wire::_template; - -const char* toString(BRepBuilderAPI_WireError err) -{ +const char *toString(BRepBuilderAPI_WireError err) { switch (err) { case BRepBuilderAPI_WireDone: return "the wire is done"; @@ -57,21 +47,61 @@ const char* toString(BRepBuilderAPI_WireError err) return "the wire is non-manifold"; break; } - return ""; + return ""; } - NAN_METHOD(Wire::NewInstance) { _NewInstance(info); } +template void addElement(T info, BRepBuilderAPI_MakeWire &mkWire) { + + Edge *edge = DynamicCast(info); + Wire *wire = DynamicCast(info); + + if (edge) { + // IsInstanceOf(info[i]->ToObject())) { + // xx Edge* edge = Nan::ObjectWrap::Unwrap(info[i]->ToObject()); + mkWire.Add(edge->edge()); + // Xx statusIsDone = mkWire.IsDone(); + // err = mkWire.Error(); + } else if (wire) { + mkWire.Add(wire->wire()); + // Xx statusIsDone = mkWire.IsDone(); + // err = mkWire.Error(); + } else { + auto mesg = std::string("invalid arguement: expecting a Wire or an Edge"); + Nan::ThrowError(mesg.c_str()); + } +} +bool extractListOfEdge(v8::Local value, + TopTools_ListOfShape &edges) { + if (value->IsArray()) { + v8::Local arr = v8::Local::Cast(value); + int length = arr->Length(); + for (int i = 0; i < length; i++) { + auto elementI = Nan::Get(arr, i).ToLocalChecked(); + Edge *pEdge = 0; + if (extractArg(elementI, pEdge)) { + edges.Append(pEdge->edge()); + } + } + } else { + // could be a single face + Edge *pEdge = 0; + if (!extractArg(value, pEdge)) { + return false; + } + edges.Append(pEdge->edge()); + } -NAN_METHOD(Wire::New) -{ + return edges.Extent() > 0; +} + +NAN_METHOD(Wire::New) { if (!info.IsConstructCall()) { return Nan::ThrowError(" use new occ.Wire() to construct a Wire"); } - - Wire* pThis = new Wire(); + Wire *pThis = new Wire(); pThis->Wrap(info.This()); pThis->InitNew(info); @@ -81,65 +111,63 @@ NAN_METHOD(Wire::New) return; } - BRepBuilderAPI_MakeWire mkWire; - - //Xx Standard_Boolean statusIsDone = false; - - BRepBuilderAPI_WireError err = BRepBuilderAPI_WireDone; - - for (int i = 0; i < info.Length(); i++) { - - Edge* edge = DynamicCast(info[i]); - Wire* wire = DynamicCast(info[i]); - - if (edge) { - // IsInstanceOf(info[i]->ToObject())) { - //xx Edge* edge = Nan::ObjectWrap::Unwrap(info[i]->ToObject()); - mkWire.Add(edge->edge()); - - //Xx statusIsDone = mkWire.IsDone(); - err = mkWire.Error(); - } else if (wire) { - mkWire.Add(wire->wire()); - //Xx statusIsDone = mkWire.IsDone(); - err = mkWire.Error(); + try { + + BRepBuilderAPI_MakeWire mkWire; + if (info.Length() == 1 && info[0]->IsArray()) { + // we expect an array of Wire or Edge + v8::Local arr = v8::Local::Cast(info[0]); + TopTools_ListOfShape elements; + extractListOfEdge(arr, elements); + mkWire.Add(elements); + BRepBuilderAPI_WireError err = mkWire.Error(); + } else { + for (int i = 0; i < info.Length(); i++) { + addElement(info[i], mkWire); + BRepBuilderAPI_WireError err = mkWire.Error(); + } } - } - err = mkWire.Error(); - if (BRepBuilderAPI_WireDone == err) { - pThis->setShape(mkWire.Wire()); - } else { - std::string mesg = std::string("Invalid Wire err:=") + toString(mkWire.Error()); - return Nan::ThrowError(mesg.c_str()); + // Xx Standard_Boolean statusIsDone = false; + BRepBuilderAPI_WireError err = BRepBuilderAPI_WireDone; + err = mkWire.Error(); + if (BRepBuilderAPI_WireDone == err || mkWire.IsDone()) { + pThis->setShape(mkWire.Wire()); + } else { + // pThis->setShape(TopoDS_Wire()); + std::string mesg = + std::string("Invalid Wire err:=") + toString(mkWire.Error()); + std::cerr << mesg << std::endl; + } } + CATCH_AND_RETHROW("Failed to create wire"); info.GetReturnValue().Set(info.This()); } -v8::Local Wire::Clone() const -{ - Wire* obj = new Wire(); +v8::Local Wire::Clone() const { + Nan::EscapableHandleScope scope; + + Wire *obj = new Wire(); v8::Local instance = makeInstance(_template); obj->Wrap(instance); obj->setShape(this->shape()); - return instance; + return scope.Escape(instance); } -NAN_METHOD(Wire::InitNew) -{ +NAN_METHOD(Wire::InitNew) { Base::InitNew(info); REXPOSE_READ_ONLY_PROPERTY_INTEGER(Wire, numVertices); REXPOSE_READ_ONLY_PROPERTY_INTEGER(Wire, numEdges); REXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Wire, isClosed); } -void Wire::Init(v8::Local target) -{ +NAN_MODULE_INIT(Wire::Init) { // Prepare constructor template - v8::Local tpl = Nan::New(Wire::New); + v8::Local tpl = + Nan::New(Wire::New); tpl->SetClassName(Nan::New("Wire").ToLocalChecked()); - // object has one internal filed ( the C++ object) + // object has one internal field ( the C++ object) tpl->InstanceTemplate()->SetInternalFieldCount(1); _template.Reset(tpl); @@ -149,27 +177,23 @@ void Wire::Init(v8::Local target) Base::InitProto(proto); - EXPOSE_METHOD(Wire,getEdges); - EXPOSE_METHOD(Wire,getVertices); + EXPOSE_METHOD(Wire, getEdges); + EXPOSE_METHOD(Wire, getVertices); EXPOSE_READ_ONLY_PROPERTY_INTEGER(Wire, numVertices); EXPOSE_READ_ONLY_PROPERTY_INTEGER(Wire, numEdges); EXPOSE_READ_ONLY_PROPERTY_BOOLEAN(Wire, isClosed); - Nan::Set(target,Nan::New("Wire").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); + Nan::Set(target, Nan::New("Wire").ToLocalChecked(), + Nan::GetFunction(tpl).ToLocalChecked()); } -NAN_METHOD(Wire::getEdges) -{ - Wire* pThis = UNWRAP(Wire); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_EDGE); +NAN_METHOD(Wire::getEdges) { + Wire *pThis = UNWRAP(Wire); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_EDGE); info.GetReturnValue().Set(arr); } -NAN_METHOD(Wire::getVertices) -{ - Wire* pThis = UNWRAP(Wire); - auto arr = extract_shapes_as_javascript_array(pThis,TopAbs_VERTEX); +NAN_METHOD(Wire::getVertices) { + Wire *pThis = UNWRAP(Wire); + auto arr = extract_shapes_as_javascript_array(pThis, TopAbs_VERTEX); info.GetReturnValue().Set(arr); } - - - diff --git a/src/Wire.h b/src/Wire.h index 9fa1386..9fddc0c 100644 --- a/src/Wire.h +++ b/src/Wire.h @@ -5,30 +5,27 @@ class Wire : public Base { - TopoDS_Wire m_wire; -public: - int numVertices(); - int numEdges(); - bool isClosed(); - - - virtual const TopoDS_Shape& shape() const; - const TopoDS_Wire& wire() const { - return m_wire; - } - virtual void setShape(const TopoDS_Shape&); - virtual v8::Local Clone() const ; - virtual Base* Unwrap(v8::Local obj) const { - return Nan::ObjectWrap::Unwrap(obj); - } + TopoDS_Wire m_wire; - static void Init(v8::Local target); - static NAN_METHOD(New); - static NAN_METHOD(getEdges); - static NAN_METHOD(getVertices); - - static NAN_METHOD(NewInstance); - virtual void InitNew(_NAN_METHOD_ARGS); - - static Nan::Persistent _template; +public: + int numVertices(); + int numEdges(); + bool isClosed(); + + virtual const TopoDS_Shape &shape() const; + const TopoDS_Wire &wire() const { return m_wire; } + virtual void setShape(const TopoDS_Shape &); + virtual v8::Local Clone() const; + virtual Base *Unwrap(v8::Local obj) const { + return Nan::ObjectWrap::Unwrap(obj); + } + + static NAN_MODULE_INIT(Init); + static NAN_METHOD(New); + static NAN_METHOD(getEdges); + static NAN_METHOD(getVertices); + static NAN_METHOD(NewInstance); + virtual void InitNew(_NAN_METHOD_ARGS); + + static Nan::Persistent _template; }; \ No newline at end of file diff --git a/src/all.cc b/src/all.cc index 0dd2bd0..14dc925 100644 --- a/src/all.cc +++ b/src/all.cc @@ -12,8 +12,8 @@ #include "Shell.cc" #include "Solid.cc" #include "Tools.cc" -#include "Transformation.cc" #include "Transform.cc" +#include "Transformation.cc" #include "Util.cc" #include "V8Wrapper.cc" #include "Vertex.cc" diff --git a/test/debug_tools.ts b/test/debug_tools.ts new file mode 100644 index 0000000..af59f4d --- /dev/null +++ b/test/debug_tools.ts @@ -0,0 +1,60 @@ +import { IShell, ISolid } from ".."; + +const doDebug = true; +export function dumpSolid(b: ISolid) { + if (doDebug) { + console.log("num faces ", b.numFaces); + console.log("num shells ", b.numShells); + console.log("num edges ", b.getEdges().length); + console.log("num vertices ", b.getVertices().length); + console.log( + " faces = ", + b + .getFaces() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + console.log( + " edges = ", + b + .getEdges() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + console.log( + " vertices = ", + b + .getVertices() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + } +} +export function dumpShell(b: IShell) { + if (doDebug) { + console.log("num faces ", b.numFaces); + console.log("num edges ", b.getEdges().length); + console.log("num vertices ", b.getVertices().length); + console.log( + " faces = ", + b + .getFaces() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + console.log( + " edges = ", + b + .getEdges() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + console.log( + " vertices = ", + b + .getVertices() + .map((e) => b.getShapeName(e)) + .join(", ") + ); + } +} diff --git a/test/helpers.js b/test/helpers.js deleted file mode 100644 index 95d8b67..0000000 --- a/test/helpers.js +++ /dev/null @@ -1,29 +0,0 @@ -const getTemporaryFilePath = require("gettemporaryfilepath"); - -const _getTemporaryFilePath = function () { - let tmp = getTemporaryFilePath.apply(null, arguments); - return tmp.replace(/\\/g, "/"); -}; -exports.getTemporaryFilePath = _getTemporaryFilePath; - - -const fs = require("fs"); - -function remove_file(filename, optional_callback) { - - optional_callback = optional_callback || function() {}; - - fs.exists(filename, function (exists) { - - if (exists) { - //Show in green - //xx console.log('File exists. Deleting now ... ' + filename); - fs.unlink(filename, optional_callback); - } else { - //Show in red - console.log("File " + filename + " not found, so not deleting."); - optional_callback || optional_callback(); - } - }); -} -exports.remove_file = remove_file; diff --git a/test/helpers.ts b/test/helpers.ts new file mode 100644 index 0000000..84dd797 --- /dev/null +++ b/test/helpers.ts @@ -0,0 +1,24 @@ +import fs from "node:fs"; +import os from "node:os"; +import crypto from "node:crypto"; +import path from "node:path"; + +export function getTemporaryFilePath({ + prefix, + suffix +}: { + prefix?: string; + suffix: string; +}) { + const name = crypto.randomUUID(); + return path.join(os.tmpdir(), (prefix || "") + name + suffix); +} + +export function removeFile(filename: string) { + if (fs.existsSync(filename)) { + fs.unlinkSync(filename); + } else { + //Show in red + console.log("File " + filename + " not found, so not deleting."); + } +} diff --git a/test/test_BREP.ts b/test/test_BREP.ts new file mode 100644 index 0000000..b997292 --- /dev/null +++ b/test/test_BREP.ts @@ -0,0 +1,168 @@ +import assert from "assert"; +import should from "should"; +import { makeLegoBrick, ISolid, occ } from ".."; + +import { removeFile, getTemporaryFilePath } from "./helpers"; + +describe("testing BREP input output ", function () { + let b1_brep: string; + let b2_brep: string; + let b3_brep: string; + let b1_volume = 0; + let b1_area = 0; + before(() => { + b1_brep = getTemporaryFilePath({ prefix: "b1_", suffix: ".brep" }); + b2_brep = getTemporaryFilePath({ prefix: "b2_", suffix: ".brep" }); + b3_brep = getTemporaryFilePath({ prefix: "b3_", suffix: ".brep" }); + + create_shapes(); + }); + after((done) => { + removeFile(b1_brep); + removeFile(b2_brep); + removeFile(b3_brep); + done(); + }); + + function create_shapes() { + let box = occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1_result = occ.writeBREP(b1_brep, box); + b1_volume = box.volume; + b1_area = box.area; + + let cyl = occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); + let b2_result = occ.writeBREP(b2_brep, cyl); + + let b3_result = occ.writeBREP(b3_brep, [box, cyl]); + + b1_result.should.eql(true); + b2_result.should.eql(true); + b3_result.should.eql(true); + } + + it("should write a simple shape", function () { + create_shapes(); + }); + + describe(" readBREP ", function () { + it("ZZ1 - should throw an error if used with no argument", function () { + should(function () { + (occ.readBREP as any)(null, (err: Error) => { + err!.message.should.match(/expecting a filename/); + }); + }).throwError(); + }); + + it("ZZ2 - should call the callback method with an error if used with an invalid arguments", (done) => { + occ.readBREP( + "||this is a invalid filename||", + (err?: Error | null, _shapes?: ISolid[]) => { + err!.message.should.match(/cannot read/); + done(); + } + ); + }); + + it("ZZ3 - should call the callback with an error if the file doesn't exist", (done) => { + occ.readBREP( + "invalid file name", + (err?: Error | null, _shapes?: ISolid[]) => { + console.log(" intercepting error ", err); + assert(err !== undefined); + done(); + } + ); + }); + + it("ZZ4 - should read the shape back", (done) => { + occ.readBREP(b1_brep, (err?: Error | null, shapes?: ISolid[]) => { + should(err).eql(null); + + if (!err && shapes) { + shapes.length.should.equal(1); + shapes[0].numFaces.should.equal(6); + + shapes[0].volume.should.equal(b1_volume); + shapes[0].area.should.equal(b1_area); + } + done(err); + }); + }); + + it("ZZ5 - should read the shape back", (done) => { + occ.readBREP(b2_brep, (err?: Error | null, shapes?: ISolid[]) => { + if (!err && shapes) { + shapes.length.should.equal(1); + shapes[0].numFaces.should.equal(3); + } + done(err); + }); + }); + + it("ZZ6 - should read the shape back", (done) => { + occ.readBREP(b3_brep, (err?: Error | null, shapes?: ISolid[]) => { + if (!err && shapes) { + shapes.length.should.equal(2); + shapes[0].numFaces.should.equal(6); + shapes[1].numFaces.should.equal(3); + } + done(); + }); + }); + }); +}); + +function build_large_part() { + let lego_filename = getTemporaryFilePath({ + prefix: "legoPlate3x2_2x2", + suffix: "" + }); + + let legoPlate = makeLegoBrick(occ, 3, 2, "thin"); + let solids: ISolid[] = []; + for (let x = 0; x < 100; x += 50) { + for (let y = 0; y < 100; y += 50) { + solids.push(legoPlate.translate([x, y, 0])); + } + } + occ.writeBREP(lego_filename + ".brep", solids); + + /* + occ.writeSTL(lego_filename + ".stl", solids); + + let obj = {solids: []}; + let counter = 0; + solids.forEach(function (solid) { + solid.name = "S" + counter; + counter++; + obj.solids.push(occ.buildSolidMesh(solid)); + }); + fs.writeFile(lego_filename + ".3js", JSON.stringify(obj, null, ""), function (err) { + console.log("OK"); + }); + + */ + return lego_filename; +} + +describe("it should write and read a large brep file", function (this: Mocha.Suite) { + this.timeout(15000); + + let filename = build_large_part(); + + it("should read a large BREP file quickly", (done) => { + console.log(" lego file ", filename); + + occ.readBREP( + filename + ".brep", + (err?: Error | null, solids?: ISolid[]) => { + console.log(" read !!!"); + + if (!err && solids) { + console.log(" num Faces = ", solids[0].numFaces); + } + done(err); + } + ); + }); +}); diff --git a/test/test_BoundingBox.js b/test/test_BoundingBox.js deleted file mode 100644 index 1218326..0000000 --- a/test/test_BoundingBox.js +++ /dev/null @@ -1,72 +0,0 @@ -const occ = require("../lib/occ"); -require("../lib/shapeFactory"); - - - -describe("testing bounding box",function(){ - describe("an empty BoundingBox", function() { - let bbox; - before(function() { - bbox = new occ.BoundingBox(); - }); - it("should be void", function() { - bbox.isVoid.should.equal(true); - }); - }); - describe("an BoundingBox built with a single point in constructor", function() { - let bbox; - before(function() { - bbox = new occ.BoundingBox([10,20,30]); - }); - it("should not be void", function() { - bbox.isVoid.should.equal(false); - }); - it("should have nearPt to be correct", function() { - bbox.nearPt.x.should.equal(10); - bbox.nearPt.y.should.equal(20); - bbox.nearPt.z.should.equal(30); - }); - it("should have farPt to be correct", function() { - bbox.farPt.x.should.equal(10); - bbox.farPt.y.should.equal(20); - bbox.farPt.z.should.equal(30); - }); - }); - describe("adding a single point to an empty bounding box", function(){ - let bbox; - before(function() { - bbox = new occ.BoundingBox(); - bbox.addPoint([10,20,30]); - }); - it("should not be void", function() { - bbox.isVoid.should.equal(false); - }); - it("should have nearPt to be correct", function() { - bbox.nearPt.x.should.equal(10); - bbox.nearPt.y.should.equal(20); - bbox.nearPt.z.should.equal(30); - }); - it("should have farPt to be correct", function() { - bbox.farPt.x.should.equal(10); - bbox.farPt.y.should.equal(20); - bbox.farPt.z.should.equal(30); - }); - }); - describe("checking calling isOut on a empty box",function() { - it("should return isOut = true for any point ",function(){ - let bbox= new occ.BoundingBox(); - bbox.isOut([10,20,30]).should.equal(true); - }); - }); - describe("checking calling isOut this box [-10,-10,-10],[5,5,5]",function() { - let bbox= new occ.BoundingBox([-10,-10,-10],[5,5,5]); - it("should return isOut = true for [10,20,30] ",function(){ - bbox.isOut([10,20,30]).should.equal(true); - }); - it("should return isOut = false for [1,2,3] ",function(){ - bbox.isOut([1,2,3]).should.equal(false); - }); - }); - - -}); diff --git a/test/test_BoundingBox.ts b/test/test_BoundingBox.ts new file mode 100644 index 0000000..c4c1342 --- /dev/null +++ b/test/test_BoundingBox.ts @@ -0,0 +1,68 @@ +import { IBoundingBox, BoundingBox } from ".."; +import "should"; + +describe("testing bounding box", function () { + describe("an empty BoundingBox", function () { + let bbox: IBoundingBox; + before(function () { + bbox = new BoundingBox(); + }); + it("should be void", function () { + bbox.isVoid.should.equal(true); + }); + }); + describe("an BoundingBox built with a single point in constructor", function () { + let bbox: IBoundingBox; + before(function () { + bbox = new BoundingBox([10, 20, 30]); + }); + it("should not be void", function () { + bbox.isVoid.should.equal(false); + }); + it("should have nearPt to be correct", function () { + bbox.nearPt.x.should.equal(10); + bbox.nearPt.y.should.equal(20); + bbox.nearPt.z.should.equal(30); + }); + it("should have farPt to be correct", function () { + bbox.farPt.x.should.equal(10); + bbox.farPt.y.should.equal(20); + bbox.farPt.z.should.equal(30); + }); + }); + describe("adding a single point to an empty bounding box", function () { + let bbox: IBoundingBox; + before(function () { + bbox = new BoundingBox(); + bbox.addPoint([10, 20, 30]); + }); + it("should not be void", function () { + bbox.isVoid.should.equal(false); + }); + it("should have nearPt to be correct", function () { + bbox.nearPt.x.should.equal(10); + bbox.nearPt.y.should.equal(20); + bbox.nearPt.z.should.equal(30); + }); + it("should have farPt to be correct", function () { + bbox.farPt.x.should.equal(10); + bbox.farPt.y.should.equal(20); + bbox.farPt.z.should.equal(30); + }); + }); + describe("checking calling isOut on a empty box", function () { + it("should return isOut = true for any point ", function () { + let bbox = new BoundingBox(); + bbox.isOut([10, 20, 30]).should.equal(true); + }); + }); + describe("checking calling isOut this box [-10,-10,-10],[5,5,5]", function () { + let bbox = new BoundingBox([-10, -10, -10], [5, 5, 5]); + it("should return isOut = true for [10,20,30] ", function () { + bbox.isOut([10, 20, 30]).should.equal(true); + }); + it("should return isOut = false for [1,2,3] ", function () { + bbox.isOut([1, 2, 3]).should.equal(false); + }); + }); +}); diff --git a/test/test_GLTF.ts b/test/test_GLTF.ts new file mode 100644 index 0000000..98255b3 --- /dev/null +++ b/test/test_GLTF.ts @@ -0,0 +1,13 @@ +import { occ } from ".."; + +import { removeFile, getTemporaryFilePath } from "./helpers"; + +describe("testing GTLF", () => { + it("should output a GLTF file", () => { + const outputFile = getTemporaryFilePath({ prefix: "b1_", suffix: ".gtlf" }); + let box = occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1_result = occ.writeGLTF(outputFile, box); + + console.log("result", outputFile); + }); +}); diff --git a/test/test_ReadWriteSTEP.js b/test/test_ReadWriteSTEP.js deleted file mode 100644 index 9731d16..0000000 --- a/test/test_ReadWriteSTEP.js +++ /dev/null @@ -1,120 +0,0 @@ -/*eslint-env node mocha*/ -/*global require*/ -// test_STEP -const assert = require("assert"); -require("should"); -const occ = require("../lib/occ"); - - - -const getTemporaryFilePath = require("./helpers").getTemporaryFilePath; -const remove_file = require("./helpers").remove_file; - -describe("testing STEP input output ", function () { - - let b1_step, b2_step, b3_step; - - before(function () { - - b1_step = getTemporaryFilePath({prefix: "b1_", suffix: ".step"}); - b2_step = getTemporaryFilePath({prefix: "b2_", suffix: ".step"}); - b3_step = getTemporaryFilePath({prefix: "b3_", suffix: ".step"}); - - let box = occ.makeBox([0, 0, 0], [100, 200, 300]); - let b1 = occ.writeSTEP(b1_step, box); - - - let cyl = occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); - let b2 = occ.writeSTEP(b2_step, cyl); - let b3 = occ.writeSTEP(b3_step, [box, cyl]); - - b1.should.eql(true); - b2.should.eql(true); - b3.should.eql(true); - }); - after(function () { - remove_file(b1_step); - remove_file(b2_step); - remove_file(b3_step); - }); - - it("AZ0 - should write a simple shape", function (done) { - let box = occ.makeBox([0, 0, 0], [100, 200, 300]); - let b1 = occ.writeSTEP(b1_step, box); - done(); - }); - - it("AZ1 - readSTEP with callback ", function (done) { - - let callback_called = 0; - occ.readSTEP(b3_step, (err, shapes) => { - console.log(err,shapes); - shapes.length.should.equal(2); - shapes[0].numFaces.should.equal(6); - shapes[1].numFaces.should.equal(3); - callback_called.should.be.greaterThan(-1); - done(); - }, function callback(message, percent) { - callback_called++; - }); - }); - - - it("AZ2 - should raise an exception with invalid arguments", function () { - (function () { - occ.readSTEP(); - }).should.throwError(); - - (function () { - occ.readSTEP("filename"); - }).should.throwError(); - - }); - - it("AZ3 - should call the callback with an error if the file doesn't exist", function (done) { - - occ.readSTEP("invalid file name", function (err, shapes) { - err.message.should.match(/invalid file name/); - done(); - }); - }); - it("AZ4 - should read file one", function (done) { - - occ.readSTEP(b1_step, function (err, shapes) { - if (err) { - console.log(" err = ", err, shapes); - } - assert(!err); - shapes.length.should.equal(1); - shapes[0].numFaces.should.equal(6); - done(); - }); - }); - - it("AZ5 - should read file two", function (done) { - - occ.readSTEP(b2_step, function (err, shapes) { - if (err) { - console.log(" err = ", err, shapes); - } - assert(!err); - shapes.length.should.equal(1); - shapes[0].numFaces.should.equal(3); - done(); - }); - - }); - it("AZ6 - should read file three", function (done) { - occ.readSTEP(b3_step, function (err, shapes) { - if (err) { - console.log(" err = ", err, shapes); - } - assert(!err); - shapes.length.should.equal(2); - shapes[0].numFaces.should.equal(6); - shapes[1].numFaces.should.equal(3); - done(); - }); - }); - -}); diff --git a/test/test_ReadWriteSTEP.ts b/test/test_ReadWriteSTEP.ts new file mode 100644 index 0000000..fd7b64d --- /dev/null +++ b/test/test_ReadWriteSTEP.ts @@ -0,0 +1,109 @@ +/*eslint-env node mocha*/ +/*global require*/ +// test_STEP +import assert from "assert"; +import "should"; +import { ISolid, occ } from ".."; +import { getTemporaryFilePath, removeFile } from "./helpers"; +import { IoT1ClickProjects } from "aws-sdk"; + +describe("testing STEP input output ", function () { + let b1_step: string; + let b2_step: string; + let b3_step: string; + + before(function () { + b1_step = getTemporaryFilePath({ prefix: "b1_", suffix: ".step" }); + b2_step = getTemporaryFilePath({ prefix: "b2_", suffix: ".step" }); + b3_step = getTemporaryFilePath({ prefix: "b3_", suffix: ".step" }); + + let box = occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1 = occ.writeSTEP(b1_step, box); + + let cyl = occ.makeCylinder([0, 0, 0], [0, 0, 10], 5); + let b2 = occ.writeSTEP(b2_step, cyl); + let b3 = occ.writeSTEP(b3_step, [box, cyl]); + + b1.should.eql(true); + b2.should.eql(true); + b3.should.eql(true); + }); + after(function () { + removeFile(b1_step); + removeFile(b2_step); + removeFile(b3_step); + }); + + it("AZ0 - should write a simple shape", () => { + let box = occ.makeBox([0, 0, 0], [100, 200, 300]); + let b1 = occ.writeSTEP(b1_step, box); + }); + + it("AZ1 - readSTEP with callback ", function (done) { + occ.readSTEP(b3_step, (err, shapes) => { + console.log(err, shapes); + shapes.length.should.equal(2); + const shape0 = shapes[0] as ISolid; + const shape1 = shapes[1] as ISolid; + shape0.numFaces.should.equal(6); + shape1.numFaces.should.equal(3); + done(); + }); + }); + + it("AZ2 - should raise an exception with invalid arguments", function () { + (function () { + (occ as any).readSTEP(); + }).should.throwError(); + + (function () { + (occ as any).readSTEP("filename"); + }).should.throwError(); + }); + + it("AZ3 - should call the callback with an error if the file doesn't exist", function (done) { + occ.readSTEP("invalid file name", function (err, shapes) { + if (err) { + err.message.should.match(/invalid file name/); + } else { + return done(new Error("Expecting Error")); + } + done(); + }); + }); + it("AZ4 - should read file one", function (done) { + occ.readSTEP(b1_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + assert(!err); + shapes.length.should.equal(1); + (shapes[0] as ISolid).numFaces.should.equal(6); + done(); + }); + }); + + it("AZ5 - should read file two", function (done) { + occ.readSTEP(b2_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + assert(!err); + shapes.length.should.equal(1); + (shapes[0] as ISolid).numFaces.should.equal(3); + done(); + }); + }); + it("AZ6 - should read file three", function (done) { + occ.readSTEP(b3_step, function (err, shapes) { + if (err) { + console.log(" err = ", err, shapes); + } + assert(!err); + shapes.length.should.equal(2); + (shapes[0] as ISolid).numFaces.should.equal(6); + (shapes[1] as ISolid).numFaces.should.equal(3); + done(); + }); + }); +}); diff --git a/test/test_applyTransform.js b/test/test_applyTransform.js deleted file mode 100644 index e1a110a..0000000 --- a/test/test_applyTransform.js +++ /dev/null @@ -1,38 +0,0 @@ - -const occ = require("../lib/occ"); -const should = require("should"); - -describe("testing various transformation",function() { - - - function getVerticeData(box) { - let vert = box.getVertices(); - vert = vert.map(function(v) { return [v.x, v.y, v.z]; }); - vert.length.should.eql(8); - return vert; - } - function add(v1,v2) { - return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2]]; - } - - it("#applyTransform",function(){ - - let box = occ.makeBox([0,0,0],[100,200,300]); - - let trsf=new occ.Transformation(); - trsf.makeTranslation([10,20,30]); - - let vert = getVerticeData(box); - - vert[1].should.eql([0,0,0]); - box.applyTransform(trsf); - - let vert_after = getVerticeData(box); - - // translate vertex - vert = vert.map(function(v){ return add(v,[10,20,30])}); - vert_after.should.eql(vert); - - }); - -}); \ No newline at end of file diff --git a/test/test_applyTransform.ts b/test/test_applyTransform.ts new file mode 100644 index 0000000..abdcf55 --- /dev/null +++ b/test/test_applyTransform.ts @@ -0,0 +1,32 @@ +import { IBoundingBox, ISolid, Transformation, Triplet, occ } from ".."; +import "should"; + +describe("testing various transformation", function () { + function getVerticeData(box: IBoundingBox | ISolid): Triplet[] { + let vert = box.getVertices(); + const triplets = vert.map((v) => [v.x, v.y, v.z] as Triplet); + triplets.length.should.eql(8); + return triplets; + } + function add(v1: Triplet, v2: Triplet): Triplet { + return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]]; + } + + it("#applyTransform", function () { + let box = occ.makeBox([0, 0, 0], [100, 200, 300]); + + let trsf = new Transformation(); + trsf.makeTranslation([10, 20, 30]); + + let vert = getVerticeData(box); + + vert[1].should.eql([0, 0, 0]); + box.applyTransform(trsf); + + let vert_after = getVerticeData(box); + + // translate vertex + vert = vert.map((v) => add(v, [10, 20, 30])); + vert_after.should.eql(vert); + }); +}); diff --git a/test/test_create_proxy_object.ts b/test/test_create_proxy_object.ts new file mode 100644 index 0000000..27a169c --- /dev/null +++ b/test/test_create_proxy_object.ts @@ -0,0 +1,40 @@ +import should from "should"; +import { calculateOperationHash, createProxyObject } from "../dist/fastbuilder"; + +describe("testing calculateOperationHash", function () { + it("should calculate the hash of 10,20,30", function () { + calculateOperationHash("myFunc", [10, 20, 30], false)[1].should.equal( + "myFunc(10,20,30)" + ); + }); + it("should calculate the hash of [10,20,30]", function () { + calculateOperationHash("myFunc", [[10, 20, 30]], false)[1].should.equal( + "myFunc([10,20,30])" + ); + }); + it('should calculate the hash of [10,20,30], "Hello"', function () { + calculateOperationHash( + "myFunc", + [[10, 20, 30], "Hello"], + false + )[1].should.equal('myFunc([10,20,30],"Hello")'); + }); +}); + +describe("testing createProxyObject", function () { + it("CF1 should ", () => { + const a = { + add(a1: number, a2: number): number { + return a1 + a2; + } + }; + + const b = createProxyObject(a); + + const resultFromB = b.add(1, 2); + + const resultFromA = a.add(1, 2); + + should(resultFromA).eql(resultFromB); + }); +}); diff --git a/test/test_edge.js b/test/test_edge.js deleted file mode 100644 index 88e7c7e..0000000 --- a/test/test_edge.js +++ /dev/null @@ -1,147 +0,0 @@ -const should = require("should"); -const occ = require("../lib/occ"); - -describe("testing Edges ",function(){ - - describe("EDGE0 - constructing an empty Edge",function(){ - let edge; - before(function(){ - edge = new occ.Edge() - should.exist(edge); - }); - it("should be valid", function(){ - edge.isNull.should.equal(true); - }); - it("should have a zero length", function(){ - edge.length.should.equal(0); - }); - it("should have a zero vertices", function(){ - edge.numVertices.should.equal(0); - }); - it("should be degenerated", function(){ - edge.isDegenerated.should.equal(true); - }); - it("shouldn't be closed", function(){ - edge.isClosed.should.equal(false); - }); - it("should provide a bounding box", function () { - edge.getBoundingBox().should.be.instanceOf(occ.BoundingBox); - edge.getBoundingBox().isVoid.should.eql(true); - }); - }); - describe("EDGE1 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) ",function(){ - let edge; - before(function(){ - let v1 = new occ.Vertex(10,20,30); - let v2 = new occ.Vertex(-30,20,30); - edge = occ.makeLine(v1, v2); - edge.should.be.instanceOf(occ.Edge); - - }); - it("should have a length of 40.0 ", function() { - edge.length.should.equal(40.0); - }); - it("should have two vertices ", function() { - edge.numVertices.should.equal(2.0); - }); - it("shouldn't be closed", function() { - edge.isClosed.should.equal(false); - }); - it("shouldn't be degenerated", function() { - edge.isDegenerated.should.equal(false); - }); - it("should provide a bounding box", function () { - edge.getBoundingBox().should.be.instanceOf(occ.BoundingBox); - edge.getBoundingBox().isVoid.should.eql(false); - - edge.getBoundingBox().nearPt.equals(new occ.Point3D(-30, 20, 30)).should.eql(true); - edge.getBoundingBox().nearPt.equals([-30, 20, 30]).should.eql(true); - edge.getBoundingBox().farPt.equals([10, 20, 30]).should.eql(true); - - let extra = 0.000000000001; - edge.getBoundingBox().farPt.asArray().should.eql([10 + extra, 20 + extra, 30 + extra]); - }); - it("should polygonize a segment with two points", function () { - console.log("polyligonize"); - let polyline = edge.polygonize(); - console.log("polyligonize2"); - polyline.length.should.eql(3 * 2); - [polyline[0], polyline[1], polyline[2]].should.eql([10, 20, 30]); - let l = polyline.length; - - (l % 3).should.eql(0); - [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([-30, 20, 30]); - }); - }); - - describe("EDGE2 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) and translated by [1,2,3]", function () { - let edge; - before(function () { - let v1 = new occ.Vertex(10, 20, 30); - let v2 = new occ.Vertex(-30, 20, 30); - edge = occ.makeLine(v1, v2); - edge = edge.translate([1, 2, 3]); - }); - it("should have a length of 40.0 ", function () { - edge.length.should.equal(40.0); - }); - it("should provide a bounding box", function () { - edge.getBoundingBox().nearPt.equals([-29, 22, 33]).should.eql(true); - edge.getBoundingBox().farPt.equals([11, 22, 33]).should.eql(true); - }); - it("should polygonize a segment with two points", function () { - let polyline = edge.polygonize(); - polyline.length.should.eql(3 * 2); - [polyline[0], polyline[1], polyline[2]].should.eql([11, 22, 33]); - let l = polyline.length; - (l % 3).should.eql(0); - [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([-29, 22, 33]); - }); - - }); - describe("EDGE3 - an Edge constructed as a Circle on the Z+ plan with a radius of 20", function () { - let edge; - before(function(){ - edge = occ.makeCircle([10, 10, 10], [0, 0, 1], 20); - }); - - it("should have a length of 2*PI*20.0 ", function(){ - let epsilon = 1E-2; - let PI = 3.1415; - edge.length.should.be.within(2*PI*20.0-epsilon,2*PI*20.0+epsilon); - }); - it("should have a unique vertex ", function(){ - edge.numVertices.should.equal(1); - }); - it("should be closed", function(){ - edge.isClosed.should.equal(true); - }); - it("shouldn't be degenerated", function(){ - edge.isDegenerated.should.equal(false); - }); - - it("should provide a bounding box", function () { - edge.getBoundingBox().should.be.instanceOf(occ.BoundingBox); - edge.getBoundingBox().isVoid.should.eql(false); - //xx console.log(JSON.stringify(edge.getBoundingBox()));//.toString()); - edge.getBoundingBox().nearPt.equals([-11.647844, -11.647844, 10]); - edge.getBoundingBox().farPt.equals([31.647844, 31.647844, 10]); - }); - - it("should polygonize a edge", function () { - - let a = edge.polygonize(); - - [a[0], a[1], a[2]].should.eql([30, 10, 10]); - let l = a.length; - - (l % 3).should.eql(0); - [a[l - 3], a[l - 2], a[l - 1]].should.eql([30, 10, 10]); - //xx console.log(a); - - }); - }); - describe("EDGE4 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) ", function () { - - }); -}); diff --git a/test/test_edge.ts b/test/test_edge.ts new file mode 100644 index 0000000..af276b9 --- /dev/null +++ b/test/test_edge.ts @@ -0,0 +1,173 @@ +import should from "should"; +import { occ, Edge, BoundingBox, IEdge, Vertex, Point, PointLike } from ".."; +const { makeLine } = occ; + +describe("testing Edges ", function () { + describe("EDGE0 - constructing an empty Edge", function () { + let edge: IEdge; + before(function () { + edge = new Edge(); + should.exist(edge); + }); + it("should be valid", function () { + edge.isNull.should.equal(true); + }); + it("should have a zero length", function () { + edge.length.should.equal(0); + }); + it("should have a zero vertices", function () { + edge.numVertices.should.equal(0); + }); + it("should be degenerated", function () { + edge.isDegenerated.should.equal(true); + }); + it("shouldn't be closed", function () { + edge.isClosed.should.equal(false); + }); + it("should provide a bounding box", function () { + edge.getBoundingBox().should.be.instanceOf(BoundingBox); + edge.getBoundingBox().isVoid.should.eql(true); + }); + }); + describe("Wire1 - an Wire constructed as as a linear Segment between (10,20,30) and (-30,20,30) ", function () { + let edge: IEdge; + before(function () { + let v1 = new Vertex(10, 20, 30); + let v2 = new Vertex(-30, 20, 30); + edge = makeLine(v1, v2); + edge.should.be.instanceOf(Edge); + }); + it("should have a length of 40.0 ", function () { + edge.length.should.equal(40.0); + }); + it("should have two vertices ", function () { + edge.numVertices.should.equal(2.0); + }); + it("shouldn't be closed", function () { + edge.isClosed.should.equal(false); + }); + it("shouldn't be degenerated", function () { + edge.isDegenerated.should.equal(false); + }); + it("should provide a bounding box", function () { + edge.getBoundingBox().should.be.instanceOf(BoundingBox); + edge.getBoundingBox().isVoid.should.eql(false); + + edge + .getBoundingBox() + .nearPt.equals(new Point(-30, 20, 30)) + .should.eql(true); + edge.getBoundingBox().nearPt.equals([-30, 20, 30]).should.eql(true); + edge.getBoundingBox().farPt.equals([10, 20, 30]).should.eql(true); + + let extra = 0.000000000001; + edge + .getBoundingBox() + .farPt.asArray() + .should.eql([10 + extra, 20 + extra, 30 + extra]); + }); + it("should polygonize a segment with two points", function () { + console.log("polyligonize"); + let polyline = edge.polygonize(); + console.log("polyligonize2"); + polyline.length.should.eql(3 * 2); + [polyline[0], polyline[1], polyline[2]].should.eql([10, 20, 30]); + let l = polyline.length; + + (l % 3).should.eql(0); + [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([ + -30, 20, 30 + ]); + }); + }); + + describe("EDGE2 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) and translated by [1,2,3]", function () { + let edge: IEdge; + before(function () { + let v1 = occ.makeVertex(10, 20, 30); + let v2 = occ.makeVertex(-30, 20, 30); + edge = occ.makeLine(v1, v2); + edge = edge.translate([1, 2, 3]); + }); + it("should have a length of 40.0 ", function () { + edge.length.should.equal(40.0); + }); + it("should provide a bounding box", function () { + edge.getBoundingBox().nearPt.equals([-29, 22, 33]).should.eql(true); + edge.getBoundingBox().farPt.equals([11, 22, 33]).should.eql(true); + }); + it("should polygonize a segment with two points", function () { + let polyline = edge.polygonize(); + polyline.length.should.eql(3 * 2); + [polyline[0], polyline[1], polyline[2]].should.eql([11, 22, 33]); + let l = polyline.length; + (l % 3).should.eql(0); + [polyline[l - 3], polyline[l - 2], polyline[l - 1]].should.eql([ + -29, 22, 33 + ]); + }); + }); + describe("Wire - an Wire constructed as a Circle on the Z+ plan with a radius of 20", function () { + let edge: IEdge; + before(function () { + edge = occ.makeCircle([10, 10, 10], [0, 0, 1], 20); + }); + + it("should have a length of 2*PI*20.0 ", function () { + let epsilon = 1e-2; + let PI = 3.1415; + edge.length.should.be.within( + 2 * PI * 20.0 - epsilon, + 2 * PI * 20.0 + epsilon + ); + }); + it("should have a unique vertex ", function () { + edge.numVertices.should.equal(1); + }); + it("should be closed", function () { + edge.isClosed.should.equal(true); + }); + it("shouldn't be degenerated", function () { + edge.isDegenerated.should.equal(false); + }); + + it("should provide a bounding box", function () { + edge.getBoundingBox().should.be.instanceOf(BoundingBox); + edge.getBoundingBox().isVoid.should.eql(false); + //xx console.log(JSON.stringify(edge.getBoundingBox()));//.toString()); + edge.getBoundingBox().nearPt.equals([-11.647844, -11.647844, 10]); + edge.getBoundingBox().farPt.equals([31.647844, 31.647844, 10]); + }); + + it("should polygonize a edge", function () { + let a = edge.polygonize(); + + [a[0], a[1], a[2]].should.eql([30, 10, 10]); + let l = a.length; + + (l % 3).should.eql(0); + [a[l - 3], a[l - 2], a[l - 1]].should.eql([30, 10, 10]); + //xx console.log(a); + }); + }); + describe("EDGE4 - an Edge constructed as as a linear Segment between (10,20,30) and (-30,20,30) ", function () {}); + + describe("EDGE5 - makeInterpolatedCurve", () => { + const points: PointLike[] = [ + [10, 0, 0], + [20, 20, 0], + [30, 0, 0] + ]; + + it("should interpolate a curve through 3 points", () => { + const edge = occ.makeInterpolatedCurve(points, false, 0.01); + + console.log(edge.firstVertex.toString()); + + console.log(edge.lastVertex.toString()); + + console.log(edge.polygonize().toString()); + console.log("l =", edge.length); + }); + }); +}); diff --git a/test/test_extrudeFace.js b/test/test_extrudeFace.js deleted file mode 100644 index 5fac143..0000000 --- a/test/test_extrudeFace.js +++ /dev/null @@ -1,34 +0,0 @@ - -const occ = require("../lib/occ"); -const should = require("should"); - -describe("demonstrate how to extrude a face",function() { - - it("extrudeFace",function() { - - // create a planar wire close line. - - const aPnt1 = [0, 0.0, 0]; - const aPnt2 = [10, 1.0, 0]; - const aPnt3 = [10, 9.0, 0]; - const aPnt4 = [0, 10.0, 0]; - const aSegment1 = new occ.makeLine(aPnt1, aPnt2); - const aSegment2 = new occ.makeLine(aPnt2, aPnt3); - const aSegment3 = new occ.makeLine(aPnt3, aPnt4); - const aSegment4 = new occ.makeLine(aPnt4, aPnt1); - - const aWire = new occ.Wire(aSegment1, aSegment2, aSegment3, aSegment4); - aWire.isClosed.should.equal(true); - aWire.numEdges.should.equal(4); - aWire.numVertices.should.equal(4); - - // the vector to extrude the face along. - const aVector = [-2, -2.0, 10]; - const aFace = new occ.Face(aWire); - - const myBody = occ.makePrism(aFace, aVector); - - occ.writeSTEP("extrudedFace.step",[myBody]); - - }); -}); diff --git a/test/test_extrudeFace.ts b/test/test_extrudeFace.ts new file mode 100644 index 0000000..50d338a --- /dev/null +++ b/test/test_extrudeFace.ts @@ -0,0 +1,30 @@ +import { Triplet, occ } from ".."; +import "should"; + +describe("demonstrate how to extrude a face", function () { + it("extrudeFace", function () { + // create a planar wire close line. + + const aPnt1: Triplet = [0, 0.0, 0]; + const aPnt2: Triplet = [10, 1.0, 0]; + const aPnt3: Triplet = [10, 9.0, 0]; + const aPnt4: Triplet = [0, 10.0, 0]; + const aSegment1 = occ.makeLine(aPnt1, aPnt2); + const aSegment2 = occ.makeLine(aPnt2, aPnt3); + const aSegment3 = occ.makeLine(aPnt3, aPnt4); + const aSegment4 = occ.makeLine(aPnt4, aPnt1); + + const aWire = occ.makeWire(aSegment1, aSegment2, aSegment3, aSegment4); + aWire.isClosed.should.equal(true); + aWire.numEdges.should.equal(4); + aWire.numVertices.should.equal(4); + + // the vector to extrude the face along. + const aVector: Triplet = [-2, -2.0, 10]; + const aFace = occ.makeFace(aWire); + + const myBody = occ.makePrism(aFace, aVector); + + occ.writeSTEP("extrudedFace.step", [myBody]); + }); +}); diff --git a/test/test_face.ts b/test/test_face.ts new file mode 100644 index 0000000..53e8565 --- /dev/null +++ b/test/test_face.ts @@ -0,0 +1,65 @@ +import should from "should"; +import { Vertex, occ } from ".."; + +// see https://npmjs.org/package/should + +describe("testing face mesh ", function () { + it("Face#mesh - should not have a mesh unless the parent solid has been meshed", function () { + // given a box solid + let solid = occ.makeBox([0, 0, 0], [10, 10, 10]); + + solid.faces.should.have.property("top"); + + let topFace = solid.faces.top; + should.exist(topFace); + + topFace.area.should.be.within(99.99, 100.0, "face area shall be 100.00"); + + topFace.hasMesh.should.equal(false); + + // now mesh the solid + let m = solid.mesh; + m.vertices.length.should.eql( + 8 * 3, + "expecting 8 vertices (made of 3 floats) in solid mesh" + ); + m.edgeIndices.length.should.eql(24); + m.triangles.length.should.eql(36); + + //xx console.log(m.toJSON()); + + // meshing the solid should cause each of its faces to be meshed + topFace.hasMesh.should.equal( + true, + "Face must have a mesh when parent solid is meshed" + ); + + //xx m.normals.length.should.eql(72); + //xx console.log(topFace.mesh.toJSON()); + let faceMesh = topFace.mesh; + + faceMesh.vertices.length.should.eql(3 * 4, "we expect 4 points "); + //xx faceMesh.normals.length.should.eql(3 * 4); + faceMesh.edgeIndices.length.should.eql(2 * 4); + faceMesh.triangles.length.should.eql(2 * 3); + }); +}); + +describe("testing face#getWire ", function () { + it("Face#getWire", function () { + let solid = occ.makeBox([0, 0, 0], [10, 10, 10]); + solid.faces.should.have.property("top"); + let topFace = solid.faces.top; + should.exist(topFace); + + let wires = topFace.getWires(); + wires.length.should.eql(1); + + wires[0].getEdges().length.should.eql(4); + + wires[0] + .getEdges()[0] + .getVertices()[0] + .should.eql(new Vertex({ x: 0, y: 10, z: 10 })); + }); +}); diff --git a/test/test_fastbuilder.ts b/test/test_fastbuilder.ts new file mode 100644 index 0000000..022bac0 --- /dev/null +++ b/test/test_fastbuilder.ts @@ -0,0 +1,188 @@ +import { occ, fastBuilder, ISolid, shapeFactory } from ".."; +import "should"; + +const fast_occ = fastBuilder; + +function makeShape() { + let e = 20; + let s1 = fast_occ.makeBox([10, e, 30], [110, 120, 130]); + let s2 = fast_occ.makeBox(100, 200, 300); + let s3 = fast_occ.fuse(s1, s2); + s3 = s3.translate([0, 20, 30]); + s3 = s3.translate([0, 20, 30]); + return s3; +} + +function startChronometer() { + return process.hrtime(); +} +function stopChronometer(time1: [number, number]) { + let diff0 = process.hrtime(time1); + let diff1 = diff0[0] * 1e9 + diff0[1]; // in nanoseconds + diff1 /= 1000.0; // in microseconds + diff1 /= 1000.0; // in miliseconds + diff1 /= 1000.0; // in seconds + return diff1; +} + +describe("testing geometry builder", function () { + before(function () { + fastBuilder.$.resetCache(); + }); + it("should create a bottle faster the second time ", function () { + fastBuilder.$.mapQueryCount.should.equal(0); + fastBuilder.$.mapHit.should.equal(0); + + let c1 = startChronometer(); + makeShape(); + let diff1 = stopChronometer(c1); + + fastBuilder.$.mapQueryCount.should.equal(5); + fastBuilder.$.mapHit.should.equal(0); + + let c2 = startChronometer(); + makeShape(); + let diff2 = stopChronometer(c2); + + fastBuilder.$.mapQueryCount.should.equal(10); + fastBuilder.$.mapHit.should.equal(5); + + console.log(" time to compute first box = ", diff1, " seconds"); + console.log(" time to compute second box = ", diff2, " seconds"); + console.log( + " speed up = ", + Math.round(((diff1 - diff2) / diff2) * 100), + "%" + ); + + diff1.should.be.greaterThan(diff2); + }); +}); + +describe("testing fast builder with array of shape", function () { + before(() => { + fastBuilder.$.resetCache(); + }); + it("should create a bottle faster the second time ", function () { + fastBuilder.$.mapQueryCount.should.equal(0); + fastBuilder.$.mapHit.should.equal(0); + let a: ISolid[] = []; + a.push(makeShape()); + a.push(makeShape().translate(10, 20, 30)); + a.push(makeShape().translate(30, 20, 30)); + + let compound = fast_occ.compound(a); + }); +}); + +describe("testing fast builder with makeThickSolid", function () { + let s1: ISolid; + let s2: ISolid; + before(function () { + s1 = fast_occ.makeBox([10, 20, 30], [110, 120, 130]); + s1 = fast_occ.makeThickSolid(s1, s1.faces.top, 6); + s2 = occ.makeBox([10, 20, 30], [110, 120, 130]); + s2 = occ.makeThickSolid(s2, s2.faces.top, 6); + }); + it(" should construct the same object as if using 'occ' ", function () { + s1.numFaces.should.equal(s2.numFaces); + }); +}); + +describe("testing fast builder with some built-in shapes", function () { + it("should create the bottle..", function () { + let s1 = shapeFactory.makeBottle(fastBuilder, { + filletRadius: 1, + height: 100 + }); + s1.numFaces.should.be.greaterThan(16); + }); +}); + +describe("testing fast builder with some shapes", function () { + it("should create the piston..", function () { + let s1 = shapeFactory.makePiston(fastBuilder); + s1.numFaces.should.be.greaterThan(7); + }); +}); + +describe("testing fast builder get Common Edge", function () { + let solid1: ISolid; + let solid2: ISolid; + + function buildFilletOnTopLeftEdge() { + let s1 = fast_occ.makeBox([10, 20, 30], [110, 120, 130]); + let edges = s1.getCommonEdges(s1.faces.front, s1.faces.left); + s1 = fast_occ.makeFillet(s1, edges, 10); + s1 = fast_occ.makeDraftAngle( + s1, + s1.faces["mleft:0"], + 0.1, + s1.faces["mbottom:0"] + ); + return s1; + } + + before(function () { + solid1 = buildFilletOnTopLeftEdge(); + solid2 = buildFilletOnTopLeftEdge(); + }); + it("should have 7 faces", function () { + solid1.numFaces.should.be.equal(7); + solid2.numFaces.should.be.equal(7); + }); +}); + +describe("testing fast-builder with impossible cone", function () { + let solid1: ISolid; + before(function () { + // this cone cannot be built : it has PI/2 for half-angle ! + }); + it("should have no solid", function () { + (function () { + solid1 = fast_occ.makeCone([0, 0, 0], [0, 0, 1], 1.5707963267948966, 10); + }).should.throwError(); + }); +}); + +describe("testing fast-builder with LEGO brick", function () { + this.timeout(10000); + + it("should produce a LEGO brick", function () { + function buildBrick() { + let nx = 3; + let ny = 6; + let brick24 = shapeFactory.makeLegoBrick(fast_occ, nx, ny, "thick"); + + brick24.numFaces.should.be.greaterThan(40); + + // now check with bounding box + let bbox = brick24.getBoundingBox(); + + let eps = 0.01; + bbox.nearPt.x.should.be.within(0 - eps, 0 + eps); + bbox.nearPt.y.should.be.within(0 - eps, 0 + eps); + bbox.nearPt.z.should.be.within(0 - eps, 0 + eps); + + bbox.farPt.x.should.be.within(nx * 8 - eps, nx * 8 + eps); + bbox.farPt.y.should.be.within(ny * 8 - eps, ny * 8 + eps); + bbox.farPt.z.should.be.within(11.2 - eps, 11.2 + eps); + } + + let c1 = startChronometer(); + buildBrick(); + let diff1 = stopChronometer(c1); + + let c2 = startChronometer(); + buildBrick(); + let diff2 = stopChronometer(c2); + + console.log(" time to compute first box = ", diff1, " seconds"); + console.log(" time to compute second box = ", diff2, " seconds"); + let speedup = Math.round(((diff1 - diff2) / diff2) * 100); + console.log(" speed up = ", speedup, "%"); + + diff1.should.be.greaterThan(diff2); + speedup.should.be.greaterThan(100); //"%" + }); +}); diff --git a/test/test_geometry.js b/test/test_geometry.js deleted file mode 100644 index 7785d59..0000000 --- a/test/test_geometry.js +++ /dev/null @@ -1,17 +0,0 @@ - -const occ = require("../lib/occ"); -const shapeFactory = require("../lib/shapeFactory"); - - -const getTemporaryFilePath = require("gettemporaryfilepath"); - - -describe("testing geometry builder",function(){ - it("should create a bottle", function () { - - let bottle_brep = getTemporaryFilePath({prefix: "bottle", suffix: ".brep"}); - let bottle = shapeFactory.makeBottle(occ); - occ.writeBREP(bottle_brep, bottle); - }); -}); - diff --git a/test/test_geometry.ts b/test/test_geometry.ts new file mode 100644 index 0000000..35ba5f1 --- /dev/null +++ b/test/test_geometry.ts @@ -0,0 +1,14 @@ +import { occ } from ".."; +import { getTemporaryFilePath } from "./helpers"; +import { makeBottle } from ".."; + +describe("testing geometry builder", function () { + it("should create a bottle", function () { + let bottle_brep = getTemporaryFilePath({ + prefix: "bottle", + suffix: ".brep" + }); + let bottle = makeBottle(occ, { height: 100, filletRadius: 2 }); + occ.writeBREP(bottle_brep, bottle); + }); +}); diff --git a/test/test_issue17_mesh_not_invalidated_when_face_moved.ts b/test/test_issue17_mesh_not_invalidated_when_face_moved.ts new file mode 100644 index 0000000..096695d --- /dev/null +++ b/test/test_issue17_mesh_not_invalidated_when_face_moved.ts @@ -0,0 +1,84 @@ +"use strict"; +import { Triplet, occ } from ".."; +import "should"; + +const doDebug = false; +function debugLog(...args: any[]) { + if (doDebug) { + console.log.apply(console, args); + } +} +describe("issue#17 testing that mesh get invalidated ", function () { + function constructFaceWithWire() { + const aPnt1: Triplet = [0, 0.0, 0]; + const aPnt2: Triplet = [10, 1.0, 0]; + const aPnt3: Triplet = [10, 9.0, 0]; + const aPnt4: Triplet = [0, 10.0, 0]; + const segment1 = occ.makeLine(aPnt1, aPnt2); + const segment2 = occ.makeLine(aPnt2, aPnt3); + const segment3 = occ.makeLine(aPnt3, aPnt4); + const segment4 = occ.makeLine(aPnt4, aPnt1); + + const wire = occ.makeWire(segment1, segment2, segment3, segment4); + wire.isClosed.should.equal(true); + wire.numEdges.should.equal(4); + wire.numVertices.should.equal(4); + + // the vector to extrude the face along. + const face = occ.makeFace(wire); + + face.getWires().length.should.eql(1); + + face.getWires()[0].getVertices().length.should.eql(4); + return face; + } + + it("should translate a face", function (done) { + let face = constructFaceWithWire(); + + const vertices_before = face.getWires()[0].getVertices(); + + face = face.translate([20, 30, 40]); + const vertices_after = face.getWires()[0].getVertices(); + + vertices_after[0].x.should.eql(vertices_before[0].x + 20); + vertices_after[0].y.should.eql(vertices_before[0].y + 30); + vertices_after[0].z.should.eql(vertices_before[0].z + 40); + + vertices_after[1].x.should.eql(vertices_before[1].x + 20); + vertices_after[1].y.should.eql(vertices_before[1].y + 30); + vertices_after[1].z.should.eql(vertices_before[1].z + 40); + + vertices_after[2].x.should.eql(vertices_before[2].x + 20); + vertices_after[2].y.should.eql(vertices_before[2].y + 30); + vertices_after[2].z.should.eql(vertices_before[2].z + 40); + + vertices_after[3].x.should.eql(vertices_before[3].x + 20); + vertices_after[3].y.should.eql(vertices_before[3].y + 30); + vertices_after[3].z.should.eql(vertices_before[3].z + 40); + + done(); + }); + + it("#17-B should provide a translated mesh when face is translated", function (done) { + let face = constructFaceWithWire(); + face.hasMesh.should.equal(false); + + // now mesh the faces + face.createMesh(0.1); + face.hasMesh.should.equal(true); + + debugLog("face mesh vertices =", face.mesh.vertices.toString()); + + const vertices_before = face.mesh.vertices; + face = face.translate([20, 30, 40]); + + debugLog("face mesh vertices =", face.mesh.vertices.toString()); + + const vertices_after = face.mesh.vertices; + + vertices_before.toString().should.eql("0,0,0,10,1,0,10,9,0,0,10,0"); + vertices_after.toString().should.eql("20,30,40,30,31,40,30,39,40,20,40,40"); + done(); + }); +}); diff --git a/test/test_makePipe.ts b/test/test_makePipe.ts new file mode 100644 index 0000000..47d6dcd --- /dev/null +++ b/test/test_makePipe.ts @@ -0,0 +1,38 @@ +import should from "should"; +import { Vertex, occ } from ".."; +import { dumpSolid, dumpShell } from "./debug_tools"; +describe("makePipe", () => { + it("should make a pipe from a spine which is a wire (circle) and a profile line ", () => { + const wire1 = occ.makeWire(occ.makeCircle([0, 0, 0], [0, 0, 1], 10)); + + const spine = occ.makeInterpolatedCurve( + [ + [0, 0, 0], + [0, 6, 10], + [0, 0, 20] + ], + false, + 0.01 + ); + const wire = occ.makeWire(spine); + const shell = occ.makePipe(wire, wire1); + dumpShell(shell); + }); + + // it("should make a pipe from a spine which is a Face and a profile line ", () => { + + // const wire1 = occ.makeWire(occ.makeCircle([0, 0, 0], [0, 0, 1], 10)); + // const face = occ.makeFace(wire1); + + // const spine = occ.makeWire(occ.makeInterpolatedCurve( + // [ + // [0, 0, 0], + // [0, 6, 10], + // [0, 0, 20], + + // ], false, 0.01)); + + // const solid = occ.makePipe(face, spine); + // dumpSolid(solid); + // }); +}); diff --git a/test/test_makePipeShell.ts b/test/test_makePipeShell.ts new file mode 100644 index 0000000..d735fa7 --- /dev/null +++ b/test/test_makePipeShell.ts @@ -0,0 +1,127 @@ +import should from "should"; +import { Triplet, IWire,Vertex, occ } from "../dist"; +import { dumpSolid, dumpShell } from "./debug_tools"; +import { getTemporaryFilePath } from "./helpers"; + + +const rotate = (point: Triplet, angleInDegree: number): Triplet => { + + // x2=cosβ*x−sinβ*y + // y2 = sinβ*x + cosβ*y + const angleInRadian = angleInDegree * Math.atan(1) / 45.0; + + const cosβ = Math.cos(angleInRadian); + const sinβ = Math.sin(angleInRadian); + const r = (x: number, y: number) => [cosβ * x - sinβ * y, sinβ * x + cosβ * y, 0]; + const [x, y, z] = point; + const [xp, yp] = r(x, y); + return [xp, yp, z]; +} +const rotTrans = (p1: Triplet, angleInDegree: number, deltaZ: number): Triplet => { + const [x, y, z] = rotate(p1, angleInDegree); + return [x, y, z + deltaZ] +} +interface IMakeHelixParams { + startPoint: Triplet; + angleInDegree: number, height: number, nbPoints: number; +} +function makeHelixPoints({ startPoint, angleInDegree, height, nbPoints }: IMakeHelixParams) { + const points: Triplet[] = [startPoint]; + for (let index = 1; index <= nbPoints; index++) { + const p = rotTrans(startPoint, angleInDegree / nbPoints * index, height / nbPoints * index) + points.push(p); + } + return points +} +describe("makePipeShell", () => { + it("should make a pipe from a spine which is a wire (circle) and a profile line ", () => { + + const wire = occ.makeWire(occ.makeCircle([0, 0, 0], [0, 0, 1], 10)); + + const spine = occ.makeWire(occ.makeInterpolatedCurve( + [ + [0, 0, 0], + [0, 6, 50], + [0, 0, 100] + ], + false, + 0.01 + )); + + const shell = occ.makePipeShell({ + wire, + spineSupport: spine, + solid: false, + }); + + dumpShell(shell); + + const b1_step = "pipe.step"; // getTemporaryFilePath({ prefix: "pipe_", suffix: ".step" }); + occ.writeSTEP(b1_step, shell as any); + + }); + + + it("should make a pipe from a spine which is a wire (circle) and a profile line ", () => { + + + // the triangle shape we want to twist along the z axis + const p1: Triplet = [10, 0, 0]; + const p2: Triplet = [8, 2, 0]; + const p3: Triplet = [8, -2, 0]; + const edge1 = occ.makeLine(p1, p2); + const edge2 = occ.makeLine(p2, p3); + const edge3 = occ.makeLine(p3, p1); + const wire = occ.makeWire([edge1, edge2, edge3]); + + // the spine is the Z -axis + const spine = occ.makeWire(occ.makeLine([0, 0, 0], [0, 0, 10])); + + + const angleInDegree = 90; + const height = 10; + const points = makeHelixPoints({ startPoint: p1, angleInDegree, height, nbPoints: 10 }); + + // we want a auxilary curve, one point should coincide with one edge of the triangle and + const auxilaryCurve = occ.makeWire(occ.makeInterpolatedCurve(points, false, 0.01)); + + const wires: IWire[] = [ + wire, + // wire.rotate([0, 0, 0], [0, 0, 1], angleInDegree/4).translate([0, 0, height/4]), + // wire.rotate([0, 0, 0], [0, 0, 1], angleInDegree/4*2).translate([0, 0, height/2]), + // wire.rotate([0, 0, 0], [0, 0, 1], angleInDegree/4*3).translate([0, 0, height/4*3]), + wire.rotate([0, 0, 0], [0, 0, 1], angleInDegree).translate([0, 0, height]) + ]; + // we are defining a shape + const solid = occ.makePipeShell({ + wires, + spineSupport: spine, + auxilaryCurve, + solid: false, + }); + + + + + const b2_step = "pipe2.step"; + occ.writeSTEP(b2_step, solid); + + }); + + // it("should make a pipe from a spine which is a Face and a profile line ", () => { + + // const wire1 = occ.makeWire(occ.makeCircle([0, 0, 0], [0, 0, 1], 10)); + // const face = occ.makeFace(wire1); + + // const spine = occ.makeWire(occ.makeInterpolatedCurve( + // [ + // [0, 0, 0], + // [0, 6, 10], + // [0, 0, 20], + + // ], false, 0.01)); + + // const solid = occ.makePipe(face, spine); + // dumpSolid(solid); + // }); +}); diff --git a/test/test_makeRevol.ts b/test/test_makeRevol.ts new file mode 100644 index 0000000..a497a96 --- /dev/null +++ b/test/test_makeRevol.ts @@ -0,0 +1,50 @@ +import { occ, IVertex, IEdge, IAxisLike } from ".."; +import { dumpSolid } from "./debug_tools"; +const { makeVertex, makeRevol, makeLine, makeWire, makeFace } = occ; + +describe("test makeRevol", function () { + it("should revolve a vertex into a egde", () => { + const zAxis: IAxisLike = [ + [0, 0, 0], + [0, 0, 1] + ]; + + const vertex: IVertex = makeVertex([10, 0, 0]); + const edge = makeRevol(vertex, zAxis, 180); + }); + + it("should revolve a edge into a wire", () => { + const zAxis: IAxisLike = [ + [0, 0, 0], + [0, 0, 1] + ]; + + const edge = makeLine([10, 0, 0], [10, 0, 10]); + const wire = makeRevol(edge, zAxis, 30); + }); + + it("should revolve a wire into a face", () => { + const zAxis: IAxisLike = [ + [0, 0, 0], + [0, 0, 1] + ]; + const edge1 = makeLine([10, 0, 0], [10, 0, 10]); + const edge2 = makeLine([10, 0, 10], [5, 0, 20]); + const wire = makeWire([edge1, edge2]); + + const face = makeRevol(wire, zAxis, 180); + }); + + it("should revolve a face into a solid", () => { + const zAxis: IAxisLike = [ + [0, 0, 0], + [0, 0, 1] + ]; + + const circle = occ.makeCircle([100, 0, 0], [1, 0, 0], 10); + const wire = makeWire(circle); + const face = makeFace(wire); + const solid = makeRevol(face, zAxis, 180); + dumpSolid(solid); + }); +}); diff --git a/test/test_meshSolid.ts b/test/test_meshSolid.ts new file mode 100644 index 0000000..ff6842b --- /dev/null +++ b/test/test_meshSolid.ts @@ -0,0 +1,324 @@ +import "should"; +import { IMesh, ISolid, Real, occ, shapeFactory } from ".."; + +const doDebug = false; + +function debugLog(...args: any[]) { + arguments; + /* implement me*/ +} + +describe("TBugLinux- testing mesh on a simple cone shape with radius2 = 0 returns 2 Faces (latteral+bottom)", function () { + // cf. https://github.com/antonymarion/node-occ-csg-editor-display/runs/1517044830?check_suite_focus=true + let shape: ISolid; + let mesh: IMesh; + before(function () { + shape = occ.makeCone([0, 0, 0], 2, [0, 0, 2], 0); + mesh = shape.createMesh(0.1); + }); + it("solid should have 2 faces", function () { + const myFaces = shape.getFaces(); + console.log("shape", shape); + console.log("cone Faces", myFaces); + myFaces.length.should.eql(2); + + // meshing should work on Linux ! (was not working w/ Linux pre compiled occ.node) + shape.hasMesh.should.be.eql(true); + shape.faces["lateral"].hasMesh.should.be.eql(true); + shape.faces["bottom"].hasMesh.should.be.eql(true); + }); +}); + +describe("T1- testing mesh on a simple box shape", function () { + let shape: ISolid; + let mesh: IMesh; + before(function () { + shape = occ.makeBox(10, 40, 100); + mesh = shape.createMesh(0.1); + }); + it("solid should have 6 faces", function () { + shape.getFaces().length.should.eql(6); + }); + it("Mesh#vertices - mesh should provide a vertex array", function () { + // ----------------------------------- testing vertices + mesh.vertices.length.should.eql(3 * 8); + + mesh.vertices[0].should.eql(0.0); + mesh.vertices[1].should.eql(0.0); + mesh.vertices[2].should.eql(0.0); + + mesh.vertices[3].should.eql(0.0); + mesh.vertices[4].should.eql(0.0); + mesh.vertices[5].should.eql(100.0); + + mesh.vertices[6].should.eql(0.0); + mesh.vertices[7].should.eql(40.0); + mesh.vertices[8].should.eql(0.0); + + mesh.vertices[9].should.eql(0.0); + mesh.vertices[10].should.eql(40.0); + mesh.vertices[11].should.eql(100.0); + + mesh.vertices[12].should.eql(10.0); + mesh.vertices[13].should.eql(0.0); + mesh.vertices[14].should.eql(0.0); + }); + it("Mesh#triangle - mesh should provide triangles indexes", function () { + // --------------------------------------- triangles + mesh.triangles.length.should.eql( + 6 * 2 * 3, + "it should provide 2 triangles per face = 2 *4 *3" + ); + }); + it("Mesh#faceRanges - mesh should provide a mechanism to easily identify triangle faces", function () { + mesh.faceRanges.length.should.eql( + 6 * 2, + "it should 6 pairs of index ( 6 faces, 2 values per face)" + ); + mesh.edgeRanges.length.should.eql( + 12 * 2, + "it should 12 pairs of index ( 12 edges, 2 values per face)" + ); + + // --------------------------------------- faces + // testing face 1 + mesh.faceRanges[0].should.eql(0); // start in triangle index + mesh.faceRanges[1].should.eql(2); // nb of triangles + + // testing face 2 + mesh.faceRanges[2].should.eql(2); // start in triangle index + mesh.faceRanges[3].should.eql(2); // nb of triangles + + // testing face 3 + mesh.faceRanges[4].should.eql(4); // start in triangle index + mesh.faceRanges[5].should.eql(2); // nb of triangles + + // testing face 4 + mesh.faceRanges[6].should.eql(6); // start in triangle index + mesh.faceRanges[7].should.eql(2); // nb of triangles + + // testing face 5 + mesh.faceRanges[8].should.eql(8); // start in triangle index + mesh.faceRanges[9].should.eql(2); // nb of triangles + + // testing face 6 + mesh.faceRanges[10].should.eql(10); // start in triangle index + mesh.faceRanges[11].should.eql(2); // nb of triangles + }); + it("Mesh#getFaceTriangles - mesh should provide a mechanism to extract triangles indexes of a given shape face", function () { + // --------------------------------------- face accessor + let arr = mesh.getFaceTriangles(shape.getFaces()[0]); + arr.should.eql(new Uint8Array([0, 1, 2, 2, 1, 3])); + + arr = mesh.getFaceTriangles(shape.getFaces()[1]); + arr.should.eql(new Uint8Array([5, 4, 6, 5, 6, 7])); + // etc... + }); + it("Mesh#edgeRanges - mesh should provide a mechanism to easily identify edges", function () { + // edge index + // --------------------------------------- edges + // testing edge 1 + mesh.edgeRanges[0].should.eql(0); // start in triangle index + mesh.edgeRanges[1].should.eql(2); // nb of triangles + + // testing edge 2 + mesh.edgeRanges[2].should.eql(2); // start in triangle index + mesh.edgeRanges[3].should.eql(2); // nb of triangles + + // testing edge 3 + mesh.edgeRanges[4].should.eql(4); // start in triangle index + mesh.edgeRanges[5].should.eql(2); // nb of triangles + + // testing edge 4 + mesh.edgeRanges[6].should.eql(6); // start in triangle index + mesh.edgeRanges[7].should.eql(2); // nb of triangles + + // testing edge 5 + mesh.edgeRanges[8].should.eql(8); // start in triangle index + mesh.edgeRanges[9].should.eql(2); // nb of triangles + + // testing edge 6 + mesh.edgeRanges[10].should.eql(10); // start in triangle index + mesh.edgeRanges[11].should.eql(2); // nb of triangles + + // testing edge 7 + mesh.edgeRanges[12].should.eql(12); // start in triangle index + mesh.edgeRanges[13].should.eql(2); // nb of triangles + + // testing edge 8 + mesh.edgeRanges[14].should.eql(14); // start in triangle index + mesh.edgeRanges[15].should.eql(2); // nb of triangles + + // testing edge 9 + mesh.edgeRanges[16].should.eql(16); // start in triangle index + mesh.edgeRanges[17].should.eql(2); // nb of triangles + + // testing edge 10 + mesh.edgeRanges[18].should.eql(18); // start in triangle index + mesh.edgeRanges[19].should.eql(2); // nb of triangles + + // testing edge 11 + mesh.edgeRanges[20].should.eql(20); // start in triangle index + mesh.edgeRanges[21].should.eql(2); // nb of triangles + + // testing edge 12 + mesh.edgeRanges[22].should.eql(22); // start in triangle index + mesh.edgeRanges[23].should.eql(2); // nb of triangles + }); + + it("Mesh#getEdgeIndices - mesh should provide a mechanism to extract the Polygon of a given edge", function () { + //xx console.log(mesh); + const arr = mesh.getEdgeIndices(shape.getEdges()[0]); + arr.should.eql(new Uint8Array([0, 1])); + }); + it("Mesh#triangleNormals - mesh should provide ", function () { + // face 0 - triangle 0 + mesh.triangleNormals[0].should.eql(0); + mesh.triangleNormals[1].should.eql(0); + mesh.triangleNormals[2].should.eql(0); + // face 0 - triangle 1 + mesh.triangleNormals[3].should.eql(0); + mesh.triangleNormals[4].should.eql(0); + mesh.triangleNormals[5].should.eql(0); + + // face 1 - triangle 0 + mesh.triangleNormals[6].should.eql(1); + mesh.triangleNormals[7].should.eql(1); + mesh.triangleNormals[8].should.eql(1); + // face 1 - triangle 1 + mesh.triangleNormals[9].should.eql(1); + mesh.triangleNormals[10].should.eql(1); + mesh.triangleNormals[11].should.eql(1); + + // face 2 - triangle 0= + mesh.triangleNormals[12].should.eql(2); + mesh.triangleNormals[13].should.eql(2); + mesh.triangleNormals[14].should.eql(2); + // face 2 - triangle 1 + mesh.triangleNormals[15].should.eql(2); + mesh.triangleNormals[16].should.eql(2); + mesh.triangleNormals[17].should.eql(2); + + // face 3 - triangle 0= + mesh.triangleNormals[18].should.eql(3); + mesh.triangleNormals[19].should.eql(3); + mesh.triangleNormals[20].should.eql(3); + // face 3 - triangle 1 + mesh.triangleNormals[21].should.eql(3); + mesh.triangleNormals[22].should.eql(3); + mesh.triangleNormals[23].should.eql(3); + + // etc... + }); + it("Mesh#normals - mesh should provide a normal array", function () { + // in the case of a simple box we expect to have 6 different normals + mesh.normals.length.should.eql(3 * 6); + + // first normal + mesh.normals[0].should.eql(-1); + mesh.normals[1].should.eql(0); + mesh.normals[2].should.eql(0); + + mesh.normals[3].should.eql(1); + mesh.normals[4].should.eql(0); + mesh.normals[5].should.eql(0); + + mesh.normals[6].should.eql(0); + mesh.normals[7].should.eql(-1); + mesh.normals[8].should.eql(0); + + mesh.normals[9].should.eql(0); + mesh.normals[10].should.eql(1); + mesh.normals[11].should.eql(0); + + mesh.normals[12].should.eql(0); + mesh.normals[13].should.eql(0); + mesh.normals[14].should.eql(-1); + + mesh.normals[15].should.eql(0); + mesh.normals[16].should.eql(0); + mesh.normals[17].should.eql(1); + }); +}); + +describe("testing performance of meshing algorithms with various parameters", function () { + this.timeout(30000); + + function makeUnitBox() { + return occ.makeBox([0, 0, 0], [100, 100, 100]); + } + + function makeSphere() { + return occ.makeSphere([0, 0, 0], 100); + } + + function makeLegoBrick() { + return shapeFactory.makeLegoBrick(occ, 4, 2, "thin"); + } + + function installFor(name: string, makeShape: () => ISolid) { + let shape2: ISolid; + beforeEach(function () { + shape2 = makeShape(); + }); + + function test_with(tol: Real, angle: Real) { + it( + name + + " testing with parameter : deflection : " + + tol + + " angle :" + + angle, + function () { + const mesh1 = shape2.createMesh(tol, angle); + debugLog(" vertices = ", mesh1.vertices.length); + debugLog(" triangles = ", mesh1.triangles.length); + } + ); + } + + test_with(0.01, 0.5); + test_with(0.01, 5); + test_with(0.01, 10); + + test_with(0.1, 0.5); + test_with(0.1, 1); + test_with(0.1, 5); + test_with(0.1, 10); + test_with(0.1, 20); + + test_with(1, 0.5); + test_with(1, 1); + test_with(1, 5); + test_with(1, 10); + test_with(1, 20); + + test_with(2, 0.5); + test_with(2, 1); + test_with(2, 5); + test_with(2, 10); + test_with(2, 20); + + describe(name + " : comparing JSON ", function () { + let shape2: ISolid; + beforeEach(function () { + shape2 = makeUnitBox(); + }); + it("should create default JSON file with acceptable size", function () { + shape2.name = "shape2"; + const obj1 = occ.buildSolidMesh(shape2); + debugLog("json json1", JSON.stringify(obj1, null, "\t")); + debugLog("json json1", JSON.stringify(obj1).length); + }); + it("should create default JSON file with acceptable size", function () { + shape2.name = "shape2"; + const obj2 = occ.buildSolidMeshNew(shape2); + debugLog("json json1", JSON.stringify(obj2, null, "\t")); + debugLog("json json2", JSON.stringify(obj2).length); + }); + }); + } + + installFor("makeLegoBrick", makeLegoBrick); + installFor("makeSphere", makeSphere); +}); diff --git a/test/test_named_faces.ts b/test/test_named_faces.ts new file mode 100644 index 0000000..9a8d1a4 --- /dev/null +++ b/test/test_named_faces.ts @@ -0,0 +1,353 @@ +import * as should from "should"; +import { IBoundingBox, ISolid, occ } from ".."; +import { dumpSolid } from "./debug_tools"; + +// see https://npmjs.org/package/should + +describe("testing face naming on simple box", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([0, 0, 0], [10, 20, 30]); + }); + it("should have only six named faces", () => { + Object.keys(solid.faces).length.should.equal(6); + }); + it("should have a face called 'top'", () => { + solid.faces.should.have.property("top"); + }); + it("should have a face called 'bottom'", () => { + solid.faces.should.have.property("bottom"); + }); + it("should have a face called 'front'", () => { + solid.faces.should.have.property("front"); + }); + it("should have a face called 'back'", () => { + solid.faces.should.have.property("back"); + }); + it("should have a face called 'left'", () => { + solid.faces.should.have.property("left"); + }); + it("should have a face called 'right'", () => { + solid.faces.should.have.property("right"); + }); + it("should provide a service to retrieve the name of its shapes", () => { + solid.getShapeName(solid.faces.top).should.equal("top"); + solid.getShapeName(solid.faces.bottom).should.equal("bottom"); + solid.getShapeName(solid.faces.back).should.equal("back"); + solid.getShapeName(solid.faces.front).should.equal("front"); + solid.getShapeName(solid.faces.left).should.equal("left"); + solid.getShapeName(solid.faces.right).should.equal("right"); + }); + it("should return undefined when shape cannot be found", () => { + const solid2 = occ.makeBox(10, 20, 30); + should.exist(solid.getShapeName(solid.faces.right)); + should.not.exist(solid.getShapeName(solid2.faces.right)); + }); + + it("should have 'top' face planar and at z=30", () => { + solid.faces.top.isPlanar.should.equal(true); + solid.faces.top.centreOfMass.z.should.equal(30); + + solid.faces.top.centreOfMass.x.should.equal(5); + solid.faces.top.centreOfMass.y.should.equal(10); + }); + it("should have 'bottom' face planar and at z=0", () => { + solid.faces.bottom.isPlanar.should.equal(true); + solid.faces.bottom.centreOfMass.z.should.equal(0); + + solid.faces.bottom.centreOfMass.x.should.equal(5); + solid.faces.bottom.centreOfMass.y.should.equal(10); + }); + it("should have 'right' face planar and at y=20", () => { + solid.faces.right.isPlanar.should.equal(true); + solid.faces.right.centreOfMass.y.should.equal(20); + + solid.faces.right.centreOfMass.z.should.equal(15); + solid.faces.right.centreOfMass.x.should.equal(5); + }); + it("should have 'left' face planar and at y=0", () => { + solid.faces.left.isPlanar.should.equal(true); + solid.faces.left.centreOfMass.y.should.equal(0); + + solid.faces.left.centreOfMass.z.should.equal(15); + solid.faces.left.centreOfMass.x.should.equal(5); + }); + it("should have 'front' face planar and at x=10", () => { + solid.faces.front.isPlanar.should.equal(true); + solid.faces.front.centreOfMass.x.should.equal(10); + + solid.faces.front.centreOfMass.y.should.equal(10); + solid.faces.front.centreOfMass.z.should.equal(15); + }); + it("should have 'back' face planar and at x=0", () => { + solid.faces.back.isPlanar.should.equal(true); + solid.faces.back.centreOfMass.x.should.equal(0); + + solid.faces.back.centreOfMass.y.should.equal(10); + solid.faces.back.centreOfMass.z.should.equal(15); + }); + it("should have named edges", () => { + const test = solid.getEdges().map((e) => { + return solid.getShapeName(e); + }); + test + .sort() + .join(" ") + .should.equal("EXY EXZ EXy EXz EYZ EYz ExY ExZ Exy Exz EyZ Eyz"); + }); + + it("should have named vertex", () => { + const test = solid.getVertices().map((e) => { + return solid.getShapeName(e); + }); + test + .sort() + .join(" ") + .should.equal("VXYZ VXYz VXyZ VXyz VxYZ VxYz VxyZ Vxyz"); + }); +}); +describe("testing face naming on simple sphere", () => { + let solid: ISolid; + before(() => { + solid = occ.makeSphere([0, 0, 0], 30); + }); + it("should have only one named face", () => { + Object.keys(solid.faces).length.should.equal(1); + }); + it("should have a face called 'lateral'", () => { + solid.faces.should.have.property("lateral"); + solid.getShapeName(solid.faces.lateral).should.equal("lateral"); + }); + it("should have not have a face called 'top' ", () => { + solid.faces.should.not.have.property("top"); + }); +}); +describe("testing face naming on combined boxes", () => { + let solid: ISolid; + let box1: ISolid; + let box2: ISolid; + before(() => { + box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = occ.makeBox([5, 5, 5], [15, 15, 15]); + solid = occ.fuse(box1, box2); + dumpSolid(solid); + }); + it(" should expose 12 named faces", () => { + Object.keys(solid.faces).length.should.equal(12); + }); + it("should preserve bottom/left/back faces of solid1", () => { + should.exist(solid.getShapeName(box1.faces.bottom)); + should.exist(solid.getShapeName(box1.faces.left)); + should.exist(solid.getShapeName(box1.faces.back)); + }); + it("should replace top/right/front faces of solid1", () => { + should.not.exist(solid.getShapeName(box1.faces.top)); + should.not.exist(solid.getShapeName(box1.faces.right)); + should.not.exist(solid.getShapeName(box1.faces.front)); + }); + it("should replace bottom/left/back faces of solid2", () => { + should.not.exist(solid.getShapeName(box2.faces.bottom)); + should.not.exist(solid.getShapeName(box2.faces.left)); + should.not.exist(solid.getShapeName(box2.faces.back)); + }); + it("should preserve top/right/front faces of solid2", () => { + should.exist(solid.getShapeName(box2.faces.top)); + should.exist(solid.getShapeName(box2.faces.right)); + should.exist(solid.getShapeName(box2.faces.front)); + }); +}); +describe("testing face naming on a box whose top/right/front corner is carved with a other box", () => { + let solid: ISolid; + let box1: ISolid; + let box2: ISolid; + before(() => { + box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = occ.makeBox([5, 5, 5], [15, 15, 15]); + solid = occ.cut(box1, box2); + }); + it(" should expose 9 named faces", () => { + Object.keys(solid.faces).length.should.equal(9); + }); + it("should preserve bottom/left/back faces of original box", () => { + should.exist(solid.getShapeName(box1.faces.bottom)); + should.exist(solid.getShapeName(box1.faces.left)); + should.exist(solid.getShapeName(box1.faces.back)); + }); + it("should replace top/right/front faces of original box", () => { + should.not.exist(solid.getShapeName(box1.faces.top)); + should.not.exist(solid.getShapeName(box1.faces.right)); + should.not.exist(solid.getShapeName(box1.faces.front)); + }); + it("should replace bottom/left/back faces of cutting box", () => { + should.not.exist(solid.getShapeName(box2.faces.bottom)); + should.not.exist(solid.getShapeName(box2.faces.left)); + should.not.exist(solid.getShapeName(box2.faces.back)); + }); + it("should delete top/right/front faces of cutting box", () => { + should.not.exist(solid.getShapeName(box2.faces.top)); + should.not.exist(solid.getShapeName(box2.faces.right)); + should.not.exist(solid.getShapeName(box2.faces.front)); + }); +}); +describe("testing face naming on a box with a split face ('top' face)", () => { + let solid: ISolid; + let block: ISolid; + let cutting_solid: ISolid; + before(() => { + block = occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid = occ.makeBox([40, -10, 10], [60, 110, 50]); + solid = occ.cut(block, cutting_solid); + }); + it(" should expose 10 named faces", () => { + Object.keys(solid.faces).length.should.equal(10); + solid.getFaces().length.should.equal(10); + }); + it("should have a preserved front/bottom/back faces ", () => { + should.exist(solid.getShapeName(block.faces.front)); + should.exist(solid.getShapeName(block.faces.bottom)); + should.exist(solid.getShapeName(block.faces.back)); + }); + it("should have modified right/top/left faces ", () => { + should.not.exist(solid.getShapeName(block.faces.right)); + should.not.exist(solid.getShapeName(block.faces.top)); + should.not.exist(solid.getShapeName(block.faces.left)); + }); +}); +describe("testing face naming on a box fused with a box that have a common face , leading to 4 merging faces", () => { + let box1: ISolid; + let box2: ISolid; + let solid: ISolid; + before(() => { + // +------+ +------+ + // |`. `. |\ \ + // | `+------+ | +------+ + // | | | | | | + // + | | + | | + // `. | | \| | + // `+------+ +------+ + // + box1 = occ.makeBox([0, 0, 0], [10, 10, 10]); + box2 = occ.makeBox([10, 0, 0], [20, 10, 10]); // box2 back face is same as box1.front frace + solid = occ.fuse(box1, box2); + }); + it("should expose 10 faces", () => { + // + // +----++----+ +----++----+ + // | || | | | + // | || | => | | + // +----++----+ +----++----+ + // + // Although the side surface could be merged + // + Object.keys(solid.faces).length.should.equal(10); + solid.getFaces().length.should.equal(10); + occ.gc(); + const faces = solid.getFaces(); + faces.forEach((face, i) => { + const bbox = face.getBoundingBox(); + console.log("face i ", i, solid.getShapeName(face), bbox.toString()); + }); + }); +}); +describe("testing face naming on a box with a top face split twice leading to 4 isolated corners)", () => { + // + // // in this sample, the top face of the block will be split in two pieces + // during the first cut operation.Then each part will be split in two pieces again + // during the second cut operation. + // + let solid: ISolid, + block: ISolid, + cutting_solid1: ISolid, + cutting_solid2: ISolid; + before(() => { + block = occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid1 = occ.makeBox([40, -10, 10], [60, 110, 50]); + cutting_solid2 = occ.makeBox([-10, 40, 10], [110, 60, 50]); + solid = occ.cut(block, cutting_solid1); + solid = occ.cut(solid, cutting_solid2); + }); + it("should expose 22 named faces", () => { + Object.keys(solid.faces).length.should.equal(22); + solid.getFaces().length.should.equal(22); + }); + it("should have a preserved bottom face", () => { + should.exist(solid.getShapeName(block.faces.bottom)); + }); + it("should have modified front/back/right/top/left faces ", () => { + should.not.exist(solid.getShapeName(block.faces.front)); + should.not.exist(solid.getShapeName(block.faces.back)); + should.not.exist(solid.getShapeName(block.faces.right)); + should.not.exist(solid.getShapeName(block.faces.top)); + should.not.exist(solid.getShapeName(block.faces.left)); + }); +}); +describe("testing face naming on a box with a top face split by a cross shape leading to 4 isolated corners", () => { + // + // in this sample, the top face of the block will be split in 4 pieces + // during the single cut operation + // + let solid: ISolid, + block: ISolid, + cutting_solid1: ISolid, + cutting_solid2: ISolid, + cutting_solid: ISolid; + before(() => { + block = occ.makeBox([0, 0, 0], [100, 100, 25]); + cutting_solid1 = occ.makeBox([40, -10, 10], [60, 110, 50]); + cutting_solid2 = occ.makeBox([-10, 40, 10], [110, 60, 50]); + cutting_solid = occ.fuse(cutting_solid1, cutting_solid2); + solid = occ.cut(block, cutting_solid); + }); + it("should expose 22 named faces", () => { + Object.keys(solid.faces).length.should.equal(22); + solid.getFaces().length.should.equal(22); + }); + it("should have a preserved bottom face", () => { + should.exist(solid.getShapeName(block.faces.bottom)); + }); + it("should have modified front/back/right/top/left faces ", () => { + should.not.exist(solid.getShapeName(block.faces.front)); + should.not.exist(solid.getShapeName(block.faces.back)); + should.not.exist(solid.getShapeName(block.faces.right)); + should.not.exist(solid.getShapeName(block.faces.top)); + should.not.exist(solid.getShapeName(block.faces.left)); + + solid.faces.should.have.property("m1:" + "front" + ":0"); + solid.faces.should.have.property("m1:" + "back" + ":0"); + solid.faces.should.have.property("m1:" + "top" + ":0"); + solid.faces.should.have.property("m1:" + "left" + ":0"); + + solid.faces.should.not.have.property("m1:" + "front" + ":1"); + solid.faces.should.not.have.property("m1:" + "back" + ":1"); + solid.faces.should.not.have.property("m1:" + "left" + ":1"); + }); + + it("should have 4 (and only 4) faces that have been generated from the top face of the original block", () => { + // this could be tested using face names + const name = block.getShapeName(block.faces.top); + + solid.faces.should.have.property("m1:" + name + ":0"); + solid.faces.should.have.property("m1:" + name + ":1"); + solid.faces.should.have.property("m1:" + name + ":2"); + solid.faces.should.have.property("m1:" + name + ":3"); + solid.faces.should.not.have.property("m1:" + name + ":4"); + }); +}); + +describe("testing naming with makeFillet operation", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([10, 20, 30], [100, 200, 300]); + dumpSolid(solid); + + const edges = solid.getCommonEdges(solid.faces.front, solid.faces.left)!; + edges.should.be.instanceOf(Array); + + solid = occ.makeFillet(solid, edges[0], 10); + dumpSolid(solid); + }); + it("should have numFaces with expected number of faces", () => { + //xx console.log(Object.keys(solid.faces).join(", ")); + Object.keys(solid.faces).length.should.equal(solid.numFaces); + }); +}); diff --git a/test/test_perf.ts b/test/test_perf.ts new file mode 100644 index 0000000..25e4c0a --- /dev/null +++ b/test/test_perf.ts @@ -0,0 +1,142 @@ +import { occ, IEdge, Triplet, IWire } from ".."; + +describe("testing perf", () => { + it("should make a lof of edges", () => { + const edges: IEdge[] = []; + for (let i = 0; i < points.length - 1; i++) { + const p1 = points[i]; + const p2 = points[i + 1]; + const e = occ.makeLine(p1, p2); + console.log("line ", i, p1, p2, e.constructor.name); + edges.push(e); + } + + const wire = occ.makeWire(...edges); + const face = occ.makeFace(wire); + const solid = occ.makePrism(face, [0, 0, 100]); + }); +}); + +const points: Triplet[] = [ + [46.121693409862004, 9.043749057038903, 0], + [49.75686261847364, 8.63160601315542, 0], + [53.489489059670476, 7.407736505532067, 0], + [57.23424936335196, 5.521838445087539, 0], + [60.9250179786637, 3.023604521015515, 0], + [60.9250179786637, -3.023604521015515, 0], + [57.23424936335196, -5.521838445087539, 0], + [53.489489059670476, -7.407736505532067, 0], + [49.75686261847364, -8.63160601315542, 0], + [46.121693409862004, -9.043749057038903, 0], + [44.46443268701728, -15.228730276083743, 0], + [47.406510046788185, -17.403241226385703, 0], + [50.02712461389047, -20.329456531503098, 0], + [52.327233137739896, -23.835072312636598, 0], + [54.27441555605418, -27.84399066313493, 0], + [51.25081103503866, -33.081027315528765, 0], + [46.80539469265236, -33.39917705071535, 0], + [42.61938810835841, -33.16003252816737, 0], + [38.774904033632765, -32.35362139208792, 0], + [35.42068362997837, -30.892963133778252, 0], + [30.89296313377826, -35.42068362997837, 0], + [32.35362139208794, -38.77490403363276, 0], + [33.16003252816738, -42.6193881083584, 0], + [33.39917705071536, -46.80539469265235, 0], + [33.08102731552877, -51.25081103503866, 0], + [27.843990663134953, -54.274415556054166, 0], + [23.835072312636616, -52.32723313773989, 0], + [20.329456531503116, -50.027124613890464, 0], + [17.40324122638572, -47.40651004678818, 0], + [15.228730276083757, -44.46443268701727, 0], + [9.043749057038903, -46.121693409862004, 0], + [8.631606013155416, -49.75686261847364, 0], + [7.407736505532066, -53.489489059670476, 0], + [5.521838445087538, -57.23424936335196, 0], + [3.0236045210155202, -60.9250179786637, 0], + [-3.023604521015513, -60.9250179786637, 0], + [-5.521838445087531, -57.23424936335196, 0], + [-7.407736505532058, -53.489489059670476, 0], + [-8.63160601315541, -49.75686261847364, 0], + [-9.043749057038896, -46.121693409862004, 0], + [-15.228730276083741, -44.46443268701728, 0], + [-17.403241226385703, -47.406510046788185, 0], + [-20.329456531503098, -50.02712461389048, 0], + [-23.835072312636594, -52.327233137739896, 0], + [-27.84399066313492, -54.27441555605418, 0], + [-33.08102731552875, -51.25081103503866, 0], + [-33.399177050715345, -46.80539469265236, 0], + [-33.16003252816737, -42.61938810835841, 0], + [-32.35362139208793, -38.774904033632765, 0], + [-30.89296313377825, -35.42068362997837, 0], + [-35.420683629978356, -30.892963133778274, 0], + [-38.77490403363274, -32.35362139208795, 0], + [-42.619388108358386, -33.16003252816739, 0], + [-46.805394692652335, -33.39917705071537, 0], + [-51.25081103503865, -33.081027315528786, 0], + [-54.274415556054166, -27.843990663134957, 0], + [-52.32723313773989, -23.83507231263662, 0], + [-50.027124613890464, -20.329456531503116, 0], + [-47.40651004678818, -17.40324122638571, 0], + [-44.46443268701727, -15.228730276083759, 0], + [-46.121693409862, -9.043749057038916, 0], + [-49.75686261847363, -8.63160601315544, 0], + [-53.489489059670476, -7.40773650553208, 0], + [-57.23424936335195, -5.521838445087554, 0], + [-60.9250179786637, -3.023604521015524, 0], + [-60.9250179786637, 3.023604521015509, 0], + [-57.23424936335196, 5.52183844508754, 0], + [-53.489489059670476, 7.407736505532067, 0], + [-49.75686261847364, 8.63160601315543, 0], + [-46.121693409862004, 9.043749057038903, 0], + [-44.46443268701728, 15.228730276083727, 0], + [-47.40651004678819, 17.403241226385678, 0], + [-50.02712461389048, 20.32945653150308, 0], + [-52.3272331377399, 23.83507231263658, 0], + [-54.27441555605419, 27.843990663134917, 0], + [-51.250811035038666, 33.08102731552875, 0], + [-46.80539469265236, 33.399177050715345, 0], + [-42.61938810835841, 33.16003252816736, 0], + [-38.774904033632765, 32.35362139208793, 0], + [-35.42068362997837, 30.89296313377825, 0], + [-30.892963133778274, 35.42068362997835, 0], + [-32.353621392087945, 38.77490403363275, 0], + [-33.1600325281674, 42.619388108358386, 0], + [-33.399177050715394, 46.80539469265232, 0], + [-33.081027315528814, 51.25081103503863, 0], + [-27.843990663134935, 54.27441555605417, 0], + [-23.835072312636594, 52.327233137739896, 0], + [-20.32945653150312, 50.027124613890464, 0], + [-17.403241226385738, 47.40651004678818, 0], + [-15.22873027608376, 44.46443268701727, 0], + [-9.043749057038918, 46.121693409862, 0], + [-8.631606013155423, 49.75686261847364, 0], + [-7.407736505532084, 53.489489059670476, 0], + [-5.521838445087532, 57.23424936335196, 0], + [-3.023604521015555, 60.925017978663696, 0], + [3.0236045210155327, 60.925017978663696, 0], + [5.5218384450875115, 57.23424936335196, 0], + [7.407736505532064, 53.489489059670476, 0], + [8.631606013155405, 49.75686261847364, 0], + [9.043749057038902, 46.121693409862004, 0], + [15.228730276083708, 44.464432687017286, 0], + [17.403241226385674, 47.40651004678819, 0], + [20.32945653150306, 50.027124613890486, 0], + [23.835072312636576, 52.3272331377399, 0], + [27.843990663134868, 54.274415556054215, 0], + [33.08102731552875, 51.250811035038666, 0], + [33.399177050715295, 46.80539469265239, 0], + [33.16003252816734, 42.61938810835843, 0], + [32.353621392087895, 38.77490403363279, 0], + [30.89296313377823, 35.420683629978384, 0], + [35.42068362997835, 30.89296313377828, 0], + [38.77490403363275, 32.353621392087945, 0], + [42.61938810835838, 33.1600325281674, 0], + [46.80539469265232, 33.3991770507154, 0], + [51.25081103503863, 33.081027315528814, 0], + [54.27441555605417, 27.84399066313494, 0], + [52.327233137739896, 23.835072312636598, 0], + [50.027124613890464, 20.329456531503123, 0], + [47.40651004678817, 17.403241226385738, 0], + [44.464432687017265, 15.228730276083764, 0], + [46.121693409862004, 9.043749057038903, 0] +]; diff --git a/test/test_relativePerformanceBREPSTEP.ts b/test/test_relativePerformanceBREPSTEP.ts new file mode 100644 index 0000000..06da6c3 --- /dev/null +++ b/test/test_relativePerformanceBREPSTEP.ts @@ -0,0 +1,109 @@ +import path from "path"; +import fs from "fs"; +import "should"; +import { promisify } from "util"; +import { ISolid, Shape, occ } from ".."; +import { removeFile, getTemporaryFilePath } from "./helpers"; + +const ProgressBar = require("progress"); + +async function myReadStep(filename: string): Promise { + let brepFilename = getTemporaryFilePath({ suffix: ".brep" }); + + console.log("brepFilename", brepFilename); + + let bar = new ProgressBar( + "reading file [:bar] :percent elapsed :elapseds ETA :etas", + { + complete: "=", + incomplete: "-", + width: 100, + total: 1000 + } + ); + + let solids: ISolid[] = []; + + function progressFunc(percent: number) { + bar.tick(percent); + } + + function performMesh(solids: ISolid[]) { + let bar = new ProgressBar( + "meshing solids [:bar] :percent elapsed :elapseds ETA :etas", + { + complete: "=", + incomplete: "-", + width: 100, + total: solids.length + } + ); + for (let i in solids) { + bar.tick(); + let solid = solids[i]; + solid.numFaces.should.be.greaterThan(1); + + solid.name = "solid_" + i; + try { + occ.buildSolidMesh(solid); + let mesh = solid.mesh; + solid.mesh.numVertices.should.be.greaterThan(3); + } catch (err) {} + } + console.log("\n"); + } + + function chrono( + async_func: (callback: (err?: Error | null) => void) => void, + message: string, + callback: (err?: Error | null) => void + ) { + let t1: Date; + let t2: Date; + let elapsed: number; + t1 = new Date(); + + async_func((err?: Error | null) => { + t2 = new Date(); + elapsed = Math.round((t2.getTime() - t1.getTime()) / 10) / 100; + + console.log("\ndone " + message + " in ", elapsed, " seconds"); + callback(err); + }); + } + + async function read_original_step_file(): Promise { + let t1 = new Date(); + return await promisify(occ.readSTEP)(filename); + } + + async function perform_mesh_on_solids() { + // make sure we have a mesh, so it can be saved in the BREP file + performMesh(solids); + } + + async function write_solids_to_brep() { + occ.writeBREP(brepFilename, solids); + } + + async function read_brep_file_again() { + return await promisify(occ.readSTEP)(filename); + } + + await read_original_step_file(); + await perform_mesh_on_solids(); + await write_solids_to_brep(); + await read_brep_file_again(); + await perform_mesh_on_solids(); + removeFile(brepFilename); +} + +// myReadStep("test/kuka.stp"); +describe("testing relative performance of BREP and STEP I/O", function () { + this.timeout(40000); + it("should read kuka robot", async () => { + let filename = path.join(__dirname, "kuka.stp"); + fs.existsSync(filename).should.eql(true, "kuka.stp should exists"); + await myReadStep(filename); + }); +}); diff --git a/test/test_scriptrunner.js b/test/test_scriptrunner.js deleted file mode 100644 index 93d7f85..0000000 --- a/test/test_scriptrunner.js +++ /dev/null @@ -1,58 +0,0 @@ -const should = require("should"); -const sr = require("../lib/scriptrunner"); -describe("Script Runner", function () { - let runner; - let myEnv = {foo: "bar"}; - - before(function () { - runner = new sr.ScriptRunner(myEnv); - }); - - it("should not be possible load external module with require", function (done) { - - runner.run("let fs= require('fs');", function () { - should.fail("done callback"); - done(new Error("test has failed: 'require' call hasn't been intercepted")); - }, function error_callback(err) { - should.exist(err); - err.message.should.equal("require is forbidden"); - done(null); // - }); - }); - it("should not be possible to use eval", function (done) { - - runner.run("eval('a=10');", - - function () { - should.fail("done callback"); - done(new Error("test has failed: 'eval' call hasn't been intercepted")); - }, - function error_callback(err) { - should.exist(err); - err.message.should.equal("eval is forbidden"); - done(null); // - } - ); - - }); - it("should expose environment provided by the caller", function (done) { - - runner.env.logs = []; // purge log - runner.env.logs.length.should.equal(0); - runner.env.foo.should.equal("bar"); - runner.run("console.log(foo); foo='baz'", - - function () { - - runner.env.foo.should.equal("baz"); - runner.env.logs.length.should.equal(1); - - done(); - }, - function error_callback(err) { - done(err); // should not fail - } - ); - - }); -}); diff --git a/test/test_scriptrunner.ts b/test/test_scriptrunner.ts new file mode 100644 index 0000000..be61444 --- /dev/null +++ b/test/test_scriptrunner.ts @@ -0,0 +1,61 @@ +import should from "should"; +import { ScriptRunner } from ".."; + +describe("Script Runner", function () { + let scriptRunner: ScriptRunner; + let myEnv = { foo: "bar" }; + + before(() => { + scriptRunner = new ScriptRunner(myEnv); + }); + + it("SR1 - should not be possible load external module with require", function (done) { + scriptRunner.run( + "let fs= require('fs');", + () => { + should.fail(false, "done callback"); + done( + new Error("test has failed: 'require' call hasn't been intercepted") + ); + }, + (err: Error) => { + should.exist(err); + err.message.should.equal("require is forbidden"); + done(null); // + } + ); + }); + it("should not be possible to use eval", function (done) { + scriptRunner.run( + "eval('a=10');", + + function () { + should.fail(false, "done callback"); + done(new Error("test has failed: 'eval' call hasn't been intercepted")); + }, + function error_callback(err: Error) { + should.exist(err); + err.message.should.equal("eval is forbidden"); + done(null); // + } + ); + }); + it("should expose environment provided by the caller", function (done) { + scriptRunner.env.logs = []; // purge log + scriptRunner.env.logs.length.should.equal(0); + scriptRunner.env.foo.should.equal("bar"); + scriptRunner.run( + "console.log(foo); foo='baz'", + + function () { + scriptRunner.env.foo.should.equal("baz"); + scriptRunner.env.logs.length.should.equal(1); + + done(); + }, + function error_callback(err: Error) { + done(err); // should not fail + } + ); + }); +}); diff --git a/test/test_solid.ts b/test/test_solid.ts new file mode 100644 index 0000000..b3c8011 --- /dev/null +++ b/test/test_solid.ts @@ -0,0 +1,777 @@ +import should from "should"; + +import { + EdgeIterator, + FaceIterator, + IBoundingBox, + IEdge, + IFace, + IShapeIterator, + ISolid, + Solid, + Triplet, + occ +} from ".."; + +const DEG2RAD = Math.PI / 180; + +// see https://npmjs.org/package/should + +describe("testing solid construction", () => { + describe("empty solid", () => { + let solid: ISolid; + before(() => { + solid = new Solid(); + }); + it("should have no faces", () => { + solid.numFaces.should.equal(0); + Object.keys(solid.faces).length.should.equal(0); + }); + it("should have no solid", () => { + solid.numSolids.should.equal(0); + }); + it("should have no shell", () => { + solid.numShells.should.equal(0); + }); + it("should have no outerShell", () => { + should.not.exist(solid.outerShell); + }); + }); + describe("makeBox with 2 points", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + }); + it("should be a SOLID", () => { + solid.shapeType.should.equal("SOLID"); + }); + it("should have 1 solid", () => { + solid.numSolids.should.equal(1); + }); + it("should have 1 shell", () => { + solid.numShells.should.equal(1); + }); + it("should have 6 faces", () => { + solid.numFaces.should.equal(6); + Object.keys(solid.faces).length.should.equal(6); + }); + it("should have an outerShell with 6 faces", () => { + should.exist(solid.getOuterShell()); + solid.getOuterShell().numFaces.should.equal(6); + // Object.keys(solid.getOuterShell().faces).length.should.equal(6); + }); + it("should have an outerShell with a forward orientation", () => { + solid.getOuterShell().orientation.should.equal("FORWARD"); + }); + it("should have (20-10)*(40-20)*(60-30) as a volume", () => { + solid.volume.should.equal((20 - 10) * (40 - 20) * (60 - 30)); + }); + + it("should have ~ 2*((20-10)*(40-20)+(20-10)*(60-30)+(40-20)*(60-30)) as a area", () => { + let expectedArea = + 2 * + ((20 - 10) * (40 - 20) + (20 - 10) * (60 - 30) + (40 - 20) * (60 - 30)); + let eps = 0.001; + solid.area.should.be.within(expectedArea - eps, expectedArea + eps); + }); + + it("should have the sum(face area) === area of solid ", () => { + let epsilon = 1e-3; + + let shapeIt = new FaceIterator(solid); + let cumulated_face_area = 0; + while (shapeIt.more) { + cumulated_face_area += shapeIt.next().area; + } + let expectedArea = solid.area; + cumulated_face_area.should.be.within( + expectedArea - epsilon, + expectedArea + epsilon + ); + }); + }); + describe("makeBox with invalid arguments", () => { + it("should raise an exception when invalid arguments are passed to makeBox", () => { + (function failing_func() { + let solid = (occ.makeBox as any)([10, 20, 30], 10, 10, 10); + }).should.throwError(); + }); + }); + describe("fuse 2 overlapping boxes", () => { + let solid1: ISolid; + let solid2: ISolid; + before(() => { + solid1 = occ.makeBox([10, 20, 30], [20, 40, 60]); + solid2 = occ.makeBox([15, 25, 35], [-20, -40, -60]); + solid1 = occ.fuse(solid1, solid2); + }); + it("should be a SOLID", () => { + solid1.shapeType.should.equal("SOLID"); + }); + it("should have 1 solid", () => { + solid1.numSolids.should.equal(1); + }); + it("should have 1 shell", () => { + solid1.numShells.should.equal(1); + }); + it("should have 12 faces", () => { + solid1.numFaces.should.equal(12); + Object.keys(solid1.faces).length.should.equal(12); + }); + it("should have an outerShell with 12 faces", () => { + should.exist(solid1.getOuterShell()); + solid1.getOuterShell().numFaces.should.equal(12); + }); + }); + describe("cut a corner of a box", () => { + let solid1: ISolid; + let solid2: ISolid; + before(() => { + // + // +------+ + // +-----|`. `. +------+ + // |`. + `+-----`+ |`+--+ `. + // | `+--` | | | | |`+--`+ + // | | + | | => | +--+ | | + // + | ` +------+ + `+-`+ | + // `. | | `. | | + // `+------+ `+------+ + solid1 = occ.makeBox([10, 20, 30], [20, 40, 60]); + solid2 = occ.makeBox([15, 25, 35], [-20, -40, -60]); + solid1 = occ.cut(solid1, solid2); + }); + it("should be a SOLID", () => { + solid1.shapeType.should.equal("SOLID"); + }); + it("should have 9 faces", () => { + solid1.numFaces.should.equal(9); + Object.keys(solid1.faces).length.should.equal(9); + }); + it("should have 1 solid", () => { + solid1.numSolids.should.equal(1); + }); + it("should have 1 shell", () => { + solid1.numShells.should.equal(1); + }); + }); + describe("Hollow box ( 1 solid with 2 shells )", () => { + let solid1: ISolid; + let solid2: ISolid; + before(() => { + solid1 = occ.makeBox([0, 0, 0], [20, 20, 20]); + solid2 = occ.makeBox([10, 10, 10], [15, 15, 15]); + + solid1 = occ.cut(solid1, solid2); + }); + it("should be a SOLID", () => { + solid1.shapeType.should.equal("SOLID"); + }); + it("should have 12 faces", () => { + solid1.numFaces.should.equal(12); + Object.keys(solid1.faces).length.should.equal(12); + }); + it("should have 1 solid", () => { + solid1.numSolids.should.equal(1); + }); + it("should have 2 shells", () => { + solid1.numShells.should.equal(2); + }); + it("should have an outer shell with 6 faces", () => { + let outerShell = solid1.getOuterShell(); + outerShell.numFaces.should.equal(6); + }); + it("should have an outer shell with 6 faces", () => { + let outerShell = solid1.getOuterShell(); + outerShell.orientation.should.equal("FORWARD"); + }); + it("should expose 2 shells (getOuterShell)", () => { + let shells = solid1.getShells(); + + let outerShell = solid1.getOuterShell(); + should.exist(outerShell); + + shells.length.should.equal(2); + for (let i in shells) { + let shell = shells[i]; + if (outerShell.hashCode !== shell.hashCode) { + shell.orientation.should.equal("FORWARD"); + } + } + }); + }); + describe("split boxes", () => { + let solid1: ISolid; + let solid2: ISolid; + let splitBoxes: ISolid; + before(() => { + // cutting a square box in 2 boxes + solid1 = occ.makeBox([0, 0, 0], [20, 20, 20]); + solid2 = occ.makeBox([-100, -100, 10], [100, 100, 15]); + + splitBoxes = occ.cut(solid1, solid2); + }); + it("should be a COMPOUND", () => { + splitBoxes.shapeType.should.equal("COMPOUND"); + }); + it("should have 12 faces", () => { + //console.log( splitBoxes.faces); + splitBoxes.numFaces.should.equal(12); + Object.keys(splitBoxes.faces).length.should.equal(12); + }); + it("should have 2 solids", () => { + splitBoxes.numSolids.should.equal(2); + }); + it("should have 2 shells", () => { + splitBoxes.numShells.should.equal(2); + }); + it("should have an outer shell with 6 faces", () => { + let solids = splitBoxes.getSolids(); + + let outerShell1 = solids[0].getOuterShell(); + outerShell1.numFaces.should.equal(6); + + let outerShell2 = solids[1].getOuterShell(); + outerShell2.numFaces.should.equal(6); + }); + }); + + describe("creating a compound", () => { + let compound: ISolid; + before(() => { + let solids: ISolid[] = []; + let solid1 = occ.makeBox(10, 20, 30); + for (let i = 0; i < 10; i++) { + let s = solid1.rotate([0, 0, 0], [0, 0, 1], i * 15); + s.numFaces.should.equal(6); + solids.push(s); + } + compound = occ.compound(solids); + }); + + it("should be a compound", () => { + compound.shapeType.should.equal("COMPOUND"); + }); + it("should have 10 solids", () => { + console.log(compound); + compound.numSolids.should.equal(10); + }); + }); + + describe("Meshing a simple solid", () => { + describe("Meshing a box", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([10, 20, 30], [20, 30, 40]); + }); + it("should have a mesh with 8 vertices", () => { + solid.mesh.numVertices.should.equal(8); + }); + it("should have a mesh with 4+4+4=12 edges", () => { + solid.mesh.numEdges.should.equal(12); + }); + it("should have a mesh with 2*6 triangles", () => { + solid.mesh.numTriangles.should.equal(12); + }); + }); + }); + describe("Testing Shape __prototype", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([10, 20, 30], [20, 30, 40]); + }); + it("should expose the expected properties ", () => { + let expected = ["shapeType", "numFaces", "isNull", "isValid"]; + let actual: string[] = []; + for (let j in Solid.prototype) { + actual.push(j.toString()); + } + let missing: string[] = []; + for (const e of expected) { + if (actual.indexOf(e) == -1) { + missing.push(e); + } + } + missing.should.have.lengthOf(0); + }); + }); + describe("exporting a solid to STEP ", () => { + let step_filename1 = "toto1.step"; + let step_filename2 = "toto2.step"; + let solid1: ISolid, solid2: ISolid; + before(() => { + solid1 = occ.makeBox([10, 20, 30], [20, 30, 40]); + solid1 = occ.makeBox([20, 30, 50], [110, 40, 0]); + }); + it("should export a single solid to STEP", () => { + occ.writeSTEP(step_filename1, solid1); + }); + it("should export many solids to STEP", () => { + occ.writeSTEP(step_filename2, solid1, solid2); + }); + }); + describe("testing ShapeIterator on solid", () => { + let solid: ISolid; + let shapeIt: + | IShapeIterator + | IShapeIterator + | IShapeIterator; + before(() => { + solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + }); + it("should iterate on 6 faces", () => { + shapeIt = new FaceIterator(solid); + shapeIt.more.should.be.equal(true); + should.not.exist(shapeIt.current); + let counter = 0; + while (shapeIt.more) { + shapeIt.more.should.be.equal(true); + shapeIt.next(); + should.exists(shapeIt.current); + counter += 1; + } + counter.should.equal(6); + shapeIt.more.should.be.equal(false); + should.exists(shapeIt.current); + }); + it("should iterate on 24 edges ( 4 on each of the 6 faces", () => { + shapeIt = new EdgeIterator(solid); + shapeIt.more.should.be.equal(true); + should.not.exist(shapeIt.current); + let counter = 0; + while (shapeIt.more) { + shapeIt.more.should.be.equal(true); + shapeIt.next(); + should.exists(shapeIt.current); + counter += 1; + } + counter.should.equal(24); + shapeIt.more.should.be.equal(false); + should.exists(shapeIt.current); + }); + }); + describe("testing fillet on a box..", () => { + let solid: ISolid; + + before(() => { + solid = occ.makeBox([10, 20, 30], [30, 40, 50]); + solid.numFaces.should.equal(6); + + solid = occ.makeFillet(solid, solid.getEdges(), 2.0); + }); + it("should be possible to round the corner...", () => { + // 6 flat surfaces -> 6*4 edges + // + 12 rounded corners -> shared + // + 8 corners -> 8*3 edges + //==> 26 faces + solid.numFaces.should.be.equal(26); + solid.getEdges().length.should.be.equal(6 * 4 + 8 * 3); + }); + }); + describe("makeCylinder (variation 1)", () => { + let solid: ISolid; + before(() => { + let radius = 50; + let height = 100; + solid = occ.makeCylinder(radius, height); + }); + it("should have 3 faces", () => { + solid.numFaces.should.equal(3); + }); + }); + + describe("makeCylinder (variation 2)", () => { + let solid: ISolid; + before(() => { + let position: [Triplet, Triplet] = [ + [0, 0, 1], + [0, 1, 0] + ]; + let radius = 50; + let height = 100; + solid = occ.makeCylinder(position, radius, height); + }); + it("should have 3 faces", () => { + solid.numFaces.should.equal(3); + }); + }); + describe("makeCylinder (variation 3 : with 2 points and a radius)", () => { + let solid: ISolid; + let bbox: IBoundingBox; + before(() => { + let startPoint: Triplet = [-100, 20, 40]; + let endPoint: Triplet = [100, 20, 40]; + let radius = 20; + solid = occ.makeCylinder(startPoint, endPoint, radius); + bbox = solid.getBoundingBox(); + }); + it("should have 3 faces", () => { + solid.numFaces.should.equal(3); + }); + it("should have a bounding box that includes X=-100,20,40", () => { + bbox.nearPt.y.should.be.within(-2, 0); + bbox.farPt.y.should.be.within(40, 42); + + bbox.nearPt.x.should.be.within(-101, -100); + bbox.farPt.x.should.be.within(100, 101); + }); + }); + describe("makeCone - variation 1", () => { + let solid: ISolid; + before(() => { + let radius1 = 50; + let radius2 = 70; + let height = 30; + solid = occ.makeCone(radius1, radius2, height); + }); + it("should have 3 faces", () => { + solid.numFaces.should.equal(3); + }); + }); + describe("makeCone - variation 2 ( point,R1, point, R2 )", () => { + let solid: ISolid; + let radius1 = 50; + let radius2 = 70; + before(() => { + let height = 30; + solid = occ.makeCone([0, 0, 0], radius1, [0, 0, height], radius2); + }); + it("should have 3 faces", () => { + solid.numFaces.should.equal(3); + should.exist(solid.faces.top); + should.exist(solid.faces.lateral); + should.exist(solid.faces.bottom); + }); + it("top face should have a area of radius**2*pi", () => { + let expectedArea = radius2 * radius2 * Math.PI; + let eps = 1.0; + solid.faces.top.area.should.be.within( + expectedArea - eps, + expectedArea + eps + ); + }); + it("bottom face should have a area of radius**2*pi", () => { + let expectedArea = radius1 * radius1 * Math.PI; + let eps = 1.0; + solid.faces.bottom.area.should.be.within( + expectedArea - eps, + expectedArea + eps + ); + }); + }); + describe("makeCone - variation 3 ( axpex,dir, half_angle, height )", () => { + let solid: ISolid; + let radius = 50; + let height = 30; + before(() => { + let angle = Math.atan(radius / height); + solid = occ.makeCone([0, 0, 0], [0, 0, 1], angle, height); + }); + it("should have 2 faces", () => { + solid.numFaces.should.equal(2); + should.exist(solid.faces.top); + should.exist(solid.faces.lateral); + should.not.exist(solid.faces.bottom); + }); + it("top face should have a area of radius**2*pi", () => { + let expectedArea = radius * radius * Math.PI; + let eps = 1.0; + solid.faces.top.area.should.be.within( + expectedArea - eps, + expectedArea + eps + ); + }); + }); + + describe("makeSphere", () => { + let solid: ISolid; + let radius = 10; + let epsilon = radius * 1e-1; + before(() => { + let center: Triplet = [10, 20, 30]; + solid = occ.makeSphere(center, radius); + }); + it("should have 1 face and one egde", () => { + solid.numFaces.should.equal(1); + solid.getEdges().length.should.equal(1); + let edges = solid.getEdges(); + for (let edge in edges) { + // todo : do some investigation + } + }); + it("should have a area of 4*Pi*R", () => { + let expected_area = 4 * 3.14159265 * radius * radius; + solid.area.should.be.within( + expected_area - epsilon, + expected_area + epsilon + ); + }); + it("should have a volume of 4/3*Pi*R*2", () => { + let expected_volume = (4.0 / 3.0) * 3.14159265 * radius * radius * radius; + solid.volume.should.be.within( + expected_volume - epsilon, + expected_volume + epsilon + ); + }); + }); + describe("makeTorus", () => { + let solid: ISolid; + before(() => { + solid = occ.makeTorus([0, 0, 0], [0, 0, 1], 100, 10); + }); + it("should have one single face", () => { + //console.log(solid.faces); + solid.numFaces.should.equal(1); + should.exist(solid.faces.lateral); + }); + }); + describe("makeTorus with invalid arguments", () => { + it("should not crash if torus is created with invalid arguments", () => { + should(() => { + const solid = occ.makeTorus([0, 0, 0], [0, 0, 0], 10, 100); + }).throwError(); + }); + }); + describe("makeCylinder with invalid arguments", () => { + it("should not crash if Cylinder is created with invalid arguments", () => { + should(() => { + const solid = occ.makeCylinder([0, 0, 0], [0, 0, 0], 10); + }).throwError(); + }); + }); + + describe("makeCone with invalid arguments", () => { + it("should not crash if Cone is created with invalid arguments", () => { + should(() => { + const solid = (occ.makeCone as any)([0, 0, 0], [0, 0, 0], 10); + }).throwError(); + + should(() => { + const solid = (occ.makeCone as any)([0, 0, 0], [0, 0, 0], 0); + }).throwError(); + }); + }); + + describe("rotate apply on a solid", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([10, 10, 0], [20, 20, 10]); + }); + it("should expose a rotated box", () => { + let epsilon = 0.1; + let bbox = solid.getBoundingBox(); + bbox.farPt.x.should.be.lessThan(20.0 + epsilon); + bbox.farPt.y.should.be.lessThan(20.0 + epsilon); + bbox.nearPt.x.should.be.greaterThan(10.0 - epsilon); + bbox.nearPt.y.should.be.greaterThan(10.0 - epsilon); + + solid = solid.rotate([0, 0, 0], [0, 0, 1], 90); + + bbox = solid.getBoundingBox(); + bbox.farPt.x.should.be.within(-10.0 - epsilon, -10 + epsilon); + bbox.farPt.y.should.be.within(20.0 - epsilon, 20 + epsilon); + bbox.nearPt.x.should.be.within(-20.0 - epsilon, -20 + epsilon); + bbox.nearPt.y.should.be.within(10.0 - epsilon, 10 + epsilon); + }); + }); + describe(" making a illegal solid ( with bad arguments) shall raise exception", () => { + it("should raise exception when trying to build a box with illegal arguments", () => { + (() => { + let solid = (occ.makeBox as any)("illegal"); + }).should.throwError(); + }); + }); + describe("test adjacent faces", () => { + let solid: ISolid; + before(() => { + solid = occ.makeBox([0, 0, 0], [100, 100, 100]); + }); + it("should have back/front/left/right faces adjacent to face 'top'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.top); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("back/front/left/right"); + }); + it("should have back/front/left/right faces adjacent to face 'bottom'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.bottom); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("back/front/left/right"); + }); + + it("should have bottom/left/right/top faces adjacent to face 'back'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.back); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("bottom/left/right/top"); + }); + + it("should have bottom/left/right/top faces adjacent to face 'front'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.front); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("bottom/left/right/top"); + }); + it("should have back/bottom/front/top faces adjacent to face 'left'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.left); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("back/bottom/front/top"); + }); + + it("should have back/bottom/front/top faces adjacent to face 'right'", () => { + let adjFaces = solid.getAdjacentFaces(solid.faces.right); + + adjFaces.length.should.equal(4); + + let names = adjFaces + .map(function (f) { + return solid.getShapeName(f); + }) + .sort(); + + names.join("/").should.equal("back/bottom/front/top"); + }); + }); + + describe("makeThickSolid (external ) on box", () => { + let initialBox: ISolid; + let thickSolid: ISolid; + before(() => { + initialBox = occ.makeBox(100, 200, 300); + thickSolid = occ.makeThickSolid(initialBox, initialBox.faces.top, 10); + }); + it("should have 23 (6 + 4 vertical faces + 4 vertical fillets + 1 horizontal face + 4 horizontal fillets + 4 rounded corners) faces", () => { + console.log( + Object.keys( + thickSolid.getFaces().map(function (el) { + return thickSolid.getShapeName(el); + }) + ).join(" ") + ); + //xx console.log( Object.keys(thickSolid.faces).join(" ")); + initialBox.numFaces.should.equal(6); + thickSolid.numFaces.should.equal(23); + }); + }); + describe("makeThickSolid (internal) on box", () => { + let initialBox: ISolid; + let thickSolid: ISolid; + before(() => { + initialBox = occ.makeBox(100, 200, 300); + thickSolid = occ.makeThickSolid(initialBox, initialBox.faces.top, -10); + }); + it("should have 1 (1 top face modified + 5 old + 5 new) faces", () => { + console.log( + Object.keys( + thickSolid.getFaces().map(function (el) { + return thickSolid.getShapeName(el); + }) + ).join(" ") + ); + //xx console.log( Object.keys(thickSolid.faces).join(" ")); + initialBox.numFaces.should.equal(6); + thickSolid.numFaces.should.equal(11); + }); + }); + describe("finding common edge of 2 faces", () => { + let box: ISolid; + before(() => { + box = occ.makeBox(100, 200, 300); + }); + it("should find a common edge between 'top' face and 'left' face", () => { + let edges = box.getCommonEdges(box.faces.top, box.faces.left); + edges.length.should.be.equal(1); + }); + it("should not find a common edge between 'top' face and 'bottom' face", () => { + let edges = box.getCommonEdges(box.faces.top, box.faces.bottom); + edges.length.should.be.equal(0); + }); + }); + describe("makeDraftAngle", () => { + let box: ISolid; + let boxWithDraftFace: ISolid; + before(() => { + box = occ.makeBox(100, 200, 300); + boxWithDraftFace = occ.makeDraftAngle( + box, + box.faces.right, + 20 * DEG2RAD, + box.faces.bottom + ); + }); + it("should have 6 faces", () => { + boxWithDraftFace.numFaces.should.equal(6); + }); + it("should have a smaller volume", () => { + boxWithDraftFace.volume.should.be.lessThan(box.volume); + }); + }); + + describe("makeDraftAngle on a box with a rounded corner", () => { + let box: ISolid; + let boxWithDraftFace: ISolid; + before(() => { + box = occ.makeBox(100, 200, 300); + let edges = box.getCommonEdges(box.faces.left, box.faces.front)[0]; + // console.log("edge = ",edges); + box = occ.makeFillet(box, edges, 10); + + // note: left , front , top and bottom faces have been modified by the fillet + // operation.; + + let faceToDraft = box.faces["mleft:0"]; + let neutralFace = box.faces["mbottom:0"]; + + console.log(Object.keys(box.faces).join(" ")); + should.exist(faceToDraft); + should.exist(neutralFace); + boxWithDraftFace = occ.makeDraftAngle( + box, + faceToDraft, + 5 * DEG2RAD, + neutralFace + ); + }); + it("should have 7 faces", () => { + boxWithDraftFace.numFaces.should.equal(7); + }); + it("should have a smaller volume", () => { + boxWithDraftFace.volume.should.be.lessThan(box.volume); + }); + }); +}); diff --git a/test/test_thruSections.ts b/test/test_thruSections.ts new file mode 100644 index 0000000..7326756 --- /dev/null +++ b/test/test_thruSections.ts @@ -0,0 +1,58 @@ +import should from "should"; +import { IEdge, IWire, Triplet, Vertex, occ } from ".."; +import { getTemporaryFilePath } from "./helpers"; + +describe("through_sections", function () { + it("should create a solid through a set of section", () => { + const circle_1 = occ.makeCircle([-100, 0, -100], [0, 0, 1], 40); + + const circle_2 = occ.makeCircle([-10, 0, -0], [0, 0, 1], 40); + + const circle_3 = occ.makeCircle([-75, 0, 100], [0, 0, 1], 40); + const circle_4 = occ.makeCircle([0, 0, 200], [0, 0, 1], 40); + + const solid = occ.makeSolidThruSections([ + circle_1, + circle_2, + circle_3, + circle_4 + ]); + + const filename = getTemporaryFilePath({ prefix: "b1_", suffix: ".step" }); + console.log("file =>", filename); + occ.writeSTEP(filename, solid); + }); + + it("should create a solid through a set of section", () => { + const DEG2RAD = Math.atan(1) / 45; + const r = (rho: number, theta: number): Triplet => { + const c = Math.cos(theta * DEG2RAD); + const s = Math.sin(theta * DEG2RAD); + return [rho * c, rho * s, 0]; + }; + + const p: Triplet[] = []; + p.push([0, 0, 0]); + p.push(r(50, 10)); + p.push(r(50, 8)); + p.push(r(60, 4)); + p.push(r(60, 0)); + p.push([0, 0, 0]); + + const segments: (IEdge | IWire)[] = []; + for (let i = 0; i < p.length - 1; i++) { + segments.push(occ.makeLine(p[i], p[i + 1])); + } + + const wire = occ.makeWire(segments); + const wire1 = wire.translate([0, 0, 10]).rotate([0, 0, 0], [0, 0, 1], 6); + const wire2 = wire.translate([0, 0, 20]).rotate([0, 0, 0], [0, 0, 1], 12); + const wire3 = wire.translate([0, 0, 30]).rotate([0, 0, 0], [0, 0, 1], 18); + + const solid = occ.makeSolidThruSections([wire, wire1, wire2, wire3]); + + const filename = getTemporaryFilePath({ prefix: "b1_", suffix: ".step" }); + console.log("file =>", filename); + occ.writeSTEP(filename, solid); + }); +}); diff --git a/test/test_transform.ts b/test/test_transform.ts new file mode 100644 index 0000000..c44a8b9 --- /dev/null +++ b/test/test_transform.ts @@ -0,0 +1,56 @@ +import should from "should"; +import { ITransform, occ, Transformation, ZDir } from ".."; + +describe("testing transformation object", function () { + let trsf: ITransform; + before(function () { + trsf = new Transformation(); + should.exist(trsf); + }); + describe("a empty transformation", function () { + it("should have a scale factor of 1.0", function () { + trsf.scaleFactor.should.equal(1.0); + }); + it("should have a rotation axis of 0,0,1", function () { + trsf.scaleFactor.should.equal(1.0); + }); + }); + + describe("testing translation [10,20,30]", function () { + before(function () { + trsf.makeTranslation([10, 20, 30]); + }); + it("should have a scale factor of 1.0", function () { + trsf.scaleFactor.should.equal(1.0); + }); + /* + it("should have a rotation axis of 0,0,1", function() { + trsf.rotationAxis.i.should.equal(0.0); + trsf.rotationAxis.j.should.equal(0.0); + trsf.rotationAxis.k.should.equal(1.0); + }); + it("should have a translationPart at [10,20,30]", function() { + trsf.translationPart.x.should.equal(10.0); + trsf.translationPart.y.should.equal(20.0); + trsf.translationPart.z.should.equal(30.0); + }); + */ + }); + describe("testing planeMirror o=[10,20,30] dir=[0,0,1", function () { + before(function () { + ZDir.should.eql([0, 0, 1]); + + trsf.makePlaneMirror([10, 20, 30], ZDir); + }); + + it("should have a scale factor of -1.0", function () { + trsf.scaleFactor.should.eql(-1); + }); + + it("should flip coord on the Z axis", function () { + let v = occ.makeVertex(10, 10, 40); + let v2 = v.transformed(trsf); + v2.x.should.eql(v.x); + }); + }); +}); diff --git a/test/test_vertex.ts b/test/test_vertex.ts new file mode 100644 index 0000000..eaa83fc --- /dev/null +++ b/test/test_vertex.ts @@ -0,0 +1,165 @@ +import should from "should"; +import { IVertex, occ } from ".."; +import { Vertex, Edge, Wire, Solid, BoundingBox, makeVertex } from ".."; +const doDebug = false; + +describe("testing Vertex ", function () { + describe("constructing a empty vertex ", function () { + let vertex: IVertex; + before(function () { + vertex = occ.makeVertex(); + }); + it("should be (0,0,0)", function () { + vertex.x.should.equal(0); + vertex.y.should.equal(0); + vertex.z.should.equal(0); + }); + }); + describe("constructing a vertex with a {x:..., y..,z: ...}", function () { + let vertex: IVertex; + before(function () { + vertex = occ.makeVertex({ x: 10, y: 20, z: 30 }); + }); + it("should be (10,20,30)", function () { + vertex.x.should.equal(10); + vertex.y.should.equal(20); + vertex.z.should.equal(30); + }); + }); + describe("constructing a vertex with {x:..., y..,z: ...} (property in random order)", function () { + let vertex: IVertex; + before(function () { + vertex = occ.makeVertex({ a: 10, y: 20, z: 30, x: 10 } as any); + }); + it("should be (10,20,30)", function () { + vertex.x.should.equal(10); + vertex.y.should.equal(20); + vertex.z.should.equal(30); + }); + }); + + describe("constructing a vertex build by passing x,y,z coordinates to constructor", function () { + let vertex: IVertex; + before(function () { + vertex = occ.makeVertex(10, 20, 30); + }); + it("should be (10,20,30)", function () { + vertex.x.should.equal(10); + vertex.y.should.equal(20); + vertex.z.should.equal(30); + }); + }); + describe("constructing a vertex build by passing [x,y,z] coordinates to constructor", function () { + let vertex: IVertex; + before(function () { + vertex = occ.makeVertex([10, 20, 30]); + }); + it("should be (10,20,30)", function () { + vertex.x.should.equal(10); + vertex.y.should.equal(20); + vertex.z.should.equal(30); + }); + it("should be valid", function () { + vertex.isValid.should.equal(true); + }); + }); + + describe("constructing a vertex and applying a translation", function () { + let vertex_org: IVertex; + before(function () { + vertex_org = occ.makeVertex([10, 20, 30]); + }); + + it("should be translated", function () { + let vertex: IVertex; + vertex = vertex_org.translate([10, 20, 30]); + + vertex_org.x.should.equal(10); + vertex_org.y.should.equal(20); + vertex_org.z.should.equal(30); + + vertex.x.should.equal(20); + vertex.y.should.equal(40); + vertex.z.should.equal(60); + }); + it("should be translated - second form ", function () { + let vertex: IVertex; + vertex = vertex_org.translate(/*[*/ 10, 20, 30 /*]*/); + + vertex_org.x.should.equal(10); + vertex_org.y.should.equal(20); + vertex_org.z.should.equal(30); + + vertex.x.should.equal(20); + vertex.y.should.equal(40); + vertex.z.should.equal(60); + }); + it("should be mirrored", function () { + const trsf = occ.makePlaneMirror([0, 0, 0], [0, 1, 0]); + + const vertex_dest = vertex_org.transformed(trsf); + vertex_org.x.should.equal(10); + vertex_org.y.should.equal(20); + vertex_org.z.should.equal(30); + + vertex_dest.x.should.equal(10); + vertex_dest.y.should.equal(-20); + vertex_dest.z.should.equal(30); + }); + }); + + describe("edge cases: bad use of constructor shall not cause software to crash ", function () { + it("Edge#constructor - should not crash if new is omitted", function () { + should(function () { + const tmp = /* new */ (Edge as any)(); + tmp; + }).throwError(" use new occ.Edge() to construct a Edge"); + }); + it("Vertex#constructor - should not crash if new is omitted", function () { + should(function () { + const tmp = /* new */ (Vertex as any)(10, 20, 30); + tmp; + }).throwError(" use occ.makeVertex() to construct a Vertex"); + }); + it("Wire#constructor - should not crash if new is omitted", function () { + should(function () { + const tmp = /* new */ (Wire as any)(); + tmp; + }).throwError(" use new occ.Wire() to construct a Wire"); + }); + it("Solid#constructor - should not crash if new is omitted", function () { + should(function () { + const tmp = /* new */ (Solid as any)(); + tmp; + }).throwError(" use new occ.Solid() to construct a Solid"); + }); + it("BoundingBox#constructor - should not crash if new is omitted", function () { + should(function () { + const tmp = /* new */ (BoundingBox as any)(10, 20, 30); + tmp; + }).throwError(" use new occ.BoundingBox() to construct a BoundingBox"); + }); + + it("Vertex#constructor should not crash if wrong argument are provided", function () { + const tmp = makeVertex({ x: 10, y: 20, z: 30 }); + tmp; + }); + }); + + describe("should provide a way to compare vertex", function () { + it("should compare 2 vertices with same coordinates", function () { + const vertex1 = occ.makeVertex(10, 20, 30); + const vertex2 = occ.makeVertex(10, 20, 30); + should(vertex1).eql(vertex2); + if (doDebug) { + console.log("vertex1 ", vertex1); + } + should(vertex1).containEql({ x: 10, y: 20, z: 30 }); + }); + it("should compare 2 vertices with different coordinates", function () { + const vertex1 = occ.makeVertex(10, 20, 30); + const vertex2 = occ.makeVertex(110, 220, 330); + should(vertex1).not.eql(vertex2); + }); + }); +}); diff --git a/test/test_wire.js b/test/test_wire.js deleted file mode 100644 index 51279b9..0000000 --- a/test/test_wire.js +++ /dev/null @@ -1,55 +0,0 @@ - -const assert = require("assert"); -const should = require("should"); - -const occ = require("../lib/occ"); - - -describe("testing Wire ",function(){ - - describe("empty wire", function() { - let wire; - before(function() { - wire = new occ.Wire(); - }); - it("should have no edges", function() { - wire.numEdges.should.equal(0); - }); - it("should have no vertex", function() { - wire.numVertices.should.equal(0); - }); - it("should not be closed", function() { - wire.isClosed.should.equal(false); - }); - }); - describe("wire with three segments", function () { - - let edge1, edge2, edge3; - let wire; - before(function () { - let v1 = new occ.Vertex(0, 0, 0); - let v2 = new occ.Vertex(10, 10, 0); - let v3 = new occ.Vertex(20, 0, 0); - edge1 = occ.makeLine(v1, v2); - edge2 = occ.makeLine(v2, v3); - edge3 = occ.makeLine(v3, v1); - wire = new occ.Wire(edge1, edge2, edge3); - }); - - it("should have three edges", function () { - wire.numEdges.should.equal(3); - }); - - it("should have three vertive", function () { - wire.numVertices.should.equal(3); - }); - - it("should be closed", function () { - wire.isClosed.should.equal(true); - }); - }); - -}); - - - diff --git a/test/test_wire.ts b/test/test_wire.ts new file mode 100644 index 0000000..2e3cd0b --- /dev/null +++ b/test/test_wire.ts @@ -0,0 +1,117 @@ +import "should"; + +import { IEdge, IWire, Triplet, occ } from ".."; + +describe("testing Wire ", function () { + describe("empty wire", function () { + let wire: IWire; + before(function () { + wire = occ.makeWire(); + }); + it("should have no edges", function () { + wire.numEdges.should.equal(0); + }); + it("should have no vertex", function () { + wire.numVertices.should.equal(0); + }); + it("should not be closed", function () { + wire.isClosed.should.equal(false); + }); + }); + describe("wire with three segments", function () { + let edge1: IEdge, edge2: IEdge, edge3: IEdge; + let wire: IWire; + before(function () { + let v1 = occ.makeVertex(0, 0, 0); + let v2 = occ.makeVertex(10, 10, 0); + let v3 = occ.makeVertex(20, 0, 0); + + edge1 = occ.makeLine(v1, v2); + edge2 = occ.makeLine(v2, v3); + edge3 = occ.makeLine(v3, v1); + + wire = occ.makeWire(edge1, edge2, edge3); + }); + + it("should have three edges", function () { + wire.numEdges.should.equal(3); + }); + + it("should have three vertive", function () { + wire.numVertices.should.equal(3); + }); + + it("should be closed", function () { + wire.isClosed.should.equal(true); + }); + }); + + describe("wire made of many small segments", () => { + const DEG2RAD = Math.atan(1) / 45; + function makeSegments() { + const r = 100; + + const segments: IEdge[] = []; + + for (let i = 0; i <= 360; i += 45) { + const a1 = i * DEG2RAD; + const c1 = Math.cos(a1); + const s1 = Math.sin(a1); + + const a2 = (i + 1) * DEG2RAD; + const c2 = Math.cos(a2); + const s2 = Math.sin(a2); + + const p1: Triplet = [r * c1, r * s1, 0]; + const p2: Triplet = [r * c2, r * s2, 0]; + + // console.log(p1, p2); + const s = occ.makeLine(p1, p2); + segments.push(s); + } + return segments; + } + + function shuffleInPlace(array: T[]): void { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + const temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + it("should create a wire with a set of ordered segments forming a close wire", () => { + const segments = makeSegments(); + const wire = occ.makeWire(...segments); + wire.isClosed.should.eql(true); + }); + + it("should create a wire with a set of shuffled segments forming a close wire", () => { + const segments = makeSegments(); + shuffleInPlace(segments); + const wire = occ.makeWire(segments); + wire.isClosed.should.eql(false); + if (wire) { + // wire.isDegenerated.should.eql(false); + } + }); + + it("should falied to create a wire with a set of segments that is not forming a close wire", () => { + const segments = makeSegments(); + const lBefore = segments.length; + + segments.splice(1, 2); + + segments.splice(5, 2); + + const lAfter = segments.length; + + console.log("lBefore", lBefore, lAfter); + const wire = occ.makeWire(segments); + if (wire) { + // wire.isClosed.should.eql(false); + // wire.isDegenerated.should.eql(false); + } + }); + }); +}); diff --git a/test1.js b/test1.js index 3951676..aab591e 100644 --- a/test1.js +++ b/test1.js @@ -1,127 +1,110 @@ -var util = require('util'); -var assert = require('assert'); +const util = require('util'); +const assert = require('assert'); -var occ = require('./'); +const { occ, shapeFactory, ZDir } = require('./'); -function testOuterShell() -{ - var solid1 = occ.makeBox([10,20,30],[20,40,60]); - var solid2 = occ.makeBox([15,25,35],[-20,-40,-60]); - var solid = occ.fuse(solid1,solid2); +function testOuterShell() { + let solid1 = occ.makeBox([10, 20, 30], [20, 40, 60]); + let solid2 = occ.makeBox([15, 25, 35], [-20, -40, -60]); + let solid = occ.fuse(solid1, solid2); - solid1 = occ.makeBox([0,0,0],[20,20,20]); - solid2 = occ.makeBox([10,10,10],[15,15,15]); - solid = occ.cut(solid1,solid2); + solid1 = occ.makeBox([0, 0, 0], [20, 20, 20]); + solid2 = occ.makeBox([10, 10, 10], [15, 15, 15]); + solid = occ.cut(solid1, solid2); solid.getOuterShell(); - var shells = solid.getShells(); - for (var i in shells) { - var shell = shells[i]; - console.log(shell.shapeType,shell.numFaces); + const shells = solid.getShells(); + for (const i in shells) { + const shell = shells[i]; + console.log(shell.shapeType, shell.numFaces); } } testOuterShell(); console.log("-------------------"); -function testCyl() -{ - var cyl =occ.makeCylinder([-100,20,30],[100,20,30],40); - +function testCyl() { + const cyl = occ.makeCylinder([-100, 20, 30], [100, 20, 30], 40); } testCyl(); -var shapeFactory = require('./lib/shapeFactory.js'); -function testCSG1() -{ - var solid = shapeFactory.makePan(occ); + +function testCSG1() { + const solid = shapeFactory.makePan(occ); } testCSG1(); -var bbox = new occ.BoundingBox(); +const bbox = new occ.BoundingBox(); console.log(bbox.nearPt); console.log(bbox.nearPt.x); -//var bottle = shapeFactory.makeBottle(); +//const bottle = shapeFactory.makeBottle(); -function test3() -{ - solid = occ.makeBox([10,20,30],[20,40,60]); - solid = occ.makeFillet(solid,solid.getEdges(),2); +function test3() { + let solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + solid = occ.makeFillet(solid, solid.getEdges(), 2); } test3(); -function test2(){ - var trsf ; - trsf=new occ.Transformation(); - trsf.makePlaneMirror([10,20,30],occ.ZDir); - - console.log(" Scale Factor=",trsf.scaleFactor); +function test2() { + const trsf = new occ.Transformation(); + trsf.makePlaneMirror([10, 20, 30], ZDir); + console.log(" Scale Factor=", trsf.scaleFactor); } test2(); function test1() { -var solid; -var shapeIt; - -solid = occ.makeBox([10,20,30],[20,40,60]); - -shapeIt = new occ.ShapeIterator(solid,"FACE"); - shapeIt.more.should.be.true; + const solid = occ.makeBox([10, 20, 30], [20, 40, 60]); + const shapeIt = new occ.ShapeIterator(solid, "FACE"); + assert(shapeIt.more); assert(shapeIt.current === undefined); - } test1(); - -var wire = new occ.Wire(); +const wire = new occ.Wire(); console.log(wire.numEdges); console.log(wire.numVertices); -var trsf; -trsf = new occ.Transformation(); -trsf.makePlaneMirror([10,20,30],occ.ZDir); - - +const trsf = new occ.Transformation(); +trsf.makePlaneMirror([10, 20, 30], ZDir); - -var v = new occ.Vertex(); -var e = new occ.Edge().createLine([10,20,30],[10,14,15]); +const v = occ.makeVertex(); +const e = new occ.Edge().createLine([10, 20, 30], [10, 14, 15]); console.log(e.length) edge = new occ.Edge(); -edge.createCircle([10,10,10],[0,0,1],20); +edge.createCircle([10, 10, 10], [0, 0, 1], 20); console.log("hello"); -var box1 = new occ.Solid(); +const box1 = new occ.Solid(); assert(box1.isNull); assert(!box1.isValid); -box1 = occ.makeBox([10,20,30],[30,40,50]); +box1 = occ.makeBox([10, 20, 30], [30, 40, 50]); -//xx for (var i in box1.mesh) { +//xx for (const i in box1.mesh) { //xx console.log( " i=",i," => ", box1.mesh[i]); //xx } console.log("---------------!!!"); -console.log( " i=",i," => ", box1.mesh.vertices); +console.log(" i=", i, " => ", box1.mesh.vertices); assert(!box1.isNull); assert(box1.isValid); -var box2 = occ.makeBox([10,20,30],[100,100,100]); -var box3 = occ.makeBox([10,20,30],100,100,100); +const box2 = occ.makeBox([10, 20, 30], [100, 100, 100]); +const box3 = occ.makeBox([10, 20, 30], 100, 100, 100); //xx console.log("box1.x",box1.location.x); //xx console.log("box1.x",box1.location.y); @@ -129,27 +112,27 @@ var box3 = occ.makeBox([10,20,30],100,100,100); //xx console.log("cuboid",JSON.stringify(box1)); -var solid = occ.makeBox([10,20,30],[20,30,40]); +const solid = occ.makeBox([10, 20, 30], [20, 30, 40]); -for ( var i in solid) { - console.log(" i = ", i, " => " , solid[i]); +for (const i in solid) { + console.log(" i = ", i, " => ", solid[i]); } -var expected = ["isNull","area","volume","numFaces","numSolids","isValid","rotate","fuse"]; +const expected = ["isNull", "area", "volume", "numFaces", "numSolids", "isValid", "rotate", "fuse"]; -for ( var j in occ.Solid.prototype) { - console.log(" j = ", j, " => " , occ.Solid.prototype[j]); -} +for (const j in occ.Solid.prototype) { + console.log(" j = ", j, " => ", occ.Solid.prototype[j]); +} console.log("------------------"); -console.log("JSON =",solid.mesh.toJSON()); +console.log("JSON =", solid.mesh.toJSON()); -occ.writeSTEP("toto.STEP",solid); +occ.writeSTEP("toto.STEP", solid); console.log("Done"); diff --git a/tsconfig.common.json b/tsconfig.common.json new file mode 100644 index 0000000..c45cb4e --- /dev/null +++ b/tsconfig.common.json @@ -0,0 +1,65 @@ +{ + "compilerOptions": { + /* Basic Options */ + "incremental": true, /* Enable incremental compilation */ + "target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "lib": [ + "ES2016" + ], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDir": "./lib", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + "types": [ + "node", + "mocha" + ], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..286856f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.common.json", + "compilerOptions": { + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDir": "./lib", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + }, + "include": [ + "lib/*.ts", + ] +} \ No newline at end of file diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..ed02144 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.common.json", + "compilerOptions": { + "outDir": "./dist-test", /* Redirect output structure to the directory. */ + "rootDir": "./test", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + }, + "include": [ + "test/*.ts", + ] +} \ No newline at end of file