@jscad/core 2.5.9 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.6.0](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/core@2.5.9...@jscad/core@2.6.0) (2022-05-15)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **core:** catch and create create message from thrown objects (non-Error) ([2cdbbf1](https://github.com/jscad/OpenJSCAD.org/commit/2cdbbf108e0c48fc1a69e53da404968cea07142e))
12
+ * **core:** corrected webRequire to catch errors from dynamic code evaluation, and rethrow with correct context ([ff06731](https://github.com/jscad/OpenJSCAD.org/commit/ff0673136f26b08116054e49fa179b8807b9ab3b))
13
+
14
+
15
+ ### Features
16
+
17
+ * **core:** corrected rebuildGeometry to catch all errors, and callback with complete error information ([61dac1c](https://github.com/jscad/OpenJSCAD.org/commit/61dac1ca8a2bc849c1e5e304c75bc752b7ae2bac))
18
+
19
+
20
+
21
+
22
+
6
23
  ## [2.5.9](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/core@2.5.8...@jscad/core@2.5.9) (2022-04-24)
7
24
 
8
25
  **Note:** Version bump only for package @jscad/core
@@ -26,7 +26,7 @@ var cachedSetTimeout,cachedClearTimeout,process=module.exports={};function defau
26
26
  },{}],8:[function(require,module,exports){
27
27
  module.exports={
28
28
  "name": "@jscad/core",
29
- "version": "2.5.9",
29
+ "version": "2.6.0",
30
30
  "description": "Core functionality for JSCAD Applications",
31
31
  "homepage": "https://openjscad.xyz/",
32
32
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -62,9 +62,9 @@ module.exports={
62
62
  "license": "MIT",
63
63
  "dependencies": {
64
64
  "@jscad/array-utils": "2.1.4",
65
- "@jscad/io": "2.3.2",
66
- "@jscad/io-utils": "2.0.18",
67
- "@jscad/modeling": "2.9.3",
65
+ "@jscad/io": "2.3.3",
66
+ "@jscad/io-utils": "2.0.19",
67
+ "@jscad/modeling": "2.9.4",
68
68
  "json5": "2.2.0",
69
69
  "strip-bom": "4.0.0"
70
70
  },
@@ -89,13 +89,13 @@ module.exports={rebuildGeometry:require("./rebuildGeometry"),rebuildGeometryCli:
89
89
  const isGeom2=require("@jscad/modeling").geometries.geom2.isA,isGeom3=require("@jscad/modeling").geometries.geom3.isA,isPath2=require("@jscad/modeling").geometries.path2.isA,{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),serializeSolids=require("./serializeSolids"),isResultGeometry=e=>!!(Array.isArray(e)&&e.length>0)&&e.reduce((e,i)=>e||isGeom3(i)||isGeom2(i)||isPath2(i),!1),instanciateDesign=(e,i,r)=>{const{serialize:s}=r;let t;const o=flatten(toArray(e.main(i)));if(isResultGeometry(o))return{solids:t=s?serializeSolids(o):o};throw new Error("bad output from script: expected geom3/geom2/path2 objects")};module.exports=instanciateDesign;
90
90
 
91
91
  },{"./serializeSolids":14,"@jscad/array-utils":906,"@jscad/modeling":592}],11:[function(require,module,exports){
92
- const loadDesign=require("../code-loading/loadDesign"),instanciateDesign=require("./instanciateDesign"),applyParameterDefinitions=require("../parameters/applyParameterDefinitions"),rebuildSolids=(e,a)=>{let{mainPath:i,apiMainPath:o,serialize:s,lookup:l,lookupCounts:n,parameterValues:t}=Object.assign({},{mainPath:"",apiMainPath:"@jscad/modeling",serialize:!1,lookup:null,lookupCounts:null,parameterValues:{}},e);const r=e.filesAndFolders,p=loadDesign(i,o,r,t);a(null,{type:"params",parameterDefaults:p.parameterValues,parameterDefinitions:p.parameterDefinitions}),t=applyParameterDefinitions(t,p.parameterDefinitions),t=Object.assign({},p.parameterValues,t);const u={lookup:l,lookupCounts:n,serialize:s},d=instanciateDesign(p.rootModule,t,u);a(null,{type:"solids",solids:d.solids,lookup:d.lookup,lookupCounts:d.lookupCounts})};module.exports=rebuildSolids;
92
+ const loadDesign=require("../code-loading/loadDesign"),instanciateDesign=require("./instanciateDesign"),applyParameterDefinitions=require("../parameters/applyParameterDefinitions"),rebuildSolids=(e,a)=>{let{mainPath:i,apiMainPath:n,serialize:s,lookup:o,lookupCounts:r,parameterValues:l}=Object.assign({},{mainPath:"",apiMainPath:"@jscad/modeling",serialize:!1,lookup:null,lookupCounts:null,parameterValues:{}},e);try{const t=e.filesAndFolders,u=loadDesign(i,n,t,l);a(null,{type:"params",parameterDefaults:u.parameterValues,parameterDefinitions:u.parameterDefinitions}),l=applyParameterDefinitions(l,u.parameterDefinitions),l=Object.assign({},u.parameterValues,l);const m={lookup:o,lookupCounts:r,serialize:s},p=instanciateDesign(u.rootModule,l,m);a(null,{type:"solids",solids:p.solids,lookup:p.lookup,lookupCounts:p.lookupCounts})}catch(e){a({type:"errors",name:e.name?e.name:"Error",message:e.message?e.message:e.toString(),description:e.description?e.description:"",number:e.number?e.number:"",fileName:e.fileName?e.fileName:"",lineNumber:e.lineNumber?e.lineNumber:"",columnNumber:e.columnNumber?e.columnNumber:"",stack:e.stack?e.stack:""},null)}};module.exports=rebuildSolids;
93
93
 
94
94
  },{"../code-loading/loadDesign":16,"../parameters/applyParameterDefinitions":27,"./instanciateDesign":10}],12:[function(require,module,exports){
95
95
  const path=require("path"),{toArray:toArray}=require("@jscad/array-utils"),requireDesignFromModule=require("../code-loading/requireDesignFromModule"),getAllParameterDefintionsAndValues=require("../parameters/getParameterDefinitionsAndValues"),makeWebRequire=require("../code-loading/webRequire"),rebuildSolids=e=>{let{apiMainPath:r,mainPath:a,parameterValues:i,useFakeFs:t}=Object.assign({},{apiMainPath:"@jscad/modeling"},e),s=require;if(t){const i=path.parse(a),t=`${i.name}.js`,u=`/${i.name}.js`,n=[{ext:"js",fullPath:u,name:t,source:e.source}];s=makeWebRequire(n,{apiMainPath:r}),a=u}const u=requireDesignFromModule(a,s),n=getAllParameterDefintionsAndValues(u,i);return toArray(u.main(n.parameterValues))};module.exports=rebuildSolids;
96
96
 
97
97
  },{"../code-loading/requireDesignFromModule":19,"../code-loading/webRequire":23,"../parameters/getParameterDefinitionsAndValues":28,"@jscad/array-utils":906,"path":4}],13:[function(require,module,exports){
98
- const rebuildGeometryWorker=e=>{const o=require("./rebuildGeometry");e.onmessage=function(r){if(r.data instanceof Object){const{data:t}=r;"generate"===t.cmd&&o(t,(o,r)=>e.postMessage(r))}}};module.exports=rebuildGeometryWorker;
98
+ const rebuildGeometryWorker=e=>{const o=require("./rebuildGeometry");e.onmessage=function(t){if(t.data instanceof Object){const{data:r}=t;"generate"===r.cmd&&o(r,(o,t)=>{t&&e.postMessage(t),o&&e.postMessage(o)})}}};module.exports=rebuildGeometryWorker;
99
99
 
100
100
  },{"./rebuildGeometry":11}],14:[function(require,module,exports){
101
101
  const{geom2:geom2,geom3:geom3,path2:path2}=require("@jscad/modeling").geometries,serializeSolids=e=>e=e.map(e=>(geom2.isA(e)&&geom2.toSides(e),geom3.isA(e)&&geom3.toPolygons(e),path2.isA(e)&&path2.toPoints(e),e));module.exports=serializeSolids;
@@ -125,7 +125,7 @@ const{deserializers:deserializers}=require("@jscad/io"),modulifyTransform=(e,r)=
125
125
  const validateDesignModule=n=>{if(!n)throw new Error("undefined root module passed !");if("function"==typeof n&&console.warn("please use named exports for your main() function ! auto updating"),!("main"in n))throw new Error("no main() function found in the input script")};module.exports=validateDesignModule;
126
126
 
127
127
  },{}],23:[function(require,module,exports){
128
- const path=require("path"),posix=path.posix?path.posix:path,getFileExtensionFromString=require("../utils/getFileExtensionFromString"),{combineParameterDefinitions:combineParameterDefinitions,getParameterDefinitionsFromSource:getParameterDefinitionsFromSource}=require("../parameters/getParameterDefinitionsFromSource"),findMatch=(e,r)=>{for(let t=0;t<r.length;t++){const n=r[t];if(e===n.fullPath||"/"+e===n.fullPath)return n;if(n.children){const r=findMatch(e,n.children);if(void 0!==r)return r}}},registerJsExtension=(e,r)=>{const t=require("strip-bom");r.extensions[".js"]=((r,n)=>{const i=e.readFileSync(n,"utf8");r._compile(t(i),n)})},registerJsonExtension=(e,r)=>{r.extensions[".json"]=((r,t)=>{const n=e.readFileSync(t,"utf8");r.exports=JSON.parse(n)})},makeWebRequire=(e,r)=>{const t={apiMainPath:"@jscad/modeling",fakeFs:require("./makeFakeFs")(e)},{apiMainPath:n,fakeFs:i}=Object.assign({},t,r),s="@jscad/modeling"===n?require("@jscad/modeling"):require(n),o={"@jscad/io":{exports:require("@jscad/io")},"@jscad/array-utils":{exports:require("@jscad/array-utils")},"@jscad/modeling":{exports:s},fs:{exports:i}},a={},l={},u=(r,t)=>{const n=o[t];if(n)return n.exports;r&&!t.startsWith("/")||(r="/");const i=r=>{let t=getFileExtensionFromString(r);t||(t="js",r+=".js"),t="."+t;const n=findMatch(r,e);if(!n)return null;if(n.children)return null;if(a[t]){if(l[r])return l[r];const e={exports:{},_compile:(r,t)=>{new Function("require","module",r)(u.bind(null,n.fullPath),e);const i=r.includes("@jscad-params")?getParameterDefinitionsFromSource(r,t):[],s=e.exports.getParameterDefinitions;e.exports.getParameterDefinitions=(()=>combineParameterDefinitions(i,s&&s()||[]))}};return a[t](e,n.fullPath),l[r]=e.exports,l[r]}return null},s=r=>{if(!findMatch(r,e))return null;"/"===r&&(r="");let t=r+"/index.js",n=i(t);return n||((n=i(t=r+"/index.json"))||null)},c=r=>{let t,n=findMatch(r,e);if(!n)return null;if(!n.children)return null;if(n=findMatch(r+"/package.json",e)){const e=JSON.parse(n.source).main;if(e){const n=posix.normalize(r+"/"+e);return(t=i(n))?t:(t=s(n))||null}}return(t=s(r))||null};if(t.startsWith("./")||t.startsWith("/")||t.startsWith("../")){t=posix.normalize(posix.dirname(r)+posix.sep+t);let e=i(t);if(e)return e;if(e=c(t))return e;throw new Error(`Cannot find relative path to module ${t}`)}const f=((e,r)=>{const t=(e=>{const r=e.split("/"),t=[];for(let e=r.length-1;e>0;e--){if("node_modules"===r[e])continue;const n=posix.sep+posix.join(...r.slice(1,e+1),"node_modules");t.push(n)}return t})(r);for(let r=0;r<t.length;r++){const n=t[r],s=posix.join(n,e);let o=i(s);if(o)return o;if(o=c(s))return o}return null})(t,posix.dirname(r));if(f)return f;throw new Error(`Cannot find module ${t}`)},c=u.bind(null,"/");return c.extensions=a,c.resolve=(()=>{}),registerJsExtension(i,c),registerJsonExtension(i,c),c};module.exports=makeWebRequire;
128
+ const path=require("path"),posix=path.posix?path.posix:path,getFileExtensionFromString=require("../utils/getFileExtensionFromString"),{combineParameterDefinitions:combineParameterDefinitions,getParameterDefinitionsFromSource:getParameterDefinitionsFromSource}=require("../parameters/getParameterDefinitionsFromSource"),findMatch=(e,t)=>{for(let r=0;r<t.length;r++){const n=t[r];if(e===n.fullPath||"/"+e===n.fullPath)return n;if(n.children){const t=findMatch(e,n.children);if(void 0!==t)return t}}},registerJsExtension=(e,t)=>{const r=require("strip-bom");t.extensions[".js"]=((t,n)=>{const i=e.readFileSync(n,"utf8");t._compile(r(i),n)})},registerJsonExtension=(e,t)=>{t.extensions[".json"]=((t,r)=>{const n=e.readFileSync(r,"utf8");t.exports=JSON.parse(n)})},makeWebRequire=(e,t)=>{const r={apiMainPath:"@jscad/modeling",fakeFs:require("./makeFakeFs")(e)},{apiMainPath:n,fakeFs:i}=Object.assign({},r,t),s="@jscad/modeling"===n?require("@jscad/modeling"):require(n),o={"@jscad/io":{exports:require("@jscad/io")},"@jscad/array-utils":{exports:require("@jscad/array-utils")},"@jscad/modeling":{exports:s},fs:{exports:i}},a={},l={},u=(t,r)=>{const n=o[r];if(n)return n.exports;t&&!r.startsWith("/")||(t="/");const i=t=>{let r=getFileExtensionFromString(t);r||(r="js",t+=".js"),r="."+r;const n=findMatch(t,e);if(!n)return null;if(n.children)return null;if(a[r]){if(l[t])return l[t];const e={exports:{},_compile:(t,r)=>{try{new Function("require","module",t)(u.bind(null,n.fullPath),e)}catch(e){const t=e.message;r=r.replace("/","");const n=e.lineNumber?e.lineNumber-2:0,i=e.columnNumber?e.columnNumber:0;throw e.stack.startsWith("Object")?e.stack=`${e.stack}\nObject.<anonymous> (${r}:${n}:${i})`:((e=new SyntaxError(t,r,n)).columnNumber=i,e.stack=`Object.<anonymous> (${r}:${n}:${i})`),e}const i=t.includes("@jscad-params")?getParameterDefinitionsFromSource(t,r):[],s=e.exports.getParameterDefinitions;e.exports.getParameterDefinitions=(()=>combineParameterDefinitions(i,s&&s()||[]))}};return a[r](e,n.fullPath),l[t]=e.exports,l[t]}return null},s=t=>{if(!findMatch(t,e))return null;"/"===t&&(t="");let r=t+"/index.js",n=i(r);return n||((n=i(r=t+"/index.json"))||null)},c=t=>{let r,n=findMatch(t,e);if(!n)return null;if(!n.children)return null;if(n=findMatch(t+"/package.json",e)){const e=JSON.parse(n.source).main;if(e){const n=posix.normalize(t+"/"+e);return(r=i(n))?r:(r=s(n))||null}}return(r=s(t))||null};if(r.startsWith("./")||r.startsWith("/")||r.startsWith("../")){r=posix.normalize(posix.dirname(t)+posix.sep+r);let e=i(r);if(e)return e;if(e=c(r))return e;throw new Error(`Cannot find relative path to module ${r}`)}const m=((e,t)=>{const r=(e=>{const t=e.split("/"),r=[];for(let e=t.length-1;e>0;e--){if("node_modules"===t[e])continue;const n=posix.sep+posix.join(...t.slice(1,e+1),"node_modules");r.push(n)}return r})(t);for(let t=0;t<r.length;t++){const n=r[t],s=posix.join(n,e);let o=i(s);if(o)return o;if(o=c(s))return o}return null})(r,posix.dirname(t));if(m)return m;throw new Error(`Cannot find module ${r}`)},c=u.bind(null,"/");return c.extensions=a,c.resolve=(()=>{}),registerJsExtension(i,c),registerJsonExtension(i,c),c};module.exports=makeWebRequire;
129
129
 
130
130
  },{"../parameters/getParameterDefinitionsFromSource":29,"../utils/getFileExtensionFromString":33,"./makeFakeFs":17,"@jscad/array-utils":906,"@jscad/io":74,"@jscad/modeling":592,"path":4,"strip-bom":7}],24:[function(require,module,exports){
131
131
  module.exports={evaluation:require("./code-evaluation"),io:require("./io"),loading:require("./code-loading"),parameters:require("./parameters"),utils:require("./utils"),web:require("./web")};
@@ -196,7 +196,7 @@ const zipSync=require("fflate").zipSync,strToU8=require("fflate").strToU8,string
196
196
  },{"xmlchars/xml/1.0/ed5":42,"xmlchars/xml/1.1/ed2":43,"xmlchars/xmlns/1.0/ed3":44}],46:[function(require,module,exports){
197
197
  module.exports={
198
198
  "name": "@jscad/amf-deserializer",
199
- "version": "2.2.11",
199
+ "version": "2.2.12",
200
200
  "description": "AMF Deserializer for JSCAD",
201
201
  "repository": "https://github.com/jscad/OpenJSCAD.org/",
202
202
  "main": "src/index.js",
@@ -227,7 +227,7 @@ module.exports={
227
227
  ],
228
228
  "license": "MIT",
229
229
  "dependencies": {
230
- "@jscad/modeling": "2.9.3",
230
+ "@jscad/modeling": "2.9.4",
231
231
  "saxes": "5.0.1"
232
232
  },
233
233
  "devDependencies": {
@@ -285,7 +285,7 @@ const{geometries:geometries,maths:maths,primitives:primitives}=require("@jscad/m
285
285
  },{"./helpers":59,"@jscad/modeling":592}],62:[function(require,module,exports){
286
286
  module.exports={
287
287
  "name": "@jscad/dxf-deserializer",
288
- "version": "2.3.15",
288
+ "version": "2.3.16",
289
289
  "description": "DXF Deserializer for JSCAD",
290
290
  "homepage": "https://openjscad.xyz/",
291
291
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -313,7 +313,7 @@ module.exports={
313
313
  ],
314
314
  "license": "MIT",
315
315
  "dependencies": {
316
- "@jscad/modeling": "2.9.3"
316
+ "@jscad/modeling": "2.9.4"
317
317
  },
318
318
  "devDependencies": {
319
319
  "ava": "3.15.0",
@@ -369,7 +369,7 @@ const{flatten:flatten,toArray:toArray}=require("@jscad/array-utils"),version=req
369
369
  },{"./package.json":77,"@jscad/array-utils":906}],77:[function(require,module,exports){
370
370
  module.exports={
371
371
  "name": "@jscad/json-deserializer",
372
- "version": "2.0.19",
372
+ "version": "2.0.20",
373
373
  "description": "JSON Deserializer for JSCAD",
374
374
  "homepage": "https://openjscad.xyz/",
375
375
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -400,7 +400,7 @@ module.exports={
400
400
  "@jscad/array-utils": "2.1.4"
401
401
  },
402
402
  "devDependencies": {
403
- "@jscad/modeling": "2.9.3",
403
+ "@jscad/modeling": "2.9.4",
404
404
  "ava": "3.15.0",
405
405
  "nyc": "15.1.0"
406
406
  },
@@ -416,7 +416,7 @@ const{colors:colors,primitives:primitives}=require("@jscad/modeling"),version=re
416
416
  },{"./package.json":80,"@jscad/modeling":592}],80:[function(require,module,exports){
417
417
  module.exports={
418
418
  "name": "@jscad/obj-deserializer",
419
- "version": "2.0.18",
419
+ "version": "2.0.19",
420
420
  "description": "OBJ Deserializer for JSCAD",
421
421
  "homepage": "https://openjscad.xyz/",
422
422
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -448,7 +448,7 @@ module.exports={
448
448
  ],
449
449
  "license": "MIT",
450
450
  "dependencies": {
451
- "@jscad/modeling": "2.9.3"
451
+ "@jscad/modeling": "2.9.4"
452
452
  },
453
453
  "devDependencies": {
454
454
  "ava": "3.15.0",
@@ -466,7 +466,7 @@ const{maths:maths,primitives:primitives}=require("@jscad/modeling"),{BinaryReade
466
466
  },{"./package.json":83,"@jscad/io-utils":70,"@jscad/modeling":592}],83:[function(require,module,exports){
467
467
  module.exports={
468
468
  "name": "@jscad/stl-deserializer",
469
- "version": "2.1.15",
469
+ "version": "2.1.16",
470
470
  "description": "STL Deserializer for JSCAD",
471
471
  "homepage": "https://openjscad.xyz/",
472
472
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -498,8 +498,8 @@ module.exports={
498
498
  ],
499
499
  "license": "MIT",
500
500
  "dependencies": {
501
- "@jscad/io-utils": "2.0.18",
502
- "@jscad/modeling": "2.9.3"
501
+ "@jscad/io-utils": "2.0.19",
502
+ "@jscad/modeling": "2.9.4"
503
503
  },
504
504
  "devDependencies": {
505
505
  "ava": "3.15.0",
@@ -532,7 +532,7 @@ const{geometries:geometries,modifiers:modifiers}=require("@jscad/modeling"),{fla
532
532
  },{"xmlchars/xml/1.0/ed5":87,"xmlchars/xml/1.1/ed2":88,"xmlchars/xmlns/1.0/ed3":89}],91:[function(require,module,exports){
533
533
  module.exports={
534
534
  "name": "@jscad/svg-deserializer",
535
- "version": "2.4.11",
535
+ "version": "2.4.12",
536
536
  "description": "SVG Deserializer for JSCAD",
537
537
  "homepage": "https://openjscad.xyz/",
538
538
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -565,7 +565,7 @@ module.exports={
565
565
  "license": "MIT",
566
566
  "dependencies": {
567
567
  "@jscad/array-utils": "2.1.4",
568
- "@jscad/modeling": "2.9.3",
568
+ "@jscad/modeling": "2.9.4",
569
569
  "saxes": "5.0.1"
570
570
  },
571
571
  "devDependencies": {
@@ -602,7 +602,7 @@ const{geometries:geometries,maths:maths,measurements:measurements,utils:utils}=r
602
602
  },{}],100:[function(require,module,exports){
603
603
  module.exports={
604
604
  "name": "@jscad/svg-serializer",
605
- "version": "2.3.6",
605
+ "version": "2.3.7",
606
606
  "description": "SVG Serializer for JSCAD",
607
607
  "homepage": "https://openjscad.xyz/",
608
608
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -634,7 +634,7 @@ module.exports={
634
634
  ],
635
635
  "license": "MIT",
636
636
  "dependencies": {
637
- "@jscad/modeling": "2.9.3",
637
+ "@jscad/modeling": "2.9.4",
638
638
  "onml": "1.3.0"
639
639
  },
640
640
  "devDependencies": {
@@ -2319,9 +2319,9 @@ const invert=(t,e)=>{const n=e[0],r=e[1],l=e[2],o=e[3],s=e[4],u=e[5],c=e[6],i=e[
2319
2319
  const isIdentity=t=>1===t[0]&&0===t[1]&&0===t[2]&&0===t[3]&&0===t[4]&&1===t[5]&&0===t[6]&&0===t[7]&&0===t[8]&&0===t[9]&&1===t[10]&&0===t[11]&&0===t[12]&&0===t[13]&&0===t[14]&&1===t[15];module.exports=isIdentity;
2320
2320
 
2321
2321
  },{}],647:[function(require,module,exports){
2322
- const cross=require("../vec3/cross"),dot=require("../vec3/dot"),fromValues=require("../vec3/fromValues"),isMirroring=r=>{const e=fromValues(r[0],r[4],r[8]),o=fromValues(r[1],r[5],r[9]),s=fromValues(r[2],r[6],r[10]);return dot(cross(e,e,o),s)<0};module.exports=isMirroring;
2322
+ const isMirroring=r=>{const i=r[4]*r[9]-r[8]*r[5],o=r[8]*r[1]-r[0]*r[9],n=r[0]*r[5]-r[4]*r[1];return i*r[2]+o*r[6]+n*r[10]<0};module.exports=isMirroring;
2323
2323
 
2324
- },{"../vec3/cross":713,"../vec3/dot":716,"../vec3/fromValues":719}],648:[function(require,module,exports){
2324
+ },{}],648:[function(require,module,exports){
2325
2325
  const isOnlyTransformScale=s=>isZero(s[1])&&isZero(s[2])&&isZero(s[3])&&isZero(s[4])&&isZero(s[6])&&isZero(s[7])&&isZero(s[8])&&isZero(s[9])&&isZero(s[11])&&1===s[15],isZero=s=>Math.abs(s)<Number.EPSILON;module.exports=isOnlyTransformScale;
2326
2326
 
2327
2327
  },{}],649:[function(require,module,exports){
@@ -2799,9 +2799,9 @@ const geom2=require("../../../geometries/geom2"),plane=require("../../../maths/p
2799
2799
  const pointInTriangle=(n,a,e,r,i,o,t,x)=>(i-t)*(a-x)-(n-t)*(o-x)>=0&&(n-t)*(r-x)-(e-t)*(a-x)>=0&&(e-t)*(o-x)-(i-t)*(r-x)>=0,area=(n,a,e)=>(a.y-n.y)*(e.x-a.x)-(a.x-n.x)*(e.y-a.y);module.exports={area:area,pointInTriangle:pointInTriangle};
2800
2800
 
2801
2801
  },{}],807:[function(require,module,exports){
2802
- const mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),repairSlice=require("./slice/repairSlice"),extrudeWalls=require("./extrudeWalls"),defaultCallback=(e,r,l)=>{let t=null;return geom2.isA(l)&&(t=slice.fromSides(geom2.toSides(l))),poly3.isA(l)&&(t=slice.fromPoints(poly3.toPoints(l))),0===e||1===e?slice.transform(mat4.fromTranslation(mat4.create(),[0,0,e]),t):null},extrudeFromSlices=(e,r)=>{const l={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,repair:!0,callback:defaultCallback},{numberOfSlices:t,capStart:o,capEnd:c,close:s,repair:i,callback:a}=Object.assign({},l,e);if(t<2)throw new Error("numberOfSlices must be 2 or more");i&&repairSlice(r);const n=t-1;let u=null,m=null,f=null,g=[];for(let e=0;e<t;e++){const l=a(e/n,e,r);if(l){if(!slice.isA(l))throw new Error("the callback function must return slice objects");if(0===slice.toEdges(l).length)throw new Error("the callback function must return slices with one or more edges");f&&(g=g.concat(extrudeWalls(f,l))),0===e&&(u=l),e===t-1&&(m=l),f=l}}if(c){const e=slice.toPolygons(m);g=g.concat(e)}if(o){const e=slice.toPolygons(u).map(poly3.invert);g=g.concat(e)}return o||c||s&&!slice.equals(m,u)&&(g=g.concat(extrudeWalls(m,u))),geom3.create(g)};module.exports=extrudeFromSlices;
2802
+ const mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),repairSlice=require("./slice/repair"),extrudeWalls=require("./extrudeWalls"),defaultCallback=(e,r,l)=>{let t=null;return geom2.isA(l)&&(t=slice.fromSides(geom2.toSides(l))),poly3.isA(l)&&(t=slice.fromPoints(poly3.toPoints(l))),0===e||1===e?slice.transform(mat4.fromTranslation(mat4.create(),[0,0,e]),t):null},extrudeFromSlices=(e,r)=>{const l={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,repair:!0,callback:defaultCallback},{numberOfSlices:t,capStart:o,capEnd:c,close:s,repair:i,callback:a}=Object.assign({},l,e);if(t<2)throw new Error("numberOfSlices must be 2 or more");i&&(r=repairSlice(r));const n=t-1;let u=null,m=null,f=null,g=[];for(let e=0;e<t;e++){const l=a(e/n,e,r);if(l){if(!slice.isA(l))throw new Error("the callback function must return slice objects");if(0===slice.toEdges(l).length)throw new Error("the callback function must return slices with one or more edges");f&&(g=g.concat(extrudeWalls(f,l))),0===e&&(u=l),e===t-1&&(m=l),f=l}}if(c){const e=slice.toPolygons(m);g=g.concat(e)}if(o){const e=slice.toPolygons(u).map(poly3.invert);g=g.concat(e)}return o||c||s&&!slice.equals(m,u)&&(g=g.concat(extrudeWalls(m,u))),geom3.create(g)};module.exports=extrudeFromSlices;
2803
2803
 
2804
- },{"../../geometries/geom2":526,"../../geometries/geom3":541,"../../geometries/poly3":579,"../../maths/mat4":644,"./extrudeWalls":815,"./slice":824,"./slice/repairSlice":826}],808:[function(require,module,exports){
2804
+ },{"../../geometries/geom2":526,"../../geometries/geom3":541,"../../geometries/poly3":579,"../../maths/mat4":644,"./extrudeWalls":815,"./slice":824,"./slice/repair":826}],808:[function(require,module,exports){
2805
2805
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudeLinearPath2=require("./extrudeLinearPath2"),extrudeLinear=(e,...t)=>{const{height:r,twistAngle:i,twistSteps:n,repair:a}=Object.assign({},{height:1,twistAngle:0,twistSteps:1,repair:!0},e);if(0===(t=flatten(t)).length)throw new Error("wrong number of arguments");e={offset:[0,0,r],twistAngle:i,twistSteps:n,repair:a};const s=t.map(t=>path2.isA(t)?extrudeLinearPath2(e,t):geom2.isA(t)?extrudeLinearGeom2(e,t):t);return 1===s.length?s[0]:s};module.exports=extrudeLinear;
2806
2806
 
2807
2807
  },{"../../geometries/geom2":526,"../../geometries/path2":562,"../../utils/flatten":895,"./extrudeLinearGeom2":809,"./extrudeLinearPath2":810}],809:[function(require,module,exports){
@@ -2856,9 +2856,9 @@ module.exports={calculatePlane:require("./calculatePlane"),clone:require("./clon
2856
2856
  const isA=e=>!!(e&&"object"==typeof e&&"edges"in e&&Array.isArray(e.edges));module.exports=isA;
2857
2857
 
2858
2858
  },{}],826:[function(require,module,exports){
2859
- const vec3=require("../../../maths/vec3"),repairSlice=e=>{if(!e.edges)return e;const t={},r={};e.edges.forEach(e=>{const c=e[0].toString(),o=e[1].toString();t[c]=e[0],t[o]=e[1],r[c]=(r[c]||0)+1,r[o]=(r[o]||0)-1});const c=Object.keys(r).filter(e=>r[e]<0),o=Object.keys(r).filter(e=>r[e]>0);return c.forEach(r=>{const c=t[r];let i,s=1/0;o.forEach(e=>{const r=t[e],o=Math.hypot(c[0]-r[0],c[1]-r[1]);o<s&&(s=o,i=r)}),console.warn(`repairSlice: repairing vertex gap ${c} to ${i} distance ${s}`),e.edges.forEach(e=>{e[0].toString()===r&&(e[0]=i),e[1].toString()===r&&(e[1]=i)})}),e.edges=e.edges.filter(e=>!vec3.equals(e[0],e[1])),e};module.exports=repairSlice;
2859
+ const vec3=require("../../../maths/vec3"),create=require("./create"),repair=e=>{if(!e.edges)return e;let t=e.edges;const r=new Map,a=new Map;(t=t.filter(e=>!vec3.equals(e[0],e[1]))).forEach(e=>{const t=e[0].toString(),o=e[1].toString();r.set(t,e[0]),r.set(o,e[1]),a.set(t,(a.get(t)||0)+1),a.set(o,(a.get(o)||0)-1)});const o=[],s=[];return a.forEach((e,t)=>{e<0&&o.push(t),e>0&&s.push(t)}),o.forEach(e=>{const a=r.get(e);let o,c=1/0;s.forEach(e=>{const t=r.get(e),s=Math.hypot(a[0]-t[0],a[1]-t[1]);s<c&&(c=s,o=t)}),console.warn(`slice.repair: repairing vertex gap ${a} to ${o} distance ${c}`),t=t.map(t=>t[0].toString()===e?[o,t[1]]:t[1].toString()===e?[t[0],o]:t)}),create(t)};module.exports=repair;
2860
2860
 
2861
- },{"../../../maths/vec3":721}],827:[function(require,module,exports){
2861
+ },{"../../../maths/vec3":721,"./create":820}],827:[function(require,module,exports){
2862
2862
  const create=require("./create"),reverse=(...e)=>{let r,t;return 1===e.length?(r=create(),t=e[0]):(r=e[0],t=e[1]),r.edges=t.edges.map(e=>[e[1],e[0]]),r};module.exports=reverse;
2863
2863
 
2864
2864
  },{"./create":820}],828:[function(require,module,exports){
@@ -2934,7 +2934,7 @@ const constants=require("../../maths/constants"),vec3=require("../../maths/vec3"
2934
2934
  const aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),createEdges=e=>{const n=poly3.toPoints(e),t=[];for(let e=0;e<n.length;e++){const l=(e+1)%n.length,r={v1:n[e],v2:n[l]};t.push(r)}for(let e=0;e<t.length;e++){const l=(e+1)%n.length;t[e].next=t[l],t[l].prev=t[e]}return t},insertEdge=(e,n)=>{const t=`${n.v1}:${n.v2}`;e.set(t,n)},deleteEdge=(e,n)=>{const t=`${n.v1}:${n.v2}`;e.delete(t)},findOppositeEdge=(e,n)=>{const t=`${n.v2}:${n.v1}`;return e.get(t)},calculateAnglesBetween=(e,n,t)=>{let l=e.prev.v1,r=e.prev.v2,o=n.next.v2;const v=calculateAngle(l,r,o,t);return l=n.prev.v1,r=n.prev.v2,o=e.next.v2,[v,calculateAngle(l,r,o,t)]},v1=vec3.create(),v2=vec3.create(),calculateAngle=(e,n,t,l)=>{const r=vec3.subtract(v1,n,e),o=vec3.subtract(v2,t,n);return vec3.cross(r,r,o),vec3.dot(r,l)},createPolygonAnd=e=>{let n;const t=[];for(;e.next;){const n=e.next;t.push(e.v1),e.v1=null,e.v2=null,e.next=null,e.prev=null,e=n}return t.length>0&&(n=poly3.create(t)),n},mergeCoplanarPolygons=e=>{if(e.length<2)return e;const n=e[0].plane,t=e.slice(),l=new Map;for(;t.length>0;){const e=t.shift(),r=createEdges(e);for(let e=0;e<r.length;e++){const t=r[e],o=findOppositeEdge(l,t);if(o){const e=calculateAnglesBetween(t,o,n);if(e[0]>=0&&e[1]>=0){const n=o.next,r=t.next;t.prev.next=o.next,t.next.prev=o.prev,o.prev.next=t.next,o.next.prev=t.prev,t.v1=null,t.v2=null,t.next=null,t.prev=null,deleteEdge(l,o),o.v1=null,o.v2=null,o.next=null,o.prev=null;const v=(e,n,t)=>{const l={v1:t.v1,v2:n.v2,next:n.next,prev:t.prev};t.prev.next=l,n.next.prev=l,deleteEdge(e,n),n.v1=null,n.v2=null,n.next=null,n.prev=null,deleteEdge(e,t),t.v1=null,t.v2=null,t.next=null,t.prev=null};0===e[0]&&v(l,n,n.prev),0===e[1]&&v(l,r,r.prev)}}else t.next&&insertEdge(l,t)}}const r=[];return l.forEach(e=>{const n=createPolygonAnd(e);n&&r.push(n)}),l.clear(),r},coplanar=(e,n)=>Math.abs(e[3]-n[3])<1.5e-7&&aboutEqualNormals(e,n),mergePolygons=(e,n)=>{const t=[];n.forEach(e=>{const n=t.find(n=>coplanar(n[0],poly3.plane(e)));if(n){n[1].push(e)}else t.push([poly3.plane(e),[e]])});let l=[];return t.forEach(e=>{const n=e[1],t=mergeCoplanarPolygons(n);l=l.concat(t)}),l};module.exports=mergePolygons;
2935
2935
 
2936
2936
  },{"../../geometries/poly3":579,"../../maths/utils/aboutEqualNormals":667,"../../maths/vec3":721}],852:[function(require,module,exports){
2937
- const{EPS:EPS}=require("../../maths/constants"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),OrthoNormalBasis=require("../../maths/OrthoNormalBasis"),interpolateBetween2DPointsForY=require("../../maths/utils/interpolateBetween2DPointsForY"),{insertSorted:insertSorted,fnNumberSort:fnNumberSort}=require("../../utils"),poly3=require("../../geometries/poly3"),reTesselateCoplanarPolygons=t=>{if(t.length<2)return t;const e=[],o=t.length,n=poly3.plane(t[0]),l=new OrthoNormalBasis(n),i=[],r=[],s={},f={},p={},h=10/EPS;for(let e=0;e<o;e++){const o=t[e];let n=[],c=o.vertices.length,g=-1;if(c>0){let t,i;for(let r=0;r<c;r++){let s=l.to2D(o.vertices[r]);const c=Math.floor(s[1]*h);let a;c in p?a=p[c]:c+1 in p?a=p[c+1]:c-1 in p?a=p[c-1]:(a=s[1],p[c]=s[1]),s=vec2.fromValues(s[0],a),n.push(s);const u=s[1];(0===r||u<t)&&(t=u,g=r),(0===r||u>i)&&(i=u),u in f||(f[u]={}),f[u][e]=!0}t>=i?(n=[],c=0,g=-1):(t in s||(s[t]=[]),s[t].push(e))}n.reverse(),g=c-g-1,i.push(n),r.push(g)}const c=[];for(const t in f)c.push(t);c.sort(fnNumberSort);let g=[],a=[];for(let t=0;t<c.length;t++){const o=[],p=c[t],h=Number(p),u=f[p];for(let t=0;t<g.length;++t){const e=g[t],o=e.polygonindex;if(u[o]){const n=i[o],l=n.length;let r=e.leftvertexindex,s=e.rightvertexindex;for(;;){let t=r+1;if(t>=l&&(t=0),n[t][1]!==h)break;r=t}let f=s-1;if(f<0&&(f=l-1),n[f][1]===h&&(s=f),r!==e.leftvertexindex&&r===s)g.splice(t,1),--t;else{e.leftvertexindex=r,e.rightvertexindex=s,e.topleft=n[r],e.topright=n[s];let t=r+1;t>=l&&(t=0),e.bottomleft=n[t];let o=s-1;o<0&&(o=l-1),e.bottomright=n[o]}}}let m;if(t>=c.length-1)g=[],m=null;else{const e=.5*(h+(m=Number(c[t+1]))),o=s[p];for(const t in o){const n=o[t],l=i[n],s=l.length,f=r[n];let p=f;for(;;){let t=p+1;if(t>=s&&(t=0),l[t][1]!==h)break;if(t===f)break;p=t}let c=f;for(;;){let t=c-1;if(t<0&&(t=s-1),l[t][1]!==h)break;if(t===p)break;c=t}let a=p+1;a>=s&&(a=0);let u=c-1;u<0&&(u=s-1);const m={polygonindex:n,leftvertexindex:p,rightvertexindex:c,topleft:l[p],topright:l[c],bottomleft:l[a],bottomright:l[u]};insertSorted(g,m,(t,o)=>{const n=interpolateBetween2DPointsForY(t.topleft,t.bottomleft,e),l=interpolateBetween2DPointsForY(o.topleft,o.bottomleft,e);return n>l?1:n<l?-1:0})}}for(const t in g){const e=g[t];let n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,h);const l=vec2.fromValues(n,h);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,h);const i=vec2.fromValues(n,h);n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,m);const r=vec2.fromValues(n,m);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,m);const s=vec2.fromValues(n,m),f={topleft:l,topright:i,bottomleft:r,bottomright:s,leftline:line2.fromPoints(line2.create(),l,r),rightline:line2.fromPoints(line2.create(),s,i)};if(o.length>0){const t=o[o.length-1],e=vec2.distance(f.topleft,t.topright),n=vec2.distance(f.bottomleft,t.bottomright);e<EPS&&n<EPS&&(f.topleft=t.topleft,f.leftline=t.leftline,f.bottomleft=t.bottomleft,o.splice(o.length-1,1))}o.push(f)}if(t>0){const t={},i={};for(let e=0;e<o.length;e++){const n=o[e];for(let e=0;e<a.length;e++)if(!i[e]){const o=a[e];if(vec2.distance(o.bottomleft,n.topleft)<EPS&&vec2.distance(o.bottomright,n.topright)<EPS){i[e]=!0;const l=line2.direction(n.leftline),r=line2.direction(o.leftline),s=l[0]-r[0],f=line2.direction(n.rightline),p=line2.direction(o.rightline),h=f[0]-p[0],c=Math.abs(s)<EPS,g=Math.abs(h)<EPS,a=g||h>=0;(c||s>=0)&&a&&(n.outpolygon=o.outpolygon,n.leftlinecontinues=c,n.rightlinecontinues=g,t[e]=!0);break}}}for(let o=0;o<a.length;o++)if(!t[o]){const t=a[o];t.outpolygon.rightpoints.push(t.bottomright),vec2.distance(t.bottomright,t.bottomleft)>EPS&&t.outpolygon.leftpoints.push(t.bottomleft),t.outpolygon.leftpoints.reverse();const i=t.outpolygon.rightpoints.concat(t.outpolygon.leftpoints).map(t=>l.to3D(t)),r=poly3.fromPointsAndPlane(i,n);r.vertices.length&&e.push(r)}}for(let t=0;t<o.length;t++){const e=o[t];e.outpolygon?(e.leftlinecontinues||e.outpolygon.leftpoints.push(e.topleft),e.rightlinecontinues||e.outpolygon.rightpoints.push(e.topright)):(e.outpolygon={leftpoints:[],rightpoints:[]},e.outpolygon.leftpoints.push(e.topleft),vec2.distance(e.topleft,e.topright)>EPS&&e.outpolygon.rightpoints.push(e.topright))}a=o}return e};module.exports=reTesselateCoplanarPolygons;
2937
+ const{EPS:EPS}=require("../../maths/constants"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),OrthoNormalBasis=require("../../maths/OrthoNormalBasis"),interpolateBetween2DPointsForY=require("../../maths/utils/interpolateBetween2DPointsForY"),{insertSorted:insertSorted,fnNumberSort:fnNumberSort}=require("../../utils"),poly3=require("../../geometries/poly3"),reTesselateCoplanarPolygons=t=>{if(t.length<2)return t;const e=[],o=t.length,n=poly3.plane(t[0]),l=new OrthoNormalBasis(n),i=[],r=[],s=new Map,f=new Map,p=new Map,h=10/EPS;for(let e=0;e<o;e++){const o=t[e];let n=[],g=o.vertices.length,c=-1;if(g>0){let t,i;for(let r=0;r<g;r++){let s=l.to2D(o.vertices[r]);const g=Math.floor(s[1]*h);let a;p.has(g)?a=p.get(g):p.has(g+1)?a=p.get(g+1):p.has(g-1)?a=p.get(g-1):(a=s[1],p.set(g,s[1])),s=vec2.fromValues(s[0],a),n.push(s);const u=s[1];(0===r||u<t)&&(t=u,c=r),(0===r||u>i)&&(i=u);let m=f.get(u);m||(m={},f.set(u,m)),m[e]=!0}if(t>=i)n=[],g=0,c=-1;else{let o=s.get(t);o||(o=[],s.set(t,o)),o.push(e)}}n.reverse(),c=g-c-1,i.push(n),r.push(c)}const g=[];f.forEach((t,e)=>g.push(e)),g.sort(fnNumberSort);let c=[],a=[];for(let t=0;t<g.length;t++){const o=[],p=g[t],h=f.get(p);for(let t=0;t<c.length;++t){const e=c[t],o=e.polygonindex;if(h[o]){const n=i[o],l=n.length;let r=e.leftvertexindex,s=e.rightvertexindex;for(;;){let t=r+1;if(t>=l&&(t=0),n[t][1]!==p)break;r=t}let f=s-1;if(f<0&&(f=l-1),n[f][1]===p&&(s=f),r!==e.leftvertexindex&&r===s)c.splice(t,1),--t;else{e.leftvertexindex=r,e.rightvertexindex=s,e.topleft=n[r],e.topright=n[s];let t=r+1;t>=l&&(t=0),e.bottomleft=n[t];let o=s-1;o<0&&(o=l-1),e.bottomright=n[o]}}}let u;if(t>=g.length-1)c=[],u=null;else{const e=.5*(p+(u=Number(g[t+1]))),o=s.get(p);for(const t in o){const n=o[t],l=i[n],s=l.length,f=r[n];let h=f;for(;;){let t=h+1;if(t>=s&&(t=0),l[t][1]!==p)break;if(t===f)break;h=t}let g=f;for(;;){let t=g-1;if(t<0&&(t=s-1),l[t][1]!==p)break;if(t===h)break;g=t}let a=h+1;a>=s&&(a=0);let u=g-1;u<0&&(u=s-1);const m={polygonindex:n,leftvertexindex:h,rightvertexindex:g,topleft:l[h],topright:l[g],bottomleft:l[a],bottomright:l[u]};insertSorted(c,m,(t,o)=>{const n=interpolateBetween2DPointsForY(t.topleft,t.bottomleft,e),l=interpolateBetween2DPointsForY(o.topleft,o.bottomleft,e);return n>l?1:n<l?-1:0})}}for(const t in c){const e=c[t];let n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,p);const l=vec2.fromValues(n,p);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,p);const i=vec2.fromValues(n,p);n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,u);const r=vec2.fromValues(n,u);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,u);const s=vec2.fromValues(n,u),f={topleft:l,topright:i,bottomleft:r,bottomright:s,leftline:line2.fromPoints(line2.create(),l,r),rightline:line2.fromPoints(line2.create(),s,i)};if(o.length>0){const t=o[o.length-1],e=vec2.distance(f.topleft,t.topright),n=vec2.distance(f.bottomleft,t.bottomright);e<EPS&&n<EPS&&(f.topleft=t.topleft,f.leftline=t.leftline,f.bottomleft=t.bottomleft,o.splice(o.length-1,1))}o.push(f)}if(t>0){const t=new Set,i=new Set;for(let e=0;e<o.length;e++){const n=o[e];for(let e=0;e<a.length;e++)if(!i.has(e)){const o=a[e];if(vec2.distance(o.bottomleft,n.topleft)<EPS&&vec2.distance(o.bottomright,n.topright)<EPS){i.add(e);const l=line2.direction(n.leftline),r=line2.direction(o.leftline),s=l[0]-r[0],f=line2.direction(n.rightline),p=line2.direction(o.rightline),h=f[0]-p[0],g=Math.abs(s)<EPS,c=Math.abs(h)<EPS,a=c||h>=0;(g||s>=0)&&a&&(n.outpolygon=o.outpolygon,n.leftlinecontinues=g,n.rightlinecontinues=c,t.add(e));break}}}for(let o=0;o<a.length;o++)if(!t.has(o)){const t=a[o];t.outpolygon.rightpoints.push(t.bottomright),vec2.distance(t.bottomright,t.bottomleft)>EPS&&t.outpolygon.leftpoints.push(t.bottomleft),t.outpolygon.leftpoints.reverse();const i=t.outpolygon.rightpoints.concat(t.outpolygon.leftpoints).map(t=>l.to3D(t)),r=poly3.fromPointsAndPlane(i,n);r.vertices.length&&e.push(r)}}for(let t=0;t<o.length;t++){const e=o[t];e.outpolygon?(e.leftlinecontinues||e.outpolygon.leftpoints.push(e.topleft),e.rightlinecontinues||e.outpolygon.rightpoints.push(e.topright)):(e.outpolygon={leftpoints:[],rightpoints:[]},e.outpolygon.leftpoints.push(e.topleft),vec2.distance(e.topleft,e.topright)>EPS&&e.outpolygon.rightpoints.push(e.topright))}a=o}return e};module.exports=reTesselateCoplanarPolygons;
2938
2938
 
2939
2939
  },{"../../geometries/poly3":579,"../../maths/OrthoNormalBasis":593,"../../maths/constants":594,"../../maths/line2":605,"../../maths/utils/interpolateBetween2DPointsForY":670,"../../maths/vec2":690,"../../utils":897}],853:[function(require,module,exports){
2940
2940
  const geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),reTesselateCoplanarPolygons=require("./reTesselateCoplanarPolygons"),coplanar=(e,o)=>Math.abs(e[3]-o[3])<1.5e-7&&aboutEqualNormals(e,o),retessellate=e=>{if(e.isRetesselated)return e;const o=geom3.toPolygons(e),s=[];o.forEach(e=>{const o=s.find(o=>coplanar(o[0],poly3.plane(e)));if(o){o[1].push(e)}else s.push([poly3.plane(e),[e]])});let a=[];s.forEach(e=>{const o=e[1],s=reTesselateCoplanarPolygons(o);a=a.concat(s)});const l=geom3.create(a);return l.isRetesselated=!0,l};module.exports=retessellate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/core",
3
- "version": "2.5.9",
3
+ "version": "2.6.0",
4
4
  "description": "Core functionality for JSCAD Applications",
5
5
  "homepage": "https://openjscad.xyz/",
6
6
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -36,9 +36,9 @@
36
36
  "license": "MIT",
37
37
  "dependencies": {
38
38
  "@jscad/array-utils": "2.1.4",
39
- "@jscad/io": "2.3.2",
40
- "@jscad/io-utils": "2.0.18",
41
- "@jscad/modeling": "2.9.3",
39
+ "@jscad/io": "2.3.3",
40
+ "@jscad/io-utils": "2.0.19",
41
+ "@jscad/modeling": "2.9.4",
42
42
  "json5": "2.2.0",
43
43
  "strip-bom": "4.0.0"
44
44
  },
@@ -53,5 +53,5 @@
53
53
  "url": "https://opencollective.com/openjscad",
54
54
  "logo": "https://opencollective.com/openjscad/logo.txt"
55
55
  },
56
- "gitHead": "85fa1fcdfb2d516a201ecf31da242e64b5b3274e"
56
+ "gitHead": "662965f40a1ce628aa97f30b814586e72a3acb36"
57
57
  }
@@ -17,9 +17,12 @@ const applyParameterDefinitions = require('../parameters/applyParameterDefinitio
17
17
  * @param {Object} [data.parameterValues] - over-rides of parameter values (optional)
18
18
  * @param {Function} callback - function to process parameters and solids
19
19
  * @return NONE
20
+ *
20
21
  * This function extracts the parameters first, and then generates the solids.
21
22
  * The parsed parameters (definitions and values) are passed back to the given callback function.
22
23
  * The generated solids are also passed back to the given callback function.
24
+ * Also, all errors are caught and passed back to the given callback function.
25
+ *
23
26
  * Everything is together in a single function, because this is usually run in the context of a web worker
24
27
  * And transfering data back & forth is both complex (see transferables) and costly (time)
25
28
  **/
@@ -34,37 +37,51 @@ const rebuildSolids = (data, callback) => {
34
37
  }
35
38
  let { mainPath, apiMainPath, serialize, lookup, lookupCounts, parameterValues } = Object.assign({}, defaults, data)
36
39
 
37
- const filesAndFolders = data.filesAndFolders
40
+ try {
41
+ const filesAndFolders = data.filesAndFolders
38
42
 
39
- // let start = new Date()
40
- const designData = loadDesign(mainPath, apiMainPath, filesAndFolders, parameterValues)
41
- // send back parameter definitions & values
42
- // in a worker this would be a postmessage, this is sent back early so that uis can update
43
- // the parameters editor before the solids are displayed (which takes longer)
44
- callback(null, {
45
- type: 'params',
46
- parameterDefaults: designData.parameterValues,
47
- parameterDefinitions: designData.parameterDefinitions
48
- })
49
- // make sure parameters are correct by applying parameter definitions
50
- // this might be redundant with ui-side logic, but it makes sure this core piece works regardless of ui
51
- parameterValues = applyParameterDefinitions(parameterValues, designData.parameterDefinitions)
52
- parameterValues = Object.assign({}, designData.parameterValues, parameterValues)
53
- // start = new Date()
54
- const options = {
55
- lookup,
56
- lookupCounts,
57
- serialize
58
- }
59
- const solidsData = instanciateDesign(designData.rootModule, parameterValues, options)
43
+ // let start = new Date()
44
+ const designData = loadDesign(mainPath, apiMainPath, filesAndFolders, parameterValues)
45
+ // send back parameter definitions & values
46
+ // in a worker this would be a postmessage, this is sent back early so that uis can update
47
+ // the parameters editor before the solids are displayed (which takes longer)
48
+ callback(null, {
49
+ type: 'params',
50
+ parameterDefaults: designData.parameterValues,
51
+ parameterDefinitions: designData.parameterDefinitions
52
+ })
53
+ // make sure parameters are correct by applying parameter definitions
54
+ // this might be redundant with ui-side logic, but it makes sure this core piece works regardless of ui
55
+ parameterValues = applyParameterDefinitions(parameterValues, designData.parameterDefinitions)
56
+ parameterValues = Object.assign({}, designData.parameterValues, parameterValues)
57
+ // start = new Date()
58
+ const options = {
59
+ lookup,
60
+ lookupCounts,
61
+ serialize
62
+ }
63
+ const solidsData = instanciateDesign(designData.rootModule, parameterValues, options)
60
64
 
61
- // send back solids & any other metadata
62
- callback(null, {
63
- type: 'solids',
64
- solids: solidsData.solids,
65
- lookup: solidsData.lookup,
66
- lookupCounts: solidsData.lookupCounts
67
- })
65
+ // send back solids & any other metadata
66
+ callback(null, {
67
+ type: 'solids',
68
+ solids: solidsData.solids,
69
+ lookup: solidsData.lookup,
70
+ lookupCounts: solidsData.lookupCounts
71
+ })
72
+ } catch (error) {
73
+ callback({
74
+ type: 'errors',
75
+ name: error.name ? error.name : 'Error',
76
+ message: error.message ? error.message : error.toString(),
77
+ description: error.description ? error.description : '',
78
+ number: error.number ? error.number : '',
79
+ fileName: error.fileName ? error.fileName : '',
80
+ lineNumber: error.lineNumber ? error.lineNumber : '',
81
+ columnNumber: error.columnNumber ? error.columnNumber : '',
82
+ stack: error.stack ? error.stack : ''
83
+ }, null)
84
+ }
68
85
  }
69
86
 
70
87
  module.exports = rebuildSolids
@@ -13,7 +13,10 @@ const rebuildGeometryWorker = (self) => {
13
13
  if (event.data instanceof Object) {
14
14
  const { data } = event
15
15
  if (data.cmd === 'generate') {
16
- rebuildGeometry(data, (err, message) => self.postMessage(message))
16
+ rebuildGeometry(data, (error, message) => {
17
+ if (message) self.postMessage(message)
18
+ if (error) self.postMessage(error)
19
+ })
17
20
  }
18
21
  }
19
22
  }
@@ -111,15 +111,31 @@ const makeWebRequire = (filesAndFolders, options) => {
111
111
  const matchingModule = {
112
112
  exports: {},
113
113
  _compile: (content, fileName) => {
114
- const moduleMakerFunction = new Function('require', 'module', content) // eslint-disable-line no-new-func
115
- moduleMakerFunction(_require.bind(null, entry.fullPath), matchingModule)
114
+ try {
115
+ const moduleMakerFunction = new Function('require', 'module', content) // eslint-disable-line no-new-func
116
+ moduleMakerFunction(_require.bind(null, entry.fullPath), matchingModule)
117
+ } catch (e) {
118
+ // catch errors and build a context specific error, with file name and stack trace
119
+ // the stack trace mimics the style of nodejs
120
+ const message = e.message
121
+ fileName = fileName.replace('/', '')
122
+ // NOTE: only firefox provides line and column numbers
123
+ const lineNumber = e.lineNumber ? e.lineNumber - 2 : 0 // the call to Function (above) adds two lines
124
+ const columnNumber = e.columnNumber ? e.columnNumber : 0
125
+ if (e.stack.startsWith('Object')) {
126
+ e.stack = `${e.stack}\nObject.<anonymous> (${fileName}:${lineNumber}:${columnNumber})`
127
+ } else {
128
+ e = new SyntaxError(message, fileName, lineNumber)
129
+ e.columnNumber = columnNumber
130
+ e.stack = `Object.<anonymous> (${fileName}:${lineNumber}:${columnNumber})`
131
+ }
132
+ throw e
133
+ }
116
134
 
117
135
  const paramDefFromSource = content.includes('@jscad-params') ? getParameterDefinitionsFromSource(content, fileName) : []
118
136
  const originalFunc = matchingModule.exports.getParameterDefinitions
119
137
  // replace getParameterDefinitions in the module, with version taht adds parsed definitions
120
138
  matchingModule.exports.getParameterDefinitions = () => combineParameterDefinitions(paramDefFromSource, originalFunc ? originalFunc() || [] : [])
121
- // add to core to resolve later references
122
- // FIXME coreModules[entry.fullPath] = matchingModule.exports
123
139
  }
124
140
  }
125
141
  extensions[baseExt](matchingModule, entry.fullPath)