@jscad/modeling 2.12.2 → 2.12.3

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,20 @@
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.12.3](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/modeling@2.12.2...@jscad/modeling@2.12.3) (2024-10-06)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **modeling:** added optional plane to poly3 TS definition ([2a3337a](https://github.com/jscad/OpenJSCAD.org/commit/2a3337a4b6d06d9072cb7f193eb0ef8de446c8c0))
12
+ * **modeling:** corrected hull of single unconvex solid ([b3901f2](https://github.com/jscad/OpenJSCAD.org/commit/b3901f2b61a64a82a687f6f6062f15a20d35611b))
13
+ * **modeling:** corrected TS definition of scission ([ad3d37d](https://github.com/jscad/OpenJSCAD.org/commit/ad3d37d32c308e99141d9ff0d8965e4d1d166123))
14
+ * **modeling:** expose hullPoints2 and hullPoints3 ([01ceae8](https://github.com/jscad/OpenJSCAD.org/commit/01ceae89570dcaf40f9676aadd4ced515e41c291))
15
+
16
+
17
+
18
+
19
+
6
20
  ## [2.12.2](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/modeling@2.12.1...@jscad/modeling@2.12.2) (2024-06-02)
7
21
 
8
22
 
@@ -4,7 +4,7 @@ const cssColors=require("./cssColors"),colorNameToRgb=o=>cssColors[o.toLowerCase
4
4
  },{"./cssColors":3}],2:[function(require,module,exports){
5
5
  const flatten=require("../utils/flatten"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),colorGeom2=(o,r)=>{const e=geom2.clone(r);return e.color=o,e},colorGeom3=(o,r)=>{const e=geom3.clone(r);return e.color=o,e},colorPath2=(o,r)=>{const e=path2.clone(r);return e.color=o,e},colorPoly3=(o,r)=>{const e=poly3.clone(r);return e.color=o,e},colorize=(o,...r)=>{if(!Array.isArray(o))throw new Error("color must be an array");if(o.length<3)throw new Error("color must contain R, G and B values");if(3===o.length&&(o=[o[0],o[1],o[2],1]),0===(r=flatten(r)).length)throw new Error("wrong number of arguments");const e=r.map(r=>geom2.isA(r)?colorGeom2(o,r):geom3.isA(r)?colorGeom3(o,r):path2.isA(r)?colorPath2(o,r):poly3.isA(r)?colorPoly3(o,r):(r.color=o,r));return 1===e.length?e[0]:e};module.exports=colorize;
6
6
 
7
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":397}],3:[function(require,module,exports){
7
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":398}],3:[function(require,module,exports){
8
8
  const cssColors={black:[0,0,0],silver:[192/255,192/255,192/255],gray:[128/255,128/255,128/255],white:[1,1,1],maroon:[128/255,0,0],red:[1,0,0],purple:[128/255,0,128/255],fuchsia:[1,0,1],green:[0,128/255,0],lime:[0,1,0],olive:[128/255,128/255,0],yellow:[1,1,0],navy:[0,0,128/255],blue:[0,0,1],teal:[0,128/255,128/255],aqua:[0,1,1],aliceblue:[240/255,248/255,1],antiquewhite:[250/255,235/255,215/255],aquamarine:[127/255,1,212/255],azure:[240/255,1,1],beige:[245/255,245/255,220/255],bisque:[1,228/255,196/255],blanchedalmond:[1,235/255,205/255],blueviolet:[138/255,43/255,226/255],brown:[165/255,42/255,42/255],burlywood:[222/255,184/255,135/255],cadetblue:[95/255,158/255,160/255],chartreuse:[127/255,1,0],chocolate:[210/255,105/255,30/255],coral:[1,127/255,80/255],cornflowerblue:[100/255,149/255,237/255],cornsilk:[1,248/255,220/255],crimson:[220/255,20/255,60/255],cyan:[0,1,1],darkblue:[0,0,139/255],darkcyan:[0,139/255,139/255],darkgoldenrod:[184/255,134/255,11/255],darkgray:[169/255,169/255,169/255],darkgreen:[0,100/255,0],darkgrey:[169/255,169/255,169/255],darkkhaki:[189/255,183/255,107/255],darkmagenta:[139/255,0,139/255],darkolivegreen:[85/255,107/255,47/255],darkorange:[1,140/255,0],darkorchid:[.6,50/255,.8],darkred:[139/255,0,0],darksalmon:[233/255,150/255,122/255],darkseagreen:[143/255,188/255,143/255],darkslateblue:[72/255,61/255,139/255],darkslategray:[47/255,79/255,79/255],darkslategrey:[47/255,79/255,79/255],darkturquoise:[0,206/255,209/255],darkviolet:[148/255,0,211/255],deeppink:[1,20/255,147/255],deepskyblue:[0,191/255,1],dimgray:[105/255,105/255,105/255],dimgrey:[105/255,105/255,105/255],dodgerblue:[30/255,144/255,1],firebrick:[178/255,34/255,34/255],floralwhite:[1,250/255,240/255],forestgreen:[34/255,139/255,34/255],gainsboro:[220/255,220/255,220/255],ghostwhite:[248/255,248/255,1],gold:[1,215/255,0],goldenrod:[218/255,165/255,32/255],greenyellow:[173/255,1,47/255],grey:[128/255,128/255,128/255],honeydew:[240/255,1,240/255],hotpink:[1,105/255,180/255],indianred:[205/255,92/255,92/255],indigo:[75/255,0,130/255],ivory:[1,1,240/255],khaki:[240/255,230/255,140/255],lavender:[230/255,230/255,250/255],lavenderblush:[1,240/255,245/255],lawngreen:[124/255,252/255,0],lemonchiffon:[1,250/255,205/255],lightblue:[173/255,216/255,230/255],lightcoral:[240/255,128/255,128/255],lightcyan:[224/255,1,1],lightgoldenrodyellow:[250/255,250/255,210/255],lightgray:[211/255,211/255,211/255],lightgreen:[144/255,238/255,144/255],lightgrey:[211/255,211/255,211/255],lightpink:[1,182/255,193/255],lightsalmon:[1,160/255,122/255],lightseagreen:[32/255,178/255,170/255],lightskyblue:[135/255,206/255,250/255],lightslategray:[119/255,136/255,.6],lightslategrey:[119/255,136/255,.6],lightsteelblue:[176/255,196/255,222/255],lightyellow:[1,1,224/255],limegreen:[50/255,205/255,50/255],linen:[250/255,240/255,230/255],magenta:[1,0,1],mediumaquamarine:[.4,205/255,170/255],mediumblue:[0,0,205/255],mediumorchid:[186/255,85/255,211/255],mediumpurple:[147/255,112/255,219/255],mediumseagreen:[60/255,179/255,113/255],mediumslateblue:[123/255,104/255,238/255],mediumspringgreen:[0,250/255,154/255],mediumturquoise:[72/255,209/255,.8],mediumvioletred:[199/255,21/255,133/255],midnightblue:[25/255,25/255,112/255],mintcream:[245/255,1,250/255],mistyrose:[1,228/255,225/255],moccasin:[1,228/255,181/255],navajowhite:[1,222/255,173/255],oldlace:[253/255,245/255,230/255],olivedrab:[107/255,142/255,35/255],orange:[1,165/255,0],orangered:[1,69/255,0],orchid:[218/255,112/255,214/255],palegoldenrod:[238/255,232/255,170/255],palegreen:[152/255,251/255,152/255],paleturquoise:[175/255,238/255,238/255],palevioletred:[219/255,112/255,147/255],papayawhip:[1,239/255,213/255],peachpuff:[1,218/255,185/255],peru:[205/255,133/255,63/255],pink:[1,192/255,203/255],plum:[221/255,160/255,221/255],powderblue:[176/255,224/255,230/255],rosybrown:[188/255,143/255,143/255],royalblue:[65/255,105/255,225/255],saddlebrown:[139/255,69/255,19/255],salmon:[250/255,128/255,114/255],sandybrown:[244/255,164/255,96/255],seagreen:[46/255,139/255,87/255],seashell:[1,245/255,238/255],sienna:[160/255,82/255,45/255],skyblue:[135/255,206/255,235/255],slateblue:[106/255,90/255,205/255],slategray:[112/255,128/255,144/255],slategrey:[112/255,128/255,144/255],snow:[1,250/255,250/255],springgreen:[0,1,127/255],steelblue:[70/255,130/255,180/255],tan:[210/255,180/255,140/255],thistle:[216/255,191/255,216/255],tomato:[1,99/255,71/255],turquoise:[64/255,224/255,208/255],violet:[238/255,130/255,238/255],wheat:[245/255,222/255,179/255],whitesmoke:[245/255,245/255,245/255],yellowgreen:[154/255,205/255,50/255]};module.exports=cssColors;
9
9
 
10
10
  },{}],4:[function(require,module,exports){
@@ -13,10 +13,10 @@ const hexToRgb=t=>{if((t=t.replace("#","")).length<6)throw new Error("the given
13
13
  },{}],5:[function(require,module,exports){
14
14
  const flatten=require("../utils/flatten"),hueToColorComponent=require("./hueToColorComponent"),hslToRgb=(...o)=>{if((o=flatten(o)).length<3)throw new Error("values must contain H, S and L values");const e=o[0],n=o[1],t=o[2];let r=t,l=t,u=t;if(0!==n){const o=t<.5?t*(1+n):t+n-t*n,h=2*t-o;r=hueToColorComponent(h,o,e+1/3),l=hueToColorComponent(h,o,e),u=hueToColorComponent(h,o,e-1/3)}if(o.length>3){return[r,l,u,o[3]]}return[r,l,u]};module.exports=hslToRgb;
15
15
 
16
- },{"../utils/flatten":397,"./hueToColorComponent":7}],6:[function(require,module,exports){
16
+ },{"../utils/flatten":398,"./hueToColorComponent":7}],6:[function(require,module,exports){
17
17
  const flatten=require("../utils/flatten"),hsvToRgb=(...e)=>{if((e=flatten(e)).length<3)throw new Error("values must contain H, S and V values");const t=e[0],a=e[1],r=e[2];let s=0,n=0,o=0;const c=Math.floor(6*t),l=6*t-c,u=r*(1-a),b=r*(1-l*a),h=r*(1-(1-l)*a);switch(c%6){case 0:s=r,n=h,o=u;break;case 1:s=b,n=r,o=u;break;case 2:s=u,n=r,o=h;break;case 3:s=u,n=b,o=r;break;case 4:s=h,n=u,o=r;break;case 5:s=r,n=u,o=b}if(e.length>3){return[s,n,o,e[3]]}return[s,n,o]};module.exports=hsvToRgb;
18
18
 
19
- },{"../utils/flatten":397}],7:[function(require,module,exports){
19
+ },{"../utils/flatten":398}],7:[function(require,module,exports){
20
20
  const hueToColorComponent=(o,e,n)=>(n<0&&(n+=1),n>1&&(n-=1),n<1/6?o+6*(e-o)*n:n<.5?e:n<2/3?o+(e-o)*(2/3-n)*6:o);module.exports=hueToColorComponent;
21
21
 
22
22
  },{}],8:[function(require,module,exports){
@@ -25,13 +25,13 @@ module.exports={colorize:require("./colorize"),colorNameToRgb:require("./colorNa
25
25
  },{"./colorNameToRgb":1,"./colorize":2,"./cssColors":3,"./hexToRgb":4,"./hslToRgb":5,"./hsvToRgb":6,"./hueToColorComponent":7,"./rgbToHex":9,"./rgbToHsl":10,"./rgbToHsv":11}],9:[function(require,module,exports){
26
26
  const flatten=require("../utils/flatten"),rgbToHex=(...t)=>{if((t=flatten(t)).length<3)throw new Error("values must contain R, G and B values");const e=255*t[0],r=255*t[1],n=255*t[2];let o=`#${Number(16777216+65536*e+256*r+n).toString(16).substring(1,7)}`;return t.length>3&&(o+=Number(255*t[3]).toString(16)),o};module.exports=rgbToHex;
27
27
 
28
- },{"../utils/flatten":397}],10:[function(require,module,exports){
28
+ },{"../utils/flatten":398}],10:[function(require,module,exports){
29
29
  const flatten=require("../utils/flatten"),rgbToHsl=(...t)=>{if((t=flatten(t)).length<3)throw new Error("values must contain R, G and B values");const e=t[0],n=t[1],s=t[2],a=Math.max(e,n,s),r=Math.min(e,n,s);let l,o;const c=(a+r)/2;if(a===r)l=o=0;else{const t=a-r;switch(o=c>.5?t/(2-a-r):t/(a+r),a){case e:l=(n-s)/t+(n<s?6:0);break;case n:l=(s-e)/t+2;break;case s:l=(e-n)/t+4}l/=6}if(t.length>3){return[l,o,c,t[3]]}return[l,o,c]};module.exports=rgbToHsl;
30
30
 
31
- },{"../utils/flatten":397}],11:[function(require,module,exports){
31
+ },{"../utils/flatten":398}],11:[function(require,module,exports){
32
32
  const flatten=require("../utils/flatten"),rgbToHsv=(...e)=>{if((e=flatten(e)).length<3)throw new Error("values must contain R, G and B values");const t=e[0],a=e[1],n=e[2],r=Math.max(t,a,n),s=Math.min(t,a,n);let l;const o=r,c=r-s,i=0===r?0:c/r;if(r===s)l=0;else{switch(r){case t:l=(a-n)/c+(a<n?6:0);break;case a:l=(n-t)/c+2;break;case n:l=(t-a)/c+4}l/=6}if(e.length>3){return[l,i,o,e[3]]}return[l,i,o]};module.exports=rgbToHsv;
33
33
 
34
- },{"../utils/flatten":397}],12:[function(require,module,exports){
34
+ },{"../utils/flatten":398}],12:[function(require,module,exports){
35
35
  const lengths=require("./lengths"),arcLengthToT=(e,t)=>{const{distance:s,segments:n}=Object.assign({},{distance:0,segments:100},e),o=lengths(n,t);let r=0,c=n;for(;r<=c;){const e=Math.floor(r+(c-r)/2),t=o[e]-s;if(t<0)r=e+1;else{if(!(t>0)){c=e;break}c=e-1}}const g=c;if(o[g]===s)return g/n;const a=o[g];return(g+(s-a)/(o[g+1]-a))/n};module.exports=arcLengthToT;
36
36
 
37
37
  },{"./lengths":16}],13:[function(require,module,exports){
@@ -118,7 +118,7 @@ const poly3=require("../poly3"),create=require("./create"),fromPoints=r=>{if(!Ar
118
118
  },{"../poly3":79,"./create":37}],40:[function(require,module,exports){
119
119
  const quickhull=require("../../operations/hulls/quickhull"),create=require("./create"),poly3=require("../poly3"),fromPointsConvex=r=>{if(!Array.isArray(r))throw new Error("the given points must be an array");const e=quickhull(r,{skipTriangulation:!0}).map(e=>{const o=e.map(e=>r[e]);return poly3.create(o)});return create(e)};module.exports=fromPointsConvex;
120
120
 
121
- },{"../../operations/hulls/quickhull":347,"../poly3":79,"./create":37}],41:[function(require,module,exports){
121
+ },{"../../operations/hulls/quickhull":348,"../poly3":79,"./create":37}],41:[function(require,module,exports){
122
122
  module.exports={clone:require("./clone"),create:require("./create"),fromPointsConvex:require("./fromPointsConvex"),fromPoints:require("./fromPoints"),fromCompactBinary:require("./fromCompactBinary"),invert:require("./invert"),isA:require("./isA"),toPoints:require("./toPoints"),toPolygons:require("./toPolygons"),toString:require("./toString"),toCompactBinary:require("./toCompactBinary"),transform:require("./transform"),validate:require("./validate")};
123
123
 
124
124
  },{"./clone":36,"./create":37,"./fromCompactBinary":38,"./fromPoints":39,"./fromPointsConvex":40,"./invert":42,"./isA":43,"./toCompactBinary":44,"./toPoints":45,"./toPolygons":46,"./toString":47,"./transform":48,"./validate":49}],42:[function(require,module,exports){
@@ -274,7 +274,7 @@ const signedDistanceToPoint=require("../../maths/plane/signedDistanceToPoint"),{
274
274
  },{"../../maths/constants":94,"../../maths/plane/signedDistanceToPoint":165,"../../maths/vec3":222,"./isA":81,"./isConvex":82,"./measureArea":83,"./plane":87}],92:[function(require,module,exports){
275
275
  module.exports={colors:require("./colors"),curves:require("./curves"),geometries:require("./geometries"),maths:require("./maths"),measurements:require("./measurements"),primitives:require("./primitives"),text:require("./text"),utils:require("./utils"),booleans:require("./operations/booleans"),expansions:require("./operations/expansions"),extrusions:require("./operations/extrusions"),hulls:require("./operations/hulls"),modifiers:require("./operations/modifiers"),transforms:require("./operations/transforms")};
276
276
 
277
- },{"./colors":8,"./curves":19,"./geometries":50,"./maths":95,"./measurements":252,"./operations/booleans":266,"./operations/expansions":295,"./operations/extrusions":318,"./operations/hulls":340,"./operations/modifiers":351,"./operations/transforms":361,"./primitives":377,"./text":391,"./utils":399}],93:[function(require,module,exports){
277
+ },{"./colors":8,"./curves":19,"./geometries":50,"./maths":95,"./measurements":252,"./operations/booleans":266,"./operations/expansions":295,"./operations/extrusions":318,"./operations/hulls":341,"./operations/modifiers":352,"./operations/transforms":362,"./primitives":378,"./text":392,"./utils":400}],93:[function(require,module,exports){
278
278
  const mat4=require("./mat4"),vec2=require("./vec2"),vec3=require("./vec3"),OrthoNormalBasis=function(e,t){arguments.length<2&&(t=vec3.orthogonal(vec3.create(),e)),this.v=vec3.normalize(vec3.create(),vec3.cross(vec3.create(),e,t)),this.u=vec3.cross(vec3.create(),this.v,e),this.plane=e,this.planeorigin=vec3.scale(vec3.create(),e,e[3])};OrthoNormalBasis.GetCartesian=function(e,t){const i=e+"/"+t;let s,n;if("X/Y"===i)s=[0,0,1],n=[1,0,0];else if("Y/-X"===i)s=[0,0,1],n=[0,1,0];else if("-X/-Y"===i)s=[0,0,1],n=[-1,0,0];else if("-Y/X"===i)s=[0,0,1],n=[0,-1,0];else if("-X/Y"===i)s=[0,0,-1],n=[-1,0,0];else if("-Y/-X"===i)s=[0,0,-1],n=[0,-1,0];else if("X/-Y"===i)s=[0,0,-1],n=[1,0,0];else if("Y/X"===i)s=[0,0,-1],n=[0,1,0];else if("X/Z"===i)s=[0,-1,0],n=[1,0,0];else if("Z/-X"===i)s=[0,-1,0],n=[0,0,1];else if("-X/-Z"===i)s=[0,-1,0],n=[-1,0,0];else if("-Z/X"===i)s=[0,-1,0],n=[0,0,-1];else if("-X/Z"===i)s=[0,1,0],n=[-1,0,0];else if("-Z/-X"===i)s=[0,1,0],n=[0,0,-1];else if("X/-Z"===i)s=[0,1,0],n=[1,0,0];else if("Z/X"===i)s=[0,1,0],n=[0,0,1];else if("Y/Z"===i)s=[1,0,0],n=[0,1,0];else if("Z/-Y"===i)s=[1,0,0],n=[0,0,1];else if("-Y/-Z"===i)s=[1,0,0],n=[0,-1,0];else if("-Z/Y"===i)s=[1,0,0],n=[0,0,-1];else if("-Y/Z"===i)s=[-1,0,0],n=[0,-1,0];else if("-Z/-Y"===i)s=[-1,0,0],n=[0,0,-1];else if("Y/-Z"===i)s=[-1,0,0],n=[0,1,0];else{if("Z/Y"!==i)throw new Error("OrthoNormalBasis.GetCartesian: invalid combination of axis identifiers. Should pass two string arguments from [X,Y,Z,-X,-Y,-Z], being two different axes.");s=[-1,0,0],n=[0,0,1]}return new OrthoNormalBasis(new Plane(new Vector3D(s),0),new Vector3D(n))},OrthoNormalBasis.Z0Plane=function(){const e=new Plane(new Vector3D([0,0,1]),0);return new OrthoNormalBasis(e,new Vector3D([1,0,0]))},OrthoNormalBasis.prototype={getProjectionMatrix:function(){return mat4.fromValues(this.u[0],this.v[0],this.plane[0],0,this.u[1],this.v[1],this.plane[1],0,this.u[2],this.v[2],this.plane[2],0,0,0,-this.plane[3],1)},getInverseProjectionMatrix:function(){const e=vec3.scale(vec3.create(),this.plane,this.plane[3]);return mat4.fromValues(this.u[0],this.u[1],this.u[2],0,this.v[0],this.v[1],this.v[2],0,this.plane[0],this.plane[1],this.plane[2],0,e[0],e[1],e[2],1)},to2D:function(e){return vec2.fromValues(vec3.dot(e,this.u),vec3.dot(e,this.v))},to3D:function(e){const t=vec3.scale(vec3.create(),this.u,e[0]),i=vec3.scale(vec3.create(),this.v,e[1]),s=vec3.add(t,t,this.planeorigin);return vec3.add(i,i,s)},line3Dto2D:function(e){const t=e.point,i=e.direction.plus(t),s=this.to2D(t),n=this.to2D(i);return Line2D.fromPoints(s,n)},line2Dto3D:function(e){const t=e.origin(),i=e.direction().plus(t),s=this.to3D(t),n=this.to3D(i);return Line3D.fromPoints(s,n)},transform:function(e){const t=this.plane.transform(e),i=this.u.transform(e),s=new Vector3D(0,0,0).transform(e),n=i.minus(s);return new OrthoNormalBasis(t,n)}},module.exports=OrthoNormalBasis;
279
279
 
280
280
  },{"./mat4":143,"./vec2":191,"./vec3":222}],94:[function(require,module,exports){
@@ -757,40 +757,40 @@ module.exports={measureAggregateArea:require("./measureAggregateArea"),measureAg
757
757
  },{"./measureAggregateArea":253,"./measureAggregateBoundingBox":254,"./measureAggregateEpsilon":255,"./measureAggregateVolume":256,"./measureArea":257,"./measureBoundingBox":258,"./measureBoundingSphere":259,"./measureCenter":260,"./measureCenterOfMass":261,"./measureDimensions":262,"./measureEpsilon":263,"./measureVolume":264}],253:[function(require,module,exports){
758
758
  const flatten=require("../utils/flatten"),measureArea=require("./measureArea"),measureAggregateArea=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("measureAggregateArea: no geometries supplied");const r=measureArea(e);if(1===e.length)return r;return r.reduce((e,r)=>e+r,0)};module.exports=measureAggregateArea;
759
759
 
760
- },{"../utils/flatten":397,"./measureArea":257}],254:[function(require,module,exports){
760
+ },{"../utils/flatten":398,"./measureArea":257}],254:[function(require,module,exports){
761
761
  const flatten=require("../utils/flatten"),vec3min=require("../maths/vec3/min"),vec3max=require("../maths/vec3/max"),measureBoundingBox=require("./measureBoundingBox"),measureAggregateBoundingBox=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("measureAggregateBoundingBox: no geometries supplied");const r=measureBoundingBox(e);if(1===e.length)return r;const u=[[Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE],[-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE]];return r.reduce((e,r)=>e=[vec3min(e[0],e[0],r[0]),vec3max(e[1],e[1],r[1])],u)};module.exports=measureAggregateBoundingBox;
762
762
 
763
- },{"../maths/vec3/max":225,"../maths/vec3/min":226,"../utils/flatten":397,"./measureBoundingBox":258}],255:[function(require,module,exports){
763
+ },{"../maths/vec3/max":225,"../maths/vec3/min":226,"../utils/flatten":398,"./measureBoundingBox":258}],255:[function(require,module,exports){
764
764
  const flatten=require("../utils/flatten"),measureAggregateBoundingBox=require("./measureAggregateBoundingBox"),calculateEpsilonFromBounds=require("./calculateEpsilonFromBounds"),{geom2:geom2,geom3:geom3,path2:path2}=require("../geometries"),measureAggregateEpsilon=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("measureAggregateEpsilon: no geometries supplied");const o=measureAggregateBoundingBox(e);let r=0;return r=e.reduce((e,o)=>path2.isA(o)||geom2.isA(o)?Math.max(e,2):geom3.isA(o)?Math.max(e,3):0,r),calculateEpsilonFromBounds(o,r)};module.exports=measureAggregateEpsilon;
765
765
 
766
- },{"../geometries":50,"../utils/flatten":397,"./calculateEpsilonFromBounds":251,"./measureAggregateBoundingBox":254}],256:[function(require,module,exports){
766
+ },{"../geometries":50,"../utils/flatten":398,"./calculateEpsilonFromBounds":251,"./measureAggregateBoundingBox":254}],256:[function(require,module,exports){
767
767
  const flatten=require("../utils/flatten"),measureVolume=require("./measureVolume"),measureAggregateVolume=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("measureAggregateVolume: no geometries supplied");const r=measureVolume(e);if(1===e.length)return r;return r.reduce((e,r)=>e+r,0)};module.exports=measureAggregateVolume;
768
768
 
769
- },{"../utils/flatten":397,"./measureVolume":264}],257:[function(require,module,exports){
769
+ },{"../utils/flatten":398,"./measureVolume":264}],257:[function(require,module,exports){
770
770
  const flatten=require("../utils/flatten"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureAreaOfPath2=()=>0,measureAreaOfGeom2=e=>{let r=cache.get(e);if(r)return r;return r=geom2.toSides(e).reduce((e,r)=>e+(r[0][0]*r[1][1]-r[0][1]*r[1][0]),0),r*=.5,cache.set(e,r),r},measureAreaOfGeom3=e=>{let r=cache.get(e);if(r)return r;return r=geom3.toPolygons(e).reduce((e,r)=>e+poly3.measureArea(r),0),cache.set(e,r),r},measureArea=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const r=e.map(e=>path2.isA(e)?0:geom2.isA(e)?measureAreaOfGeom2(e):geom3.isA(e)?measureAreaOfGeom3(e):0);return 1===r.length?r[0]:r};module.exports=measureArea;
771
771
 
772
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":397}],258:[function(require,module,exports){
772
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":398}],258:[function(require,module,exports){
773
773
  const flatten=require("../utils/flatten"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureBoundingBoxOfPath2=e=>{let o=cache.get(e);if(o)return o;const t=path2.toPoints(e);let n;n=0===t.length?vec2.create():vec2.clone(t[0]);let r=vec2.clone(n);return t.forEach(e=>{vec2.min(n,n,e),vec2.max(r,r,e)}),n=[n[0],n[1],0],r=[r[0],r[1],0],o=[n,r],cache.set(e,o),o},measureBoundingBoxOfGeom2=e=>{let o=cache.get(e);if(o)return o;const t=geom2.toPoints(e);let n;n=0===t.length?vec2.create():vec2.clone(t[0]);let r=vec2.clone(n);return t.forEach(e=>{vec2.min(n,n,e),vec2.max(r,r,e)}),n=[n[0],n[1],0],r=[r[0],r[1],0],o=[n,r],cache.set(e,o),o},measureBoundingBoxOfGeom3=e=>{let o=cache.get(e);if(o)return o;const t=geom3.toPolygons(e);let n=vec3.create();if(t.length>0){const e=poly3.toPoints(t[0]);vec3.copy(n,e[0])}let r=vec3.clone(n);return t.forEach(e=>{poly3.toPoints(e).forEach(e=>{vec3.min(n,n,e),vec3.max(r,r,e)})}),n=[n[0],n[1],n[2]],r=[r[0],r[1],r[2]],o=[n,r],cache.set(e,o),o},measureBoundingBox=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const o=e.map(e=>path2.isA(e)?measureBoundingBoxOfPath2(e):geom2.isA(e)?measureBoundingBoxOfGeom2(e):geom3.isA(e)?measureBoundingBoxOfGeom3(e):[[0,0,0],[0,0,0]]);return 1===o.length?o[0]:o};module.exports=measureBoundingBox;
774
774
 
775
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../maths/vec2":191,"../maths/vec3":222,"../utils/flatten":397}],259:[function(require,module,exports){
775
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../maths/vec2":191,"../maths/vec3":222,"../utils/flatten":398}],259:[function(require,module,exports){
776
776
  const flatten=require("../utils/flatten"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cacheOfBoundingSpheres=new WeakMap,measureBoundingSphereOfPath2=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=path2.toPoints(e);if(c.length>0){let e=0;const t=vec3.create();c.forEach(o=>{vec3.add(r,r,vec3.fromVec2(t,o,0)),e++}),vec3.scale(r,r,1/e),c.forEach(e=>{o=Math.max(o,vec2.squaredDistance(r,e))}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphereOfGeom2=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=geom2.toSides(e);if(c.length>0){let e=0;const t=vec3.create();c.forEach(o=>{vec3.add(r,r,vec3.fromVec2(t,o[0],0)),e++}),vec3.scale(r,r,1/e),c.forEach(e=>{o=Math.max(o,vec2.squaredDistance(r,e[0]))}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphereOfGeom3=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=geom3.toPolygons(e);if(c.length>0){let e=0;c.forEach(t=>{poly3.toPoints(t).forEach(t=>{vec3.add(r,r,t),e++})}),vec3.scale(r,r,1/e),c.forEach(e=>{poly3.toPoints(e).forEach(e=>{o=Math.max(o,vec3.squaredDistance(r,e))})}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphere=(...e)=>{const t=(e=flatten(e)).map(e=>path2.isA(e)?measureBoundingSphereOfPath2(e):geom2.isA(e)?measureBoundingSphereOfGeom2(e):geom3.isA(e)?measureBoundingSphereOfGeom3(e):[[0,0,0],0]);return 1===t.length?t[0]:t};module.exports=measureBoundingSphere;
777
777
 
778
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../maths/vec2":191,"../maths/vec3":222,"../utils/flatten":397}],260:[function(require,module,exports){
778
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../maths/vec2":191,"../maths/vec3":222,"../utils/flatten":398}],260:[function(require,module,exports){
779
779
  const flatten=require("../utils/flatten"),measureBoundingBox=require("./measureBoundingBox"),measureCenter=(...e)=>{const n=(e=flatten(e)).map(e=>{const n=measureBoundingBox(e);return[n[0][0]+(n[1][0]-n[0][0])/2,n[0][1]+(n[1][1]-n[0][1])/2,n[0][2]+(n[1][2]-n[0][2])/2]});return 1===n.length?n[0]:n};module.exports=measureCenter;
780
780
 
781
- },{"../utils/flatten":397,"./measureBoundingBox":258}],261:[function(require,module,exports){
781
+ },{"../utils/flatten":398,"./measureBoundingBox":258}],261:[function(require,module,exports){
782
782
  const flatten=require("../utils/flatten"),vec3=require("../maths/vec3"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),cacheOfCenterOfMass=new WeakMap,measureCenterOfMassGeom2=e=>{let t=cacheOfCenterOfMass.get(e);if(void 0!==t)return t;const s=geom2.toSides(e);let r=0,c=0,a=0;if(s.length>0){for(let e=0;e<s.length;e++){const t=s[e][0],o=s[e][1],n=t[0]*o[1]-t[1]*o[0];r+=n,c+=(t[0]+o[0])*n,a+=(t[1]+o[1])*n}const e=1/(6*(r/=2));c*=e,a*=e}return t=vec3.fromValues(c,a,0),cacheOfCenterOfMass.set(e,t),t},measureCenterOfMassGeom3=e=>{let t=cacheOfCenterOfMass.get(e);if(void 0!==t)return t;t=vec3.create();const s=geom3.toPolygons(e);if(0===s.length)return t;let r=0;const c=vec3.create();return s.forEach(e=>{const s=e.vertices;for(let e=0;e<s.length-2;e++){vec3.cross(c,s[e+1],s[e+2]);const a=vec3.dot(s[0],c)/6;r+=a,vec3.add(c,s[0],s[e+1]),vec3.add(c,c,s[e+2]);const o=vec3.scale(c,c,.25*a);vec3.add(t,t,o)}}),vec3.scale(t,t,1/r),cacheOfCenterOfMass.set(e,t),t},measureCenterOfMass=(...e)=>{const t=(e=flatten(e)).map(e=>geom2.isA(e)?measureCenterOfMassGeom2(e):geom3.isA(e)?measureCenterOfMassGeom3(e):[0,0,0]);return 1===t.length?t[0]:t};module.exports=measureCenterOfMass;
783
783
 
784
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../maths/vec3":222,"../utils/flatten":397}],262:[function(require,module,exports){
784
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../maths/vec3":222,"../utils/flatten":398}],262:[function(require,module,exports){
785
785
  const flatten=require("../utils/flatten"),measureBoundingBox=require("./measureBoundingBox"),measureDimensions=(...e)=>{const n=(e=flatten(e)).map(e=>{const n=measureBoundingBox(e);return[n[1][0]-n[0][0],n[1][1]-n[0][1],n[1][2]-n[0][2]]});return 1===n.length?n[0]:n};module.exports=measureDimensions;
786
786
 
787
- },{"../utils/flatten":397,"./measureBoundingBox":258}],263:[function(require,module,exports){
787
+ },{"../utils/flatten":398,"./measureBoundingBox":258}],263:[function(require,module,exports){
788
788
  const flatten=require("../utils/flatten"),{geom2:geom2,geom3:geom3,path2:path2}=require("../geometries"),calculateEpsilonFromBounds=require("./calculateEpsilonFromBounds"),measureBoundingBox=require("./measureBoundingBox"),measureEpsilonOfPath2=e=>calculateEpsilonFromBounds(measureBoundingBox(e),2),measureEpsilonOfGeom2=e=>calculateEpsilonFromBounds(measureBoundingBox(e),2),measureEpsilonOfGeom3=e=>calculateEpsilonFromBounds(measureBoundingBox(e),3),measureEpsilon=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const o=e.map(e=>path2.isA(e)?measureEpsilonOfPath2(e):geom2.isA(e)?measureEpsilonOfGeom2(e):geom3.isA(e)?measureEpsilonOfGeom3(e):0);return 1===o.length?o[0]:o};module.exports=measureEpsilon;
789
789
 
790
- },{"../geometries":50,"../utils/flatten":397,"./calculateEpsilonFromBounds":251,"./measureBoundingBox":258}],264:[function(require,module,exports){
790
+ },{"../geometries":50,"../utils/flatten":398,"./calculateEpsilonFromBounds":251,"./measureBoundingBox":258}],264:[function(require,module,exports){
791
791
  const flatten=require("../utils/flatten"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureVolumeOfPath2=()=>0,measureVolumeOfGeom2=()=>0,measureVolumeOfGeom3=e=>{let r=cache.get(e);if(r)return r;return r=geom3.toPolygons(e).reduce((e,r)=>e+poly3.measureSignedVolume(r),0),cache.set(e,r),r},measureVolume=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const r=e.map(e=>path2.isA(e)?0:geom2.isA(e)?0:geom3.isA(e)?measureVolumeOfGeom3(e):0);return 1===r.length?r[0]:r};module.exports=measureVolume;
792
792
 
793
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":397}],265:[function(require,module,exports){
793
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62,"../geometries/poly3":79,"../utils/flatten":398}],265:[function(require,module,exports){
794
794
  const vec2=require("../../maths/vec2"),geom2=require("../../geometries/geom2"),fromFakePolygon=(e,o)=>{if(o.vertices.length<4)return null;const r=[],n=o.vertices.filter((e,o)=>e[2]>0&&(r.push(o),!0));if(2!==n.length)throw new Error("Assertion failed: fromFakePolygon: not enough points found");const t=n.map(o=>{const r=Math.round(o[0]/e)*e+0,n=Math.round(o[1]/e)*e+0;return vec2.fromValues(r,n)});if(vec2.equals(t[0],t[1]))return null;const s=r[1]-r[0];if(1!==s&&3!==s)throw new Error("Assertion failed: fromFakePolygon: unknown index ordering");return 1===s&&t.reverse(),t},fromFakePolygons=(e,o)=>{const r=o.map(o=>fromFakePolygon(e,o)).filter(e=>null!==e);return geom2.create(r)};module.exports=fromFakePolygons;
795
795
 
796
796
  },{"../../geometries/geom2":25,"../../maths/vec2":191}],266:[function(require,module,exports){
@@ -799,13 +799,13 @@ module.exports={intersect:require("./intersect"),scission:require("./scission"),
799
799
  },{"./intersect":267,"./scission":272,"./subtract":274,"./union":285}],267:[function(require,module,exports){
800
800
  const flatten=require("../../utils/flatten"),areAllShapesTheSameType=require("../../utils/areAllShapesTheSameType"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),intersectGeom2=require("./intersectGeom2"),intersectGeom3=require("./intersectGeom3"),intersect=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");if(!areAllShapesTheSameType(e))throw new Error("only intersect of the types are supported");const r=e[0];return geom2.isA(r)?intersectGeom2(e):geom3.isA(r)?intersectGeom3(e):r};module.exports=intersect;
801
801
 
802
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":395,"../../utils/flatten":397,"./intersectGeom2":268,"./intersectGeom3":269}],268:[function(require,module,exports){
802
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":396,"../../utils/flatten":398,"./intersectGeom2":268,"./intersectGeom3":269}],268:[function(require,module,exports){
803
803
  const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),measureEpsilon=require("../../measurements/measureEpsilon"),fromFakePolygons=require("./fromFakePolygons"),to3DWalls=require("./to3DWalls"),intersectGeom3=require("./intersectGeom3"),intersect=(...e)=>{const o=(e=flatten(e)).map(e=>to3DWalls({z0:-1,z1:1},e)),r=intersectGeom3(o),t=measureEpsilon(r);return fromFakePolygons(t,geom3.toPolygons(r))};module.exports=intersect;
804
804
 
805
- },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"./fromFakePolygons":265,"./intersectGeom3":269,"./to3DWalls":278}],269:[function(require,module,exports){
805
+ },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"./fromFakePolygons":265,"./intersectGeom3":269,"./to3DWalls":278}],269:[function(require,module,exports){
806
806
  const flatten=require("../../utils/flatten"),retessellate=require("../modifiers/retessellate"),intersectSub=require("./intersectGeom3Sub"),intersect=(...e)=>{let t=(e=flatten(e)).shift();return e.forEach(e=>{t=intersectSub(t,e)}),t=retessellate(t)};module.exports=intersect;
807
807
 
808
- },{"../../utils/flatten":397,"../modifiers/retessellate":355,"./intersectGeom3Sub":270}],270:[function(require,module,exports){
808
+ },{"../../utils/flatten":398,"../modifiers/retessellate":356,"./intersectGeom3Sub":270}],270:[function(require,module,exports){
809
809
  const geom3=require("../../geometries/geom3"),mayOverlap=require("./mayOverlap"),{Tree:Tree}=require("./trees"),intersectGeom3Sub=(e,o)=>{if(!mayOverlap(e,o))return geom3.create();const r=new Tree(geom3.toPolygons(e)),t=new Tree(geom3.toPolygons(o));r.invert(),t.clipTo(r),t.invert(),r.clipTo(t),t.clipTo(r),r.addPolygons(t.allPolygons()),r.invert();const n=r.allPolygons();return geom3.create(n)};module.exports=intersectGeom3Sub;
810
810
 
811
811
  },{"../../geometries/geom3":41,"./mayOverlap":271,"./trees":282}],271:[function(require,module,exports){
@@ -814,19 +814,19 @@ const{EPS:EPS}=require("../../maths/constants"),measureBoundingBox=require("../.
814
814
  },{"../../maths/constants":94,"../../measurements/measureBoundingBox":258}],272:[function(require,module,exports){
815
815
  const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),scissionGeom3=require("./scissionGeom3"),scission=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const s=e.map(e=>geom3.isA(e)?scissionGeom3(e):e);return 1===s.length?s[0]:s};module.exports=scission;
816
816
 
817
- },{"../../geometries/geom3":41,"../../utils/flatten":397,"./scissionGeom3":273}],273:[function(require,module,exports){
817
+ },{"../../geometries/geom3":41,"../../utils/flatten":398,"./scissionGeom3":273}],273:[function(require,module,exports){
818
818
  const vec3=require("../../maths/vec3"),measureEpsilon=require("../../measurements/measureEpsilon"),geom3=require("../../geometries/geom3"),sortNb=e=>e.sort((e,s)=>e-s).filter((e,s,o)=>!s||e!==o[s-1]),insertMapping=(e,s,o)=>{const t=`${s}`,n=e.get(t);void 0===n?e.set(t,[o]):n.push(o)},findMapping=(e,s)=>{const o=`${s}`;return e.get(o)},scissionGeom3=e=>{const s=measureEpsilon(e),o=geom3.toPolygons(e),t=o.length,n=new Map,r=vec3.create();o.forEach((e,o)=>{e.vertices.forEach(e=>{insertMapping(n,vec3.snap(r,e,s),o)})});const c=o.map(e=>{let o=[];return e.vertices.forEach(e=>{o=o.concat(findMapping(n,vec3.snap(r,e,s)))}),{e:1,d:sortNb(o)}});n.clear();let i=0;const a=c.length;for(let e=0;e<a;e++){const s=c[e];if(s.e>0){const o=new Array(t);o[e]=!0;do{i=0,o.forEach((e,s)=>{const t=c[s];if(t.e>0){t.e=-1;for(let e=0;e<t.d.length;e++)o[t.d[e]]=!0;i++}})}while(i>0);s.indexes=o}}const p=[];for(let e=0;e<a;e++)if(c[e].indexes){const s=[];c[e].indexes.forEach((e,t)=>s.push(o[t])),p.push(geom3.create(s))}return p};module.exports=scissionGeom3;
819
819
 
820
820
  },{"../../geometries/geom3":41,"../../maths/vec3":222,"../../measurements/measureEpsilon":263}],274:[function(require,module,exports){
821
821
  const flatten=require("../../utils/flatten"),areAllShapesTheSameType=require("../../utils/areAllShapesTheSameType"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),subtractGeom2=require("./subtractGeom2"),subtractGeom3=require("./subtractGeom3"),subtract=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");if(!areAllShapesTheSameType(e))throw new Error("only subtract of the types are supported");const r=e[0];return geom2.isA(r)?subtractGeom2(e):geom3.isA(r)?subtractGeom3(e):r};module.exports=subtract;
822
822
 
823
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":395,"../../utils/flatten":397,"./subtractGeom2":275,"./subtractGeom3":276}],275:[function(require,module,exports){
823
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":396,"../../utils/flatten":398,"./subtractGeom2":275,"./subtractGeom3":276}],275:[function(require,module,exports){
824
824
  const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),measureEpsilon=require("../../measurements/measureEpsilon"),fromFakePolygons=require("./fromFakePolygons"),to3DWalls=require("./to3DWalls"),subtractGeom3=require("./subtractGeom3"),subtract=(...e)=>{const o=(e=flatten(e)).map(e=>to3DWalls({z0:-1,z1:1},e)),r=subtractGeom3(o),t=measureEpsilon(r);return fromFakePolygons(t,geom3.toPolygons(r))};module.exports=subtract;
825
825
 
826
- },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"./fromFakePolygons":265,"./subtractGeom3":276,"./to3DWalls":278}],276:[function(require,module,exports){
826
+ },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"./fromFakePolygons":265,"./subtractGeom3":276,"./to3DWalls":278}],276:[function(require,module,exports){
827
827
  const flatten=require("../../utils/flatten"),retessellate=require("../modifiers/retessellate"),subtractSub=require("./subtractGeom3Sub"),subtract=(...t)=>{let e=(t=flatten(t)).shift();return t.forEach(t=>{e=subtractSub(e,t)}),e=retessellate(e)};module.exports=subtract;
828
828
 
829
- },{"../../utils/flatten":397,"../modifiers/retessellate":355,"./subtractGeom3Sub":277}],277:[function(require,module,exports){
829
+ },{"../../utils/flatten":398,"../modifiers/retessellate":356,"./subtractGeom3Sub":277}],277:[function(require,module,exports){
830
830
  const geom3=require("../../geometries/geom3"),mayOverlap=require("./mayOverlap"),{Tree:Tree}=require("./trees"),subtractGeom3Sub=(e,o)=>{if(!mayOverlap(e,o))return geom3.clone(e);const r=new Tree(geom3.toPolygons(e)),t=new Tree(geom3.toPolygons(o));r.invert(),r.clipTo(t),t.clipTo(r,!0),r.addPolygons(t.allPolygons()),r.invert();const l=r.allPolygons();return geom3.create(l)};module.exports=subtractGeom3Sub;
831
831
 
832
832
  },{"../../geometries/geom3":41,"./mayOverlap":271,"./trees":282}],278:[function(require,module,exports){
@@ -853,19 +853,19 @@ const{EPS:EPS}=require("../../../maths/constants"),plane=require("../../../maths
853
853
  },{"../../../geometries/poly3":79,"../../../maths/constants":94,"../../../maths/plane":163,"../../../maths/vec3":222,"./splitLineSegmentByPlane":283}],285:[function(require,module,exports){
854
854
  const flatten=require("../../utils/flatten"),areAllShapesTheSameType=require("../../utils/areAllShapesTheSameType"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),unionGeom2=require("./unionGeom2"),unionGeom3=require("./unionGeom3"),union=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");if(!areAllShapesTheSameType(e))throw new Error("only unions of the same type are supported");const o=e[0];return geom2.isA(o)?unionGeom2(e):geom3.isA(o)?unionGeom3(e):o};module.exports=union;
855
855
 
856
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":395,"../../utils/flatten":397,"./unionGeom2":286,"./unionGeom3":287}],286:[function(require,module,exports){
856
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../utils/areAllShapesTheSameType":396,"../../utils/flatten":398,"./unionGeom2":286,"./unionGeom3":287}],286:[function(require,module,exports){
857
857
  const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),measureEpsilon=require("../../measurements/measureEpsilon"),fromFakePolygons=require("./fromFakePolygons"),to3DWalls=require("./to3DWalls"),unionGeom3=require("./unionGeom3"),union=(...e)=>{const o=(e=flatten(e)).map(e=>to3DWalls({z0:-1,z1:1},e)),n=unionGeom3(o),r=measureEpsilon(n);return fromFakePolygons(r,geom3.toPolygons(n))};module.exports=union;
858
858
 
859
- },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"./fromFakePolygons":265,"./to3DWalls":278,"./unionGeom3":287}],287:[function(require,module,exports){
859
+ },{"../../geometries/geom3":41,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"./fromFakePolygons":265,"./to3DWalls":278,"./unionGeom3":287}],287:[function(require,module,exports){
860
860
  const flatten=require("../../utils/flatten"),retessellate=require("../modifiers/retessellate"),unionSub=require("./unionGeom3Sub"),union=(...e)=>{let t;for(e=flatten(e),t=1;t<e.length;t+=2)e.push(unionSub(e[t-1],e[t]));let n=e[t-1];return n=retessellate(n)};module.exports=union;
861
861
 
862
- },{"../../utils/flatten":397,"../modifiers/retessellate":355,"./unionGeom3Sub":288}],288:[function(require,module,exports){
862
+ },{"../../utils/flatten":398,"../modifiers/retessellate":356,"./unionGeom3Sub":288}],288:[function(require,module,exports){
863
863
  const geom3=require("../../geometries/geom3"),mayOverlap=require("./mayOverlap"),{Tree:Tree}=require("./trees"),unionSub=(e,o)=>{if(!mayOverlap(e,o))return unionForNonIntersecting(e,o);const n=new Tree(geom3.toPolygons(e)),r=new Tree(geom3.toPolygons(o));n.clipTo(r,!1),r.clipTo(n),r.invert(),r.clipTo(n),r.invert();const t=n.allPolygons().concat(r.allPolygons());return geom3.create(t)},unionForNonIntersecting=(e,o)=>{let n=geom3.toPolygons(e);return n=n.concat(geom3.toPolygons(o)),geom3.create(n)};module.exports=unionSub;
864
864
 
865
865
  },{"../../geometries/geom3":41,"./mayOverlap":271,"./trees":282}],289:[function(require,module,exports){
866
866
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),expandGeom2=require("./expandGeom2"),expandGeom3=require("./expandGeom3"),expandPath2=require("./expandPath2"),expand=(e,...r)=>{if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");const t=r.map(r=>path2.isA(r)?expandPath2(e,r):geom2.isA(r)?expandGeom2(e,r):geom3.isA(r)?expandGeom3(e,r):r);return 1===t.length?t[0]:t};module.exports=expand;
867
867
 
868
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/flatten":397,"./expandGeom2":290,"./expandGeom3":291,"./expandPath2":292}],290:[function(require,module,exports){
868
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/flatten":398,"./expandGeom2":290,"./expandGeom3":291,"./expandPath2":292}],290:[function(require,module,exports){
869
869
  const geom2=require("../../geometries/geom2"),offsetFromPoints=require("./offsetFromPoints"),expandGeom2=(e,o)=>{const{delta:r,corners:s,segments:t}=Object.assign({},{delta:1,corners:"edge",segments:16},e);if("edge"!==s&&"chamfer"!==s&&"round"!==s)throw new Error('corners must be "edge", "chamfer", or "round"');const n=geom2.toOutlines(o).map(o=>offsetFromPoints(e={delta:r,corners:s,closed:!0,segments:t},o)).reduce((e,o)=>e.concat(geom2.toSides(geom2.fromPoints(o))),[]);return geom2.create(n)};module.exports=expandGeom2;
870
870
 
871
871
  },{"../../geometries/geom2":25,"./offsetFromPoints":297}],291:[function(require,module,exports){
@@ -877,7 +877,7 @@ const area=require("../../maths/utils/area"),vec2=require("../../maths/vec2"),ge
877
877
  },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../maths/utils/area":168,"../../maths/vec2":191,"./offsetFromPoints":297}],293:[function(require,module,exports){
878
878
  const{EPS:EPS,TAU:TAU}=require("../../maths/constants"),mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),fnNumberSort=require("../../utils/fnNumberSort"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),sphere=require("../../primitives/sphere"),retessellate=require("../modifiers/retessellate"),unionGeom3Sub=require("../booleans/unionGeom3Sub"),extrudePolygon=require("./extrudePolygon"),mapPlaneToVertex=(e,t,o)=>{const n=t.toString();if(e.has(n)){e.get(n)[1].push(o)}else{const s=[t,[o]];e.set(n,s)}},mapPlaneToEdge=(e,t,o)=>{const n=t[0].toString(),s=t[1].toString(),r=n<s?`${n},${s}`:`${s},${n}`;if(e.has(r)){e.get(r)[1].push(o)}else{const n=[t,[o]];e.set(r,n)}},addUniqueAngle=(e,t)=>{e.findIndex(e=>e===t)<0&&e.push(t)},expandShell=(e,t)=>{const{delta:o,segments:n}=Object.assign({},{delta:1,segments:12},e);let s=geom3.create();const r=new Map,c=new Map,a=vec3.create(),l=vec3.create();return geom3.toPolygons(t).forEach((e,t)=>{const n=vec3.scale(vec3.create(),poly3.plane(e),2*o),a=poly3.transform(mat4.fromTranslation(mat4.create(),vec3.scale(vec3.create(),n,-.5)),e),l=extrudePolygon(n,a);s=unionGeom3Sub(s,l);const u=e.vertices;for(let t=0;t<u.length;t++){mapPlaneToVertex(r,u[t],poly3.plane(e));const o=(t+1)%u.length,n=[u[t],u[o]];mapPlaneToEdge(c,n,poly3.plane(e))}}),c.forEach(e=>{const t=e[0],r=e[1],c=t[0],u=t[1],i=vec3.subtract(vec3.create(),u,c);vec3.normalize(i,i);const m=r[0],g=vec3.cross(vec3.create(),m,i);let p=[];for(let e=0;e<n;e++)addUniqueAngle(p,e*TAU/n);for(let e=0,t=r.length;e<t;e++){const t=r[e],o=vec3.dot(g,t),n=vec3.dot(m,t);let s=Math.atan2(o,n);s<0&&(s+=TAU),addUniqueAngle(p,s),(s=Math.atan2(-o,-n))<0&&(s+=TAU),addUniqueAngle(p,s)}const h=(p=p.sort(fnNumberSort)).length;let v,d;const f=[],S=[],q=[];for(let e=-1;e<h;e++){const t=p[e<0?e+h:e],n=Math.sin(t),s=Math.cos(t);vec3.scale(a,m,s*o),vec3.scale(l,g,n*o),vec3.add(a,a,l);const r=vec3.add(vec3.create(),c,a),i=vec3.add(vec3.create(),u,a);let y=!1;if(e>=0&&vec3.distance(r,v)<EPS&&(y=!0),!y){if(e>=0){f.push(r),S.push(i);const e=[d,i,r,v],t=poly3.create(e);q.push(t)}v=r,d=i}}S.reverse(),q.push(poly3.create(f)),q.push(poly3.create(S));const y=geom3.create(q);s=unionGeom3Sub(s,y)}),r.forEach(e=>{const t=e[0],r=e[1],c=r[0];let u=null,i=0;for(let e=1;e<r.length;e++){const t=r[e],o=vec3.cross(a,c,t),n=vec3.length(o);n>.05&&n>i&&(i=n,u=t)}u||(u=vec3.orthogonal(a,c));const m=vec3.cross(a,c,u);vec3.normalize(m,m);const g=vec3.cross(l,m,c),p=sphere({center:[t[0],t[1],t[2]],radius:o,segments:n,axes:[c,m,g]});s=unionGeom3Sub(s,p)}),retessellate(s)};module.exports=expandShell;
879
879
 
880
- },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/constants":94,"../../maths/mat4":143,"../../maths/vec3":222,"../../primitives/sphere":385,"../../utils/fnNumberSort":398,"../booleans/unionGeom3Sub":288,"../modifiers/retessellate":355,"./extrudePolygon":294}],294:[function(require,module,exports){
880
+ },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/constants":94,"../../maths/mat4":143,"../../maths/vec3":222,"../../primitives/sphere":386,"../../utils/fnNumberSort":399,"../booleans/unionGeom3Sub":288,"../modifiers/retessellate":356,"./extrudePolygon":294}],294:[function(require,module,exports){
881
881
  const mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),extrudePolygon=(e,r)=>{vec3.dot(poly3.plane(r),e)>0&&(r=poly3.invert(r));const t=[r],o=poly3.transform(mat4.fromTranslation(mat4.create(),e),r),s=r.vertices.length;for(let e=0;e<s;e++){const c=e<s-1?e+1:0,i=poly3.create([r.vertices[e],o.vertices[e],o.vertices[c],r.vertices[c]]);t.push(i)}return t.push(poly3.invert(o)),geom3.create(t)};module.exports=extrudePolygon;
882
882
 
883
883
  },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/mat4":143,"../../maths/vec3":222}],295:[function(require,module,exports){
@@ -886,7 +886,7 @@ module.exports={expand:require("./expand"),offset:require("./offset")};
886
886
  },{"./expand":289,"./offset":296}],296:[function(require,module,exports){
887
887
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),offsetGeom2=require("./offsetGeom2"),offsetPath2=require("./offsetPath2"),offset=(e,...t)=>{if(0===(t=flatten(t)).length)throw new Error("wrong number of arguments");const o=t.map(t=>path2.isA(t)?offsetPath2(e,t):geom2.isA(t)?offsetGeom2(e,t):t);return 1===o.length?o[0]:o};module.exports=offset;
888
888
 
889
- },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":397,"./offsetGeom2":298,"./offsetPath2":299}],297:[function(require,module,exports){
889
+ },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":398,"./offsetGeom2":298,"./offsetPath2":299}],297:[function(require,module,exports){
890
890
  const{EPS:EPS,TAU:TAU}=require("../../maths/constants"),intersect=require("../../maths/utils/intersect"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),area=require("../../maths/utils/area"),offsetFromPoints=(e,t)=>{let{delta:s,corners:c,closed:n,segments:a}=Object.assign({},{delta:1,corners:"edge",closed:!1,segments:16},e);if(Math.abs(s)<EPS)return t;let r=e.closed?area(t):1;0===r&&(r=1);const o=r>0&&s>=0||r<0&&s<0;s=Math.abs(s);let i=null,l=[];const u=[],v=vec2.create(),f=t.length;for(let e=0;e<f;e++){const c=(e+1)%f,a=t[e],r=t[c];o?vec2.subtract(v,a,r):vec2.subtract(v,r,a),vec2.normal(v,v),vec2.normalize(v,v),vec2.scale(v,v,s);const h=vec2.add(vec2.create(),a,v),d=vec2.add(vec2.create(),r,v),m=[h,d];if(null!=i&&(n||!n&&0!==c)){const e=intersect(i[0],i[1],m[0],m[1]);e?(l.pop(),m[0]=e):u.push({c:a,s0:i,s1:m})}i=[h,d],(0!==c||n)&&(l.push(m[0]),l.push(m[1]))}if(n&&null!=i){const e=l[0],s=l[1],c=intersect(i[0],i[1],e,s);if(c)l[0]=c,l.pop();else{const c=t[0],n=[e,s];u.push({c:c,s0:i,s1:n})}}if("edge"===c){const e=new Map;l.forEach((t,s)=>e.set(t,s));const t=line2.create(),s=line2.create();u.forEach(c=>{line2.fromPoints(t,c.s0[0],c.s0[1]),line2.fromPoints(s,c.s1[0],c.s1[1]);const n=line2.intersectPointOfLines(t,s);if(Number.isFinite(n[0])&&Number.isFinite(n[1])){const t=c.s0[1],s=e.get(t);l[s]=n,l[(s+1)%l.length]=void 0}else{const t=c.s1[0],s=e.get(t);l[s]=void 0}}),l=l.filter(e=>void 0!==e)}if("round"===c){let e=Math.floor(a/4);const t=vec2.create();u.forEach(c=>{let n=vec2.angle(vec2.subtract(t,c.s1[0],c.c));if(n-=vec2.angle(vec2.subtract(t,c.s0[1],c.c)),o&&n<0&&(n+=Math.PI)<0&&(n+=Math.PI),!o&&n>0&&(n-=Math.PI)>0&&(n-=Math.PI),0!==n){const r=n/(e=Math.floor(a*(Math.abs(n)/TAU))),o=vec2.angle(vec2.subtract(t,c.s0[1],c.c)),i=[];for(let t=1;t<e;t++){const e=o+r*t,n=vec2.fromAngleRadians(vec2.create(),e);vec2.scale(n,n,s),vec2.add(n,n,c.c),i.push(n)}if(i.length>0){const e=c.s0[1];let t=l.findIndex(t=>vec2.equals(e,t));t=(t+1)%l.length,l.splice(t,0,...i)}}else{const e=c.s1[0],t=l.findIndex(t=>vec2.equals(e,t));l.splice(t,1)}})}return l};module.exports=offsetFromPoints;
891
891
 
892
892
  },{"../../maths/constants":94,"../../maths/line2":105,"../../maths/utils/area":168,"../../maths/utils/intersect":171,"../../maths/vec2":191}],298:[function(require,module,exports){
@@ -928,7 +928,7 @@ const{TAU:TAU}=require("../../maths/constants"),slice=require("./slice"),mat4=re
928
928
  },{"../../geometries/geom2":25,"../../maths/constants":94,"../../maths/mat4":143,"./extrudeFromSlices":308,"./slice":326}],310:[function(require,module,exports){
929
929
  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;
930
930
 
931
- },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":397,"./extrudeLinearGeom2":311,"./extrudeLinearPath2":312}],311:[function(require,module,exports){
931
+ },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":398,"./extrudeLinearGeom2":311,"./extrudeLinearPath2":312}],311:[function(require,module,exports){
932
932
  const mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),geom2=require("../../geometries/geom2"),slice=require("./slice"),extrudeFromSlices=require("./extrudeFromSlices"),extrudeGeom2=(e,t)=>{let{offset:r,twistAngle:s,twistSteps:o,repair:i}=Object.assign({},{offset:[0,0,1],twistAngle:0,twistSteps:12,repair:!0},e);if(o<1)throw new Error("twistSteps must be 1 or more");0===s&&(o=1);const c=vec3.clone(r),m=geom2.toSides(t);if(0===m.length)throw new Error("the given geometry cannot be empty");const a=slice.fromSides(m);c[2]<0&&slice.reverse(a,a);const n=mat4.create();return extrudeFromSlices(e={numberOfSlices:o+1,capStart:!0,capEnd:!0,repair:i,callback:(e,t,r)=>{const i=t/o*s,m=vec3.scale(vec3.create(),c,t/o);return mat4.multiply(n,mat4.fromZRotation(n,i),mat4.fromTranslation(mat4.create(),m)),slice.transform(n,r)}},a)};module.exports=extrudeGeom2;
933
933
 
934
934
  },{"../../geometries/geom2":25,"../../maths/mat4":143,"../../maths/vec3":222,"./extrudeFromSlices":308,"./slice":326}],312:[function(require,module,exports){
@@ -937,7 +937,7 @@ const geom2=require("../../geometries/geom2"),path2=require("../../geometries/pa
937
937
  },{"../../geometries/geom2":25,"../../geometries/path2":62,"./extrudeLinearGeom2":311}],313:[function(require,module,exports){
938
938
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),extrudeRectangularPath2=require("./extrudeRectangularPath2"),extrudeRectangularGeom2=require("./extrudeRectangularGeom2"),extrudeRectangular=(e,...t)=>{const{size:r,height:a}=Object.assign({},{size:1,height:1},e);if(0===(t=flatten(t)).length)throw new Error("wrong number of arguments");if(r<=0)throw new Error("size must be positive");if(a<=0)throw new Error("height must be positive");const u=t.map(t=>path2.isA(t)?extrudeRectangularPath2(e,t):geom2.isA(t)?extrudeRectangularGeom2(e,t):t);return 1===u.length?u[0]:u};module.exports=extrudeRectangular;
939
939
 
940
- },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":397,"./extrudeRectangularGeom2":314,"./extrudeRectangularPath2":315}],314:[function(require,module,exports){
940
+ },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../utils/flatten":398,"./extrudeRectangularGeom2":314,"./extrudeRectangularPath2":315}],314:[function(require,module,exports){
941
941
  const{area:area}=require("../../maths/utils"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),expand=require("../expansions/expand"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudeRectangularGeom2=(e,r)=>{const{size:t,height:o}=Object.assign({},{size:1,height:1},e);e.delta=t,e.offset=[0,0,o];const a=geom2.toOutlines(r);if(0===a.length)throw new Error("the given geometry cannot be empty");const n=a.map(r=>(area(r)<0&&r.reverse(),expand(e,path2.fromPoints({closed:!0},r)))).reduce((e,r)=>e.concat(geom2.toSides(r)),[]),i=geom2.create(n);return extrudeLinearGeom2(e,i)};module.exports=extrudeRectangularGeom2;
942
942
 
943
943
  },{"../../geometries/geom2":25,"../../geometries/path2":62,"../../maths/utils":169,"../expansions/expand":289,"./extrudeLinearGeom2":311}],315:[function(require,module,exports){
@@ -946,7 +946,7 @@ const path2=require("../../geometries/path2"),expand=require("../expansions/expa
946
946
  },{"../../geometries/path2":62,"../expansions/expand":289,"./extrudeLinearGeom2":311}],316:[function(require,module,exports){
947
947
  const{TAU:TAU}=require("../../maths/constants"),mat4=require("../../maths/mat4"),{mirrorX:mirrorX}=require("../transforms/mirror"),geom2=require("../../geometries/geom2"),slice=require("./slice"),extrudeFromSlices=require("./extrudeFromSlices"),extrudeRotate=(e,t)=>{const r={segments:12,startAngle:0,angle:TAU,overflow:"cap"};let{segments:a,startAngle:o,angle:s,overflow:m}=Object.assign({},r,e);if(a<3)throw new Error("segments must be greater then 3");o=Math.abs(o)>TAU?o%TAU:o,s=Math.abs(s)>TAU?s%TAU:s;let n=o+s;if((n=Math.abs(n)>TAU?n%TAU:n)<o){const e=o;o=n,n=e}let l=n-o;if(l<=0&&(l=TAU),Math.abs(l)<TAU){const e=TAU/a;a=Math.floor(Math.abs(l)/e),Math.abs(l)>a*e&&a++}let i=geom2.toSides(t);if(0===i.length)throw new Error("the given geometry cannot be empty");const c=i.filter(e=>e[0][0]<0),g=i.filter(e=>e[0][0]>=0);c.length>0&&g.length>0&&"cap"===m&&(c.length>g.length?(i=i.map(e=>{let t=e[0],r=e[1];return[t=[Math.min(t[0],0),t[1]],r=[Math.min(r[0],0),r[1]]]}),t=geom2.create(i),t=mirrorX(t)):g.length>=c.length&&(i=i.map(e=>{let t=e[0],r=e[1];return[t=[Math.max(t[0],0),t[1]],r=[Math.max(r[0],0),r[1]]]}),t=geom2.create(i)));const h=l/a,u=Math.abs(l)<TAU,A=slice.fromSides(geom2.toSides(t));slice.reverse(A,A);const f=mat4.create();return extrudeFromSlices(e={numberOfSlices:a+1,capStart:u,capEnd:u,close:!u,callback:(e,t,r)=>{let s=h*t+o;return l===TAU&&t===a&&(s=o),mat4.multiply(f,mat4.fromZRotation(f,s),mat4.fromXRotation(mat4.create(),TAU/4)),slice.transform(f,r)}},A)};module.exports=extrudeRotate;
948
948
 
949
- },{"../../geometries/geom2":25,"../../maths/constants":94,"../../maths/mat4":143,"../transforms/mirror":362,"./extrudeFromSlices":308,"./slice":326}],317:[function(require,module,exports){
949
+ },{"../../geometries/geom2":25,"../../maths/constants":94,"../../maths/mat4":143,"../transforms/mirror":363,"./extrudeFromSlices":308,"./slice":326}],317:[function(require,module,exports){
950
950
  const{EPS:EPS}=require("../../maths/constants"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),gcd=(e,t)=>e===t?e:e<t?gcd(t,e):1===t?1:0===t?e:gcd(t,e%t),lcm=(e,t)=>e*t/gcd(e,t),repartitionEdges=(e,t)=>{const r=e/t.length;if(1===r)return t;const s=vec3.fromValues(r,r,r),c=[];return t.forEach(e=>{const t=vec3.subtract(vec3.create(),e[1],e[0]);vec3.divide(t,t,s);let l=e[0];for(let e=1;e<=r;++e){const e=vec3.add(vec3.create(),l,t);c.push([l,e]),l=e}}),c},EPSAREA=EPS*EPS/2*Math.sin(Math.PI/3),extrudeWalls=(e,t)=>{let r=slice.toEdges(e),s=slice.toEdges(t);if(r.length!==s.length){const e=lcm(r.length,s.length);e!==r.length&&(r=repartitionEdges(e,r)),e!==s.length&&(s=repartitionEdges(e,s))}const c=[];return r.forEach((e,t)=>{const r=s[t],l=poly3.create([e[0],e[1],r[1]]),o=poly3.measureArea(l);Number.isFinite(o)&&o>EPSAREA&&c.push(l);const n=poly3.create([e[0],r[1],r[0]]),i=poly3.measureArea(n);Number.isFinite(i)&&i>EPSAREA&&c.push(n)}),c};module.exports=extrudeWalls;
951
951
 
952
952
  },{"../../geometries/poly3":79,"../../maths/constants":94,"../../maths/vec3":222,"./slice":326}],318:[function(require,module,exports){
@@ -955,7 +955,7 @@ module.exports={extrudeFromSlices:require("./extrudeFromSlices"),extrudeLinear:r
955
955
  },{"./extrudeFromSlices":308,"./extrudeHelical":309,"./extrudeLinear":310,"./extrudeRectangular":313,"./extrudeRotate":316,"./project":319,"./slice":326}],319:[function(require,module,exports){
956
956
  const flatten=require("../../utils/flatten"),aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),plane=require("../../maths/plane"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),measureEpsilon=require("../../measurements/measureEpsilon"),unionGeom2=require("../booleans/unionGeom2"),projectGeom3=(e,o)=>{const r=plane.fromNormalAndPoint(plane.create(),e.axis,e.origin);if(Number.isNaN(r[0])||Number.isNaN(r[1])||Number.isNaN(r[2])||Number.isNaN(r[3]))throw new Error("project: invalid axis or origin");const t=measureEpsilon(o),a=t*t*Math.sqrt(3)/4;if(0===t)return geom2.create();const n=geom3.toPolygons(o);let s=[];for(let e=0;e<n.length;e++){const o=n[e].vertices.map(e=>plane.projectionOfPoint(r,e)),t=poly3.create(o),i=poly3.plane(t);aboutEqualNormals(r,i)&&(poly3.measureArea(t)<a||s.push(t))}if(!aboutEqualNormals(r,[0,0,1])){const e=mat4.fromVectorRotation(mat4.create(),r,[0,0,1]);s=s.map(o=>poly3.transform(e,o))}const i=(s=s.sort((e,o)=>poly3.measureArea(o)-poly3.measureArea(e))).map(e=>geom2.fromPoints(e.vertices));return unionGeom2(i)},project=(e,...o)=>{const{axis:r,origin:t}=Object.assign({},{axis:[0,0,1],origin:[0,0,0]},e);if(0===(o=flatten(o)).length)throw new Error("wrong number of arguments");e={axis:r,origin:t};const a=o.map(o=>geom3.isA(o)?projectGeom3(e,o):o);return 1===a.length?a[0]:a};module.exports=project;
957
957
 
958
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/mat4":143,"../../maths/plane":163,"../../maths/utils/aboutEqualNormals":167,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"../booleans/unionGeom2":286}],320:[function(require,module,exports){
958
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/mat4":143,"../../maths/plane":163,"../../maths/utils/aboutEqualNormals":167,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"../booleans/unionGeom2":286}],320:[function(require,module,exports){
959
959
  const plane=require("../../../maths/plane"),vec3=require("../../../maths/vec3"),calculatePlane=e=>{const c=e.edges;if(c.length<3)throw new Error("slices must have 3 or more edges to calculate a plane");const a=c.reduce((e,c)=>vec3.add(vec3.create(),e,c[0]),vec3.create());let t;vec3.scale(a,a,1/c.length);let l=0;c.forEach(e=>{if(!vec3.equals(e[0],e[1])){const c=vec3.squaredDistance(a,e[0]);c>l&&(t=e,l=c)}});const r=c.find(e=>vec3.equals(e[1],t[0]));return plane.fromPoints(plane.create(),r[0],t[0],t[1])};module.exports=calculatePlane;
960
960
 
961
961
  },{"../../../maths/plane":163,"../../../maths/vec3":222}],321:[function(require,module,exports){
@@ -1000,211 +1000,214 @@ const vec3=require("../../../maths/vec3"),create=require("./create"),transform=(
1000
1000
  },{"../../../maths/vec3":222,"./create":322}],334:[function(require,module,exports){
1001
1001
  const flatten=require("../../utils/flatten"),areAllShapesTheSameType=require("../../utils/areAllShapesTheSameType"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),hullPath2=require("./hullPath2"),hullGeom2=require("./hullGeom2"),hullGeom3=require("./hullGeom3"),hull=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");if(!areAllShapesTheSameType(e))throw new Error("only hulls of the same type are supported");const l=e[0];return path2.isA(l)?hullPath2(e):geom2.isA(l)?hullGeom2(e):geom3.isA(l)?hullGeom3(e):l};module.exports=hull;
1002
1002
 
1003
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/areAllShapesTheSameType":395,"../../utils/flatten":397,"./hullGeom2":336,"./hullGeom3":337,"./hullPath2":338}],335:[function(require,module,exports){
1003
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/areAllShapesTheSameType":396,"../../utils/flatten":398,"./hullGeom2":336,"./hullGeom3":337,"./hullPath2":338}],335:[function(require,module,exports){
1004
1004
  const flatten=require("../../utils/flatten"),union=require("../booleans/union"),hull=require("./hull"),hullChain=(...n)=>{if((n=flatten(n)).length<2)throw new Error("wrong number of arguments");const e=[];for(let l=1;l<n.length;l++)e.push(hull(n[l-1],n[l]));return union(e)};module.exports=hullChain;
1005
1005
 
1006
- },{"../../utils/flatten":397,"../booleans/union":285,"./hull":334}],336:[function(require,module,exports){
1006
+ },{"../../utils/flatten":398,"../booleans/union":285,"./hull":334}],336:[function(require,module,exports){
1007
1007
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),hullPoints2=require("./hullPoints2"),toUniquePoints=require("./toUniquePoints"),hullGeom2=(...e)=>{e=flatten(e);const t=toUniquePoints(e),o=hullPoints2(t);return o.length<3?geom2.create():geom2.fromPoints(o)};module.exports=hullGeom2;
1008
1008
 
1009
- },{"../../geometries/geom2":25,"../../utils/flatten":397,"./hullPoints2":339,"./toUniquePoints":349}],337:[function(require,module,exports){
1010
- const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),quickhull=require("./quickhull"),toUniquePoints=require("./toUniquePoints"),hullGeom3=(...e)=>{if(1===(e=flatten(e)).length)return e[0];const t=toUniquePoints(e),o=quickhull(t,{skipTriangulation:!0}).map(e=>{const o=e.map(e=>t[e]);return poly3.create(o)});return geom3.create(o)};module.exports=hullGeom3;
1009
+ },{"../../geometries/geom2":25,"../../utils/flatten":398,"./hullPoints2":339,"./toUniquePoints":350}],337:[function(require,module,exports){
1010
+ const flatten=require("../../utils/flatten"),geom3=require("../../geometries/geom3"),toUniquePoints=require("./toUniquePoints"),hullPoints3=require("./hullPoints3"),hullGeom3=(...e)=>{e=flatten(e);const t=toUniquePoints(e);return 0===t.length?geom3.create():geom3.create(hullPoints3(t))};module.exports=hullGeom3;
1011
1011
 
1012
- },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../utils/flatten":397,"./quickhull":347,"./toUniquePoints":349}],338:[function(require,module,exports){
1012
+ },{"../../geometries/geom3":41,"../../utils/flatten":398,"./hullPoints3":340,"./toUniquePoints":350}],338:[function(require,module,exports){
1013
1013
  const flatten=require("../../utils/flatten"),path2=require("../../geometries/path2"),hullPoints2=require("./hullPoints2"),toUniquePoints=require("./toUniquePoints"),hullPath2=(...t)=>{t=flatten(t);const e=toUniquePoints(t),o=hullPoints2(e);return path2.fromPoints({closed:!0},o)};module.exports=hullPath2;
1014
1014
 
1015
- },{"../../geometries/path2":62,"../../utils/flatten":397,"./hullPoints2":339,"./toUniquePoints":349}],339:[function(require,module,exports){
1015
+ },{"../../geometries/path2":62,"../../utils/flatten":398,"./hullPoints2":339,"./toUniquePoints":350}],339:[function(require,module,exports){
1016
1016
  const vec2=require("../../maths/vec2"),hullPoints2=e=>{let t=vec2.fromValues(1/0,1/0);e.forEach(e=>{(e[1]<t[1]||e[1]===t[1]&&e[0]<t[0])&&(t=e)});const n=[];e.forEach(e=>{const o=fakeAtan2(e[1]-t[1],e[0]-t[0]),s=vec2.squaredDistance(e,t);n.push({point:e,angle:o,distSq:s})}),n.sort((e,t)=>e.angle!==t.angle?e.angle-t.angle:e.distSq-t.distSq);const o=[];return n.forEach(e=>{let t=o.length;for(;t>1&&ccw(o[t-2],o[t-1],e.point)<=Number.EPSILON;)o.pop(),t=o.length;o.push(e.point)}),o},ccw=(e,t,n)=>(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0]),fakeAtan2=(e,t)=>0===e&&0===t?-1/0:-t/e;module.exports=hullPoints2;
1017
1017
 
1018
1018
  },{"../../maths/vec2":191}],340:[function(require,module,exports){
1019
- module.exports={hull:require("./hull"),hullChain:require("./hullChain")};
1019
+ const poly3=require("../../geometries/poly3"),quickhull=require("./quickhull"),hullPoints3=l=>{return quickhull(l,{skipTriangulation:!0}).map(u=>{const e=u.map(u=>l[u]);return poly3.create(e)})};module.exports=hullPoints3;
1020
1020
 
1021
- },{"./hull":334,"./hullChain":335}],341:[function(require,module,exports){
1021
+ },{"../../geometries/poly3":79,"./quickhull":348}],341:[function(require,module,exports){
1022
+ module.exports={hull:require("./hull"),hullChain:require("./hullChain"),hullPoints2:require("./hullPoints2"),hullPoints3:require("./hullPoints3")};
1023
+
1024
+ },{"./hull":334,"./hullChain":335,"./hullPoints2":339,"./hullPoints3":340}],342:[function(require,module,exports){
1022
1025
  const add=require("../../../maths/vec3/add"),copy=require("../../../maths/vec3/copy"),cross=require("../../../maths/vec3/cross"),dot=require("../../../maths/vec3/dot"),length=require("../../../maths/vec3/length"),normalize=require("../../../maths/vec3/normalize"),scale=require("../../../maths/vec3/scale"),subtract=require("../../../maths/vec3/subtract"),HalfEdge=require("./HalfEdge"),VISIBLE=0,NON_CONVEX=1,DELETED=2;class Face{constructor(){this.normal=[],this.centroid=[],this.offset=0,this.outside=null,this.mark=VISIBLE,this.edge=null,this.nVertices=0}getEdge(e){if("number"!=typeof e)throw Error("requires a number");let t=this.edge;for(;e>0;)t=t.next,e-=1;for(;e<0;)t=t.prev,e+=1;return t}computeNormal(){const e=this.edge,t=e.next;let r=t.next;const s=subtract([],t.head().point,e.head().point),o=[],i=[];for(this.nVertices=2,this.normal=[0,0,0];r!==e;)copy(i,s),subtract(s,r.head().point,e.head().point),add(this.normal,this.normal,cross(o,i,s)),r=r.next,this.nVertices+=1;this.area=length(this.normal),this.normal=scale(this.normal,this.normal,1/this.area)}computeNormalMinArea(e){if(this.computeNormal(),this.area<e){let e,t=0,r=this.edge;do{const s=r.lengthSquared();s>t&&(e=r,t=s),r=r.next}while(r!==this.edge);const s=e.tail().point,o=e.head().point,i=subtract([],o,s),n=Math.sqrt(t);scale(i,i,1/n);const a=dot(this.normal,i);scale(i,i,-a),add(this.normal,this.normal,i),normalize(this.normal,this.normal)}}computeCentroid(){this.centroid=[0,0,0];let e=this.edge;do{add(this.centroid,this.centroid,e.head().point),e=e.next}while(e!==this.edge);scale(this.centroid,this.centroid,1/this.nVertices)}computeNormalAndCentroid(e){void 0!==e?this.computeNormalMinArea(e):this.computeNormal(),this.computeCentroid(),this.offset=dot(this.normal,this.centroid)}distanceToPlane(e){return dot(this.normal,e)-this.offset}connectHalfEdges(e,t){let r;if(e.opposite.face===t.opposite.face){const s=t.opposite.face;let o;e===this.edge&&(this.edge=t),3===s.nVertices?(o=t.opposite.prev.opposite,s.mark=DELETED,r=s):(o=t.opposite.next,s.edge===o.prev&&(s.edge=o),o.prev=o.prev.prev,o.prev.next=o),t.prev=e.prev,t.prev.next=t,t.setOpposite(o),s.computeNormalAndCentroid()}else e.next=t,t.prev=e;return r}mergeAdjacentFaces(e,t){const r=e.opposite,s=r.face;t.push(s),s.mark=DELETED;let o,i,n=e.prev,a=e.next,c=r.prev,h=r.next;for(;n.opposite.face===s;)n=n.prev,h=h.next;for(;a.opposite.face===s;)a=a.next,c=c.prev;for(o=h;o!==c.next;o=o.next)o.face=this;return this.edge=a,(i=this.connectHalfEdges(c,a))&&t.push(i),(i=this.connectHalfEdges(n,h))&&t.push(i),this.computeNormalAndCentroid(),t}collectIndices(){const e=[];let t=this.edge;do{e.push(t.head().index),t=t.next}while(t!==this.edge);return e}static createTriangle(e,t,r,s=0){const o=new Face,i=new HalfEdge(e,o),n=new HalfEdge(t,o),a=new HalfEdge(r,o);return i.next=a.prev=n,n.next=i.prev=a,a.next=n.prev=i,o.edge=i,o.computeNormalAndCentroid(s),o}}module.exports={VISIBLE:VISIBLE,NON_CONVEX:1,DELETED:DELETED,Face:Face};
1023
1026
 
1024
- },{"../../../maths/vec3/add":209,"../../../maths/vec3/copy":212,"../../../maths/vec3/cross":214,"../../../maths/vec3/dot":217,"../../../maths/vec3/length":223,"../../../maths/vec3/normalize":229,"../../../maths/vec3/scale":234,"../../../maths/vec3/subtract":238,"./HalfEdge":342}],342:[function(require,module,exports){
1027
+ },{"../../../maths/vec3/add":209,"../../../maths/vec3/copy":212,"../../../maths/vec3/cross":214,"../../../maths/vec3/dot":217,"../../../maths/vec3/length":223,"../../../maths/vec3/normalize":229,"../../../maths/vec3/scale":234,"../../../maths/vec3/subtract":238,"./HalfEdge":343}],343:[function(require,module,exports){
1025
1028
  const distance=require("../../../maths/vec3/distance"),squaredDistance=require("../../../maths/vec3/squaredDistance");class HalfEdge{constructor(t,e){this.vertex=t,this.face=e,this.next=null,this.prev=null,this.opposite=null}head(){return this.vertex}tail(){return this.prev?this.prev.vertex:null}length(){return this.tail()?distance(this.tail().point,this.head().point):-1}lengthSquared(){return this.tail()?squaredDistance(this.tail().point,this.head().point):-1}setOpposite(t){this.opposite=t,t.opposite=this}}module.exports=HalfEdge;
1026
1029
 
1027
- },{"../../../maths/vec3/distance":215,"../../../maths/vec3/squaredDistance":236}],343:[function(require,module,exports){
1030
+ },{"../../../maths/vec3/distance":215,"../../../maths/vec3/squaredDistance":236}],344:[function(require,module,exports){
1028
1031
  const dot=require("../../../maths/vec3/dot"),pointLineDistance=require("./point-line-distance"),getPlaneNormal=require("./get-plane-normal"),VertexList=require("./VertexList"),Vertex=require("./Vertex"),{Face:Face,VISIBLE:VISIBLE,NON_CONVEX:NON_CONVEX,DELETED:DELETED}=require("./Face"),MERGE_NON_CONVEX_WRT_LARGER_FACE=1,MERGE_NON_CONVEX=2;class QuickHull{constructor(e){if(!Array.isArray(e))throw TypeError("input is not a valid array");if(e.length<4)throw Error("cannot build a simplex out of <4 points");this.tolerance=-1,this.nFaces=0,this.nPoints=e.length,this.faces=[],this.newFaces=[],this.claimed=new VertexList,this.unclaimed=new VertexList,this.vertices=[];for(let t=0;t<e.length;t+=1)this.vertices.push(new Vertex(e[t],t));this.discardedFaces=[],this.vertexPointIndices=[]}addVertexToFace(e,t){e.face=t,t.outside?this.claimed.insertBefore(t.outside,e):this.claimed.add(e),t.outside=e}removeVertexFromFace(e,t){e===t.outside&&(e.next&&e.next.face===t?t.outside=e.next:t.outside=null),this.claimed.remove(e)}removeAllVerticesFromFace(e){if(e.outside){let t=e.outside;for(;t.next&&t.next.face===e;)t=t.next;return this.claimed.removeChain(e.outside,t),t.next=null,e.outside}}deleteFaceVertices(e,t){const i=this.removeAllVerticesFromFace(e);if(i)if(t){let e;for(let s=i;s;s=e){e=s.next,t.distanceToPlane(s.point)>this.tolerance?this.addVertexToFace(s,t):this.unclaimed.add(s)}}else this.unclaimed.addAll(i)}resolveUnclaimedPoints(e){let t=this.unclaimed.first();for(let i=t;i;i=t){t=i.next;let s,o=this.tolerance;for(let t=0;t<e.length;t+=1){const a=e[t];if(a.mark===VISIBLE){const e=a.distanceToPlane(i.point);if(e>o&&(o=e,s=a),o>1e3*this.tolerance)break}}s&&this.addVertexToFace(i,s)}}computeExtremes(){const e=[],t=[],i=[],s=[];let o,a;for(o=0;o<3;o+=1)i[o]=s[o]=this.vertices[0];for(o=0;o<3;o+=1)e[o]=t[o]=this.vertices[0].point[o];for(o=1;o<this.vertices.length;o+=1){const c=this.vertices[o],n=c.point;for(a=0;a<3;a+=1)n[a]<e[a]&&(e[a]=n[a],i[a]=c);for(a=0;a<3;a+=1)n[a]>t[a]&&(t[a]=n[a],s[a]=c)}return this.tolerance=3*Number.EPSILON*(Math.max(Math.abs(e[0]),Math.abs(t[0]))+Math.max(Math.abs(e[1]),Math.abs(t[1]))+Math.max(Math.abs(e[2]),Math.abs(t[2]))),[i,s]}createInitialSimplex(){const e=this.vertices,[t,i]=this.computeExtremes();let s,o,a,c,n=0,r=0;for(a=0;a<3;a+=1){const e=i[a].point[a]-t[a].point[a];e>n&&(n=e,r=a)}const l=t[r],h=i[r];for(n=0,a=0;a<this.vertices.length;a+=1){const e=this.vertices[a];if(e!==l&&e!==h){const t=pointLineDistance(e.point,l.point,h.point);t>n&&(n=t,s=e)}}const d=getPlaneNormal([],l.point,h.point,s.point),p=dot(l.point,d);for(n=-1,a=0;a<this.vertices.length;a+=1){const e=this.vertices[a];if(e!==l&&e!==h&&e!==s){const t=Math.abs(dot(d,e.point)-p);t>n&&(n=t,o=e)}}const f=[];if(dot(o.point,d)-p<0)for(f.push(Face.createTriangle(l,h,s),Face.createTriangle(o,h,l),Face.createTriangle(o,s,h),Face.createTriangle(o,l,s)),a=0;a<3;a+=1){const e=(a+1)%3;f[a+1].getEdge(2).setOpposite(f[0].getEdge(e)),f[a+1].getEdge(1).setOpposite(f[e+1].getEdge(0))}else for(f.push(Face.createTriangle(l,s,h),Face.createTriangle(o,l,h),Face.createTriangle(o,h,s),Face.createTriangle(o,s,l)),a=0;a<3;a+=1){const e=(a+1)%3;f[a+1].getEdge(2).setOpposite(f[0].getEdge((3-a)%3)),f[a+1].getEdge(0).setOpposite(f[e+1].getEdge(1))}for(a=0;a<4;a+=1)this.faces.push(f[a]);for(a=0;a<e.length;a+=1){const t=e[a];if(t!==l&&t!==h&&t!==s&&t!==o){let e;for(n=this.tolerance,c=0;c<4;c+=1){const i=f[c].distanceToPlane(t.point);i>n&&(n=i,e=f[c])}e&&this.addVertexToFace(t,e)}}}reindexFaceAndVertices(){const e=[];for(let t=0;t<this.faces.length;t+=1){const i=this.faces[t];i.mark===VISIBLE&&e.push(i)}this.faces=e}collectFaces(e){const t=[];for(let i=0;i<this.faces.length;i+=1){if(this.faces[i].mark!==VISIBLE)throw Error("attempt to include a destroyed face in the hull");const s=this.faces[i].collectIndices();if(e)t.push(s);else for(let e=0;e<s.length-2;e+=1)t.push([s[0],s[e+1],s[e+2]])}return t}nextVertexToAdd(){if(!this.claimed.isEmpty()){let e,t,i=0;const s=this.claimed.first().face;for(t=s.outside;t&&t.face===s;t=t.next){const o=s.distanceToPlane(t.point);o>i&&(i=o,e=t)}return e}}computeHorizon(e,t,i,s){let o;this.deleteFaceVertices(i),i.mark=DELETED,o=t?t.next:t=i.getEdge(0);do{const t=o.opposite,i=t.face;i.mark===VISIBLE&&(i.distanceToPlane(e)>this.tolerance?this.computeHorizon(e,t,i,s):s.push(o)),o=o.next}while(o!==t)}addAdjoiningFace(e,t){const i=Face.createTriangle(e,t.tail(),t.head());return this.faces.push(i),i.getEdge(-1).setOpposite(t.opposite),i.getEdge(0)}addNewFaces(e,t){let i,s;this.newFaces=[];for(let o=0;o<t.length;o+=1){const a=t[o],c=this.addAdjoiningFace(e,a);i?c.next.setOpposite(s):i=c,this.newFaces.push(c.face),s=c}i.next.setOpposite(s)}oppositeFaceDistance(e){return e.face.distanceToPlane(e.opposite.face.centroid)}doAdjacentMerge(e,t){let i=e.edge,s=!0,o=0;do{if(o>=e.nVertices)throw Error("merge recursion limit exceeded");const a=i.opposite.face;let c=!1;if(t===MERGE_NON_CONVEX?(this.oppositeFaceDistance(i)>-this.tolerance||this.oppositeFaceDistance(i.opposite)>-this.tolerance)&&(c=!0):e.area>a.area?this.oppositeFaceDistance(i)>-this.tolerance?c=!0:this.oppositeFaceDistance(i.opposite)>-this.tolerance&&(s=!1):this.oppositeFaceDistance(i.opposite)>-this.tolerance?c=!0:this.oppositeFaceDistance(i)>-this.tolerance&&(s=!1),c){const t=e.mergeAdjacentFaces(i,[]);for(let i=0;i<t.length;i+=1)this.deleteFaceVertices(t[i],e);return!0}i=i.next,o+=1}while(i!==e.edge);return s||(e.mark=NON_CONVEX),!1}addVertexToHull(e){const t=[];this.unclaimed.clear(),this.removeVertexFromFace(e,e.face),this.computeHorizon(e.point,null,e.face,t),this.addNewFaces(e,t);for(let e=0;e<this.newFaces.length;e+=1){const t=this.newFaces[e];if(t.mark===VISIBLE)for(;this.doAdjacentMerge(t,MERGE_NON_CONVEX_WRT_LARGER_FACE););}for(let e=0;e<this.newFaces.length;e+=1){const t=this.newFaces[e];if(t.mark===NON_CONVEX)for(t.mark=VISIBLE;this.doAdjacentMerge(t,MERGE_NON_CONVEX););}this.resolveUnclaimedPoints(this.newFaces)}build(){let e;for(this.createInitialSimplex();e=this.nextVertexToAdd();)this.addVertexToHull(e);this.reindexFaceAndVertices()}}module.exports=QuickHull;
1029
1032
 
1030
- },{"../../../maths/vec3/dot":217,"./Face":341,"./Vertex":344,"./VertexList":345,"./get-plane-normal":346,"./point-line-distance":348}],344:[function(require,module,exports){
1033
+ },{"../../../maths/vec3/dot":217,"./Face":342,"./Vertex":345,"./VertexList":346,"./get-plane-normal":347,"./point-line-distance":349}],345:[function(require,module,exports){
1031
1034
  class Vertex{constructor(t,e){this.point=t,this.index=e,this.next=null,this.prev=null,this.face=null}}module.exports=Vertex;
1032
1035
 
1033
- },{}],345:[function(require,module,exports){
1036
+ },{}],346:[function(require,module,exports){
1034
1037
  class VertexList{constructor(){this.head=null,this.tail=null}clear(){this.head=this.tail=null}insertBefore(e,t){t.prev=e.prev,t.next=e,t.prev?t.prev.next=t:this.head=t,e.prev=t}insertAfter(e,t){t.prev=e,t.next=e.next,t.next?t.next.prev=t:this.tail=t,e.next=t}add(e){this.head?this.tail.next=e:this.head=e,e.prev=this.tail,e.next=null,this.tail=e}addAll(e){for(this.head?this.tail.next=e:this.head=e,e.prev=this.tail;e.next;)e=e.next;this.tail=e}remove(e){e.prev?e.prev.next=e.next:this.head=e.next,e.next?e.next.prev=e.prev:this.tail=e.prev}removeChain(e,t){e.prev?e.prev.next=t.next:this.head=t.next,t.next?t.next.prev=e.prev:this.tail=e.prev}first(){return this.head}isEmpty(){return!this.head}}module.exports=VertexList;
1035
1038
 
1036
- },{}],346:[function(require,module,exports){
1039
+ },{}],347:[function(require,module,exports){
1037
1040
  const cross=require("../../../maths/vec3/cross"),normalize=require("../../../maths/vec3/normalize"),subtract=require("../../../maths/vec3/subtract"),planeNormal=(r,e,s,t)=>{const a=[0,0,0];return subtract(r,e,s),subtract(a,s,t),cross(r,r,a),normalize(r,r)};module.exports=planeNormal;
1038
1041
 
1039
- },{"../../../maths/vec3/cross":214,"../../../maths/vec3/normalize":229,"../../../maths/vec3/subtract":238}],347:[function(require,module,exports){
1042
+ },{"../../../maths/vec3/cross":214,"../../../maths/vec3/normalize":229,"../../../maths/vec3/subtract":238}],348:[function(require,module,exports){
1040
1043
  const QuickHull=require("./QuickHull"),runner=(u,l={})=>{const e=new QuickHull(u);return e.build(),e.collectFaces(l.skipTriangulation)};module.exports=runner;
1041
1044
 
1042
- },{"./QuickHull":343}],348:[function(require,module,exports){
1045
+ },{"./QuickHull":344}],349:[function(require,module,exports){
1043
1046
  const cross=require("../../../maths/vec3/cross"),subtract=require("../../../maths/vec3/subtract"),squaredLength=require("../../../maths/vec3/squaredLength"),distanceSquared=(e,t,r)=>{const s=[],a=[];subtract(s,r,t),subtract(a,e,t);const n=squaredLength(cross([],a,s)),c=squaredLength(s);if(0===c)throw Error("a and b are the same point");return n/c},pointLineDistance=(e,t,r)=>Math.sqrt(distanceSquared(e,t,r));module.exports=pointLineDistance;
1044
1047
 
1045
- },{"../../../maths/vec3/cross":214,"../../../maths/vec3/squaredLength":237,"../../../maths/vec3/subtract":238}],349:[function(require,module,exports){
1048
+ },{"../../../maths/vec3/cross":214,"../../../maths/vec3/squaredLength":237,"../../../maths/vec3/subtract":238}],350:[function(require,module,exports){
1046
1049
  const geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),toUniquePoints=o=>{const e=new Set,t=[],r=o=>{const r=o.toString();e.has(r)||(t.push(o),e.add(r))};return o.forEach(o=>{geom2.isA(o)?geom2.toPoints(o).forEach(r):geom3.isA(o)?geom3.toPoints(o).forEach(o=>o.forEach(r)):path2.isA(o)&&path2.toPoints(o).forEach(r)}),t};module.exports=toUniquePoints;
1047
1050
 
1048
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62}],350:[function(require,module,exports){
1051
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62}],351:[function(require,module,exports){
1049
1052
  const flatten=require("../../utils/flatten"),measureEpsilon=require("../../measurements/measureEpsilon"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),snapPolygons=require("./snapPolygons"),mergePolygons=require("./mergePolygons"),insertTjunctions=require("./insertTjunctions"),triangulatePolygons=require("./triangulatePolygons"),generalizePath2=(e,r)=>r,generalizeGeom2=(e,r)=>r,generalizeGeom3=(e,r)=>{const{snap:n,simplify:o,triangulate:t}=Object.assign({},{snap:!1,simplify:!1,triangulate:!1},e),i=measureEpsilon(r);let s=geom3.toPolygons(r);n&&(s=snapPolygons(i,s)),o&&(s=mergePolygons(i,s)),t&&(s=insertTjunctions(s),s=triangulatePolygons(i,s));const g=Object.assign({},r);return g.polygons=s,g},generalize=(e,...r)=>{if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");const n=r.map(r=>{if(path2.isA(r))return generalizePath2(0,r);if(geom2.isA(r))return generalizeGeom2(0,r);if(geom3.isA(r))return generalizeGeom3(e,r);throw new Error("invalid geometry")});return 1===n.length?n[0]:n};module.exports=generalize;
1050
1053
 
1051
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"./insertTjunctions":352,"./mergePolygons":353,"./snapPolygons":357,"./triangulatePolygons":358}],351:[function(require,module,exports){
1054
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"./insertTjunctions":353,"./mergePolygons":354,"./snapPolygons":358,"./triangulatePolygons":359}],352:[function(require,module,exports){
1052
1055
  module.exports={generalize:require("./generalize"),snap:require("./snap"),retessellate:require("./retessellate")};
1053
1056
 
1054
- },{"./generalize":350,"./retessellate":355,"./snap":356}],352:[function(require,module,exports){
1057
+ },{"./generalize":351,"./retessellate":356,"./snap":357}],353:[function(require,module,exports){
1055
1058
  const constants=require("../../maths/constants"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),assert=!1,getTag=e=>`${e}`,addSide=(e,t,s,n,r,c)=>{const o=getTag(n),g=getTag(r);const l=`${o}/${g}`,a=`${g}/${o}`;if(e.has(a))return deleteSide(e,t,s,r,n,null),null;const i={vertex0:n,vertex1:r,polygonindex:c};return e.has(l)?e.get(l).push(i):e.set(l,[i]),t.has(o)?t.get(o).push(l):t.set(o,[l]),s.has(g)?s.get(g).push(l):s.set(g,[l]),l},deleteSide=(e,t,s,n,r,c)=>{const o=getTag(n),g=getTag(r),l=`${o}/${g}`;let a=-1;const i=e.get(l);for(let e=0;e<i.length;e++){const t=i[e];let s=getTag(t.vertex0);if(s===o&&((s=getTag(t.vertex1))===g&&(null===c||t.polygonindex===c))){a=e;break}}i.splice(a,1),0===i.length&&e.delete(l),a=t.get(o).indexOf(l),t.get(o).splice(a,1),0===t.get(o).length&&t.delete(o),a=s.get(g).indexOf(l),s.get(g).splice(a,1),0===s.get(g).length&&s.delete(g)},insertTjunctions=e=>{const t=new Map;for(let s=0;s<e.length;s++){const n=e[s],r=n.vertices.length;if(r>=3){let e=n.vertices[0],c=getTag(e);for(let o=0;o<r;o++){let g=o+1;g===r&&(g=0);const l=n.vertices[g],a=getTag(l),i=`${c}/${a}`,v=`${a}/${c}`;if(t.has(v)){const e=t.get(v);e.splice(-1,1),0===e.length&&t.delete(v)}else{const n={vertex0:e,vertex1:l,polygonindex:s};t.has(i)?t.get(i).push(n):t.set(i,[n])}e=l,c=a}}else console.warn("warning: invalid polygon found during insertTjunctions")}if(t.size>0){const s=new Map,n=new Map,r=new Map;for(const[e,c]of t)r.set(e,!0),c.forEach(t=>{const r=getTag(t.vertex0),c=getTag(t.vertex1);s.has(r)?s.get(r).push(e):s.set(r,[e]),n.has(c)?n.get(c).push(e):n.set(c,[e])});const c=e.slice(0);for(;0!==t.size;){for(const e of t.keys())r.set(e,!0);let e=!1;for(;;){const o=Array.from(r.keys());if(0===o.length)break;const g=o[0];let l=!0;if(t.has(g)){const o=t.get(g);0;const a=o[0];for(let o=0;o<2;o++){const g=0===o?a.vertex0:a.vertex1,i=0===o?a.vertex1:a.vertex0,v=getTag(g),d=getTag(i);let h=[];0===o?n.has(v)&&(h=n.get(v)):s.has(v)&&(h=s.get(v));for(let a=0;a<h.length;a++){const v=h[a],f=t.get(v)[0],u=0===o?f.vertex0:f.vertex1,x=0===o?f.vertex1:f.vertex0,p=getTag(u);getTag(x);if(p===d){deleteSide(t,s,n,g,i,null),deleteSide(t,s,n,i,g,null),l=!1,o=2,e=!0;break}{const a=g,v=i,d=u,h=vec3.subtract(vec3.create(),d,a),x=vec3.dot(vec3.subtract(vec3.create(),v,a),h)/vec3.dot(h,h);if(x>0&&x<1){const g=vec3.scale(vec3.create(),h,x);if(vec3.add(g,g,a),vec3.squaredDistance(g,v)<constants.EPS*constants.EPS){const g=f.polygonindex,a=c[g],v=getTag(f.vertex1);let d=-1;for(let e=0;e<a.vertices.length;e++)if(getTag(a.vertices[e])===v){d=e;break}0;const h=a.vertices.slice(0);h.splice(d,0,i);const u=poly3.create(h);c[g]=u,deleteSide(t,s,n,f.vertex0,f.vertex1,g);const x=addSide(t,s,n,f.vertex0,i,g),p=addSide(t,s,n,i,f.vertex1,g);null!==x&&r.set(x,!0),null!==p&&r.set(p,!0),l=!1,o=2,e=!0;break}}}}}}l&&r.delete(g)}if(!e)break}e=c}return t.clear(),e};module.exports=insertTjunctions;
1056
1059
 
1057
- },{"../../geometries/poly3":79,"../../maths/constants":94,"../../maths/vec3":222}],353:[function(require,module,exports){
1060
+ },{"../../geometries/poly3":79,"../../maths/constants":94,"../../maths/vec3":222}],354:[function(require,module,exports){
1058
1061
  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;
1059
1062
 
1060
- },{"../../geometries/poly3":79,"../../maths/utils/aboutEqualNormals":167,"../../maths/vec3":222}],354:[function(require,module,exports){
1063
+ },{"../../geometries/poly3":79,"../../maths/utils/aboutEqualNormals":167,"../../maths/vec3":222}],355:[function(require,module,exports){
1061
1064
  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;
1062
1065
 
1063
- },{"../../geometries/poly3":79,"../../maths/OrthoNormalBasis":93,"../../maths/constants":94,"../../maths/line2":105,"../../maths/utils/interpolateBetween2DPointsForY":170,"../../maths/vec2":191,"../../utils":399}],355:[function(require,module,exports){
1066
+ },{"../../geometries/poly3":79,"../../maths/OrthoNormalBasis":93,"../../maths/constants":94,"../../maths/line2":105,"../../maths/utils/interpolateBetween2DPointsForY":170,"../../maths/vec2":191,"../../utils":400}],356:[function(require,module,exports){
1064
1067
  const geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),{NEPS:NEPS}=require("../../maths/constants"),reTesselateCoplanarPolygons=require("./reTesselateCoplanarPolygons"),retessellate=e=>{if(e.isRetesselated)return e;const s=geom3.toPolygons(e).map((e,s)=>({vertices:e.vertices,plane:poly3.plane(e),index:s})),o=classifyPolygons(s),l=[];o.forEach(e=>{if(Array.isArray(e)){const s=reTesselateCoplanarPolygons(e);l.push(...s)}else l.push(e)});const n=geom3.create(l);return n.isRetesselated=!0,n},classifyPolygons=e=>{let s=[e];const o=[];for(let e=3;e>=0;e--){const l=[],n=3===e?1.5e-8:NEPS;s.forEach(s=>{s.sort(byPlaneComponent(e,n));let t=0;for(let r=1;r<s.length;r++)s[r].plane[e]-s[t].plane[e]>n&&(r-t==1?o.push(s[t]):l.push(s.slice(t,r)),t=r);s.length-t==1?o.push(s[t]):l.push(s.slice(t))}),s=l}const l=[];return s.forEach(e=>{e[0]&&(l[e[0].index]=e)}),o.forEach(e=>{l[e.index]=e}),l},byPlaneComponent=(e,s)=>(o,l)=>o.plane[e]-l.plane[e]>s?1:l.plane[e]-o.plane[e]>s?-1:0;module.exports=retessellate;
1065
1068
 
1066
- },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/constants":94,"./reTesselateCoplanarPolygons":354}],356:[function(require,module,exports){
1069
+ },{"../../geometries/geom3":41,"../../geometries/poly3":79,"../../maths/constants":94,"./reTesselateCoplanarPolygons":355}],357:[function(require,module,exports){
1067
1070
  const flatten=require("../../utils/flatten"),vec2=require("../../maths/vec2"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),measureEpsilon=require("../../measurements/measureEpsilon"),snapPolygons=require("./snapPolygons"),snapPath2=e=>{const s=measureEpsilon(e),r=path2.toPoints(e).map(e=>vec2.snap(vec2.create(),e,s));return path2.create(r)},snapGeom2=e=>{const s=measureEpsilon(e);let r=geom2.toSides(e).map(e=>[vec2.snap(vec2.create(),e[0],s),vec2.snap(vec2.create(),e[1],s)]);return r=r.filter(e=>!vec2.equals(e[0],e[1])),geom2.create(r)},snapGeom3=e=>{const s=measureEpsilon(e),r=geom3.toPolygons(e),o=snapPolygons(s,r);return geom3.create(o)},snap=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const s=e.map(e=>path2.isA(e)?snapPath2(e):geom2.isA(e)?snapGeom2(e):geom3.isA(e)?snapGeom3(e):e);return 1===s.length?s[0]:s};module.exports=snap;
1068
1071
 
1069
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/vec2":191,"../../measurements/measureEpsilon":263,"../../utils/flatten":397,"./snapPolygons":357}],357:[function(require,module,exports){
1072
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/vec2":191,"../../measurements/measureEpsilon":263,"../../utils/flatten":398,"./snapPolygons":358}],358:[function(require,module,exports){
1070
1073
  const vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),isValidPoly3=(e,o)=>{const r=Math.abs(poly3.measureArea(o));return Number.isFinite(r)&&r>e},snapPolygons=(e,o)=>{let r=o.map(o=>{const r=o.vertices.map(o=>vec3.snap(vec3.create(),o,e)),t=[];for(let e=0;e<r.length;e++){const o=(e+1)%r.length;vec3.equals(r[e],r[o])||t.push(r[e])}const s=poly3.create(t);return o.color&&(s.color=o.color),s});const t=e*e*Math.sqrt(3)/4;return r=r.filter(e=>isValidPoly3(t,e))};module.exports=snapPolygons;
1071
1074
 
1072
- },{"../../geometries/poly3":79,"../../maths/vec3":222}],358:[function(require,module,exports){
1075
+ },{"../../geometries/poly3":79,"../../maths/vec3":222}],359:[function(require,module,exports){
1073
1076
  const vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),triangulatePolygon=(e,o,r)=>{const t=o.vertices.length;if(t>3){if(t>4){const c=[0,0,0];o.vertices.forEach(e=>vec3.add(c,c,e)),vec3.snap(c,vec3.divide(c,c,[t,t,t]),e);for(let e=0;e<t;e++){const s=poly3.create([c,o.vertices[e],o.vertices[(e+1)%t]]);o.color&&(s.color=o.color),r.push(s)}return}const c=poly3.create([o.vertices[0],o.vertices[1],o.vertices[2]]),s=poly3.create([o.vertices[0],o.vertices[2],o.vertices[3]]);return o.color&&(c.color=o.color,s.color=o.color),void r.push(c,s)}r.push(o)},triangulatePolygons=(e,o)=>{const r=[];return o.forEach(o=>{triangulatePolygon(e,o,r)}),r};module.exports=triangulatePolygons;
1074
1077
 
1075
- },{"../../geometries/poly3":79,"../../maths/vec3":222}],359:[function(require,module,exports){
1078
+ },{"../../geometries/poly3":79,"../../maths/vec3":222}],360:[function(require,module,exports){
1076
1079
  const flatten=require("../../utils/flatten"),padArrayToLength=require("../../utils/padArrayToLength"),measureAggregateBoundingBox=require("../../measurements/measureAggregateBoundingBox"),{translate:translate}=require("./translate"),validateOptions=e=>{if(!Array.isArray(e.modes)||e.modes.length>3)throw new Error("align(): modes must be an array of length <= 3");if(e.modes=padArrayToLength(e.modes,"none",3),3!==e.modes.filter(e=>["center","max","min","none"].includes(e)).length)throw new Error('align(): all modes must be one of "center", "max" or "min"');if(!Array.isArray(e.relativeTo)||e.relativeTo.length>3)throw new Error("align(): relativeTo must be an array of length <= 3");if(e.relativeTo=padArrayToLength(e.relativeTo,0,3),3!==e.relativeTo.filter(e=>Number.isFinite(e)||null==e).length)throw new Error("align(): all relativeTo values must be a number, or null.");if("boolean"!=typeof e.grouped)throw new Error("align(): grouped must be a boolean value.");return e},populateRelativeToFromBounds=(e,r,t)=>{for(let n=0;n<3;n++)null==e[n]&&("center"===r[n]?e[n]=(t[0][n]+t[1][n])/2:"max"===r[n]?e[n]=t[1][n]:"min"===r[n]&&(e[n]=t[0][n]));return e},alignGeometries=(e,r,t)=>{const n=measureAggregateBoundingBox(e),o=[0,0,0];for(let e=0;e<3;e++)"center"===r[e]?o[e]=t[e]-(n[0][e]+n[1][e])/2:"max"===r[e]?o[e]=t[e]-n[1][e]:"min"===r[e]&&(o[e]=t[e]-n[0][e]);return translate(o,e)},align=(e,...r)=>{e=Object.assign({},{modes:["center","center","min"],relativeTo:[0,0,0],grouped:!1},e),e=validateOptions(e);let{modes:t,relativeTo:n,grouped:o}=e;if(0===(r=flatten(r)).length)throw new Error("align(): No geometries were provided to act upon");if(n.filter(e=>null==e).length){const e=measureAggregateBoundingBox(r);n=populateRelativeToFromBounds(n,t,e)}return 1===(r=o?alignGeometries(r,t,n):r.map(e=>alignGeometries(e,t,n))).length?r[0]:r};module.exports=align;
1077
1080
 
1078
- },{"../../measurements/measureAggregateBoundingBox":254,"../../utils/flatten":397,"../../utils/padArrayToLength":401,"./translate":366}],360:[function(require,module,exports){
1081
+ },{"../../measurements/measureAggregateBoundingBox":254,"../../utils/flatten":398,"../../utils/padArrayToLength":402,"./translate":367}],361:[function(require,module,exports){
1079
1082
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),measureBoundingBox=require("../../measurements/measureBoundingBox"),{translate:translate}=require("./translate"),centerGeometry=(e,r)=>{const{axes:t,relativeTo:n}=Object.assign({},{axes:[!0,!0,!0],relativeTo:[0,0,0]},e),a=measureBoundingBox(r),o=[0,0,0];return t[0]&&(o[0]=n[0]-(a[0][0]+(a[1][0]-a[0][0])/2)),t[1]&&(o[1]=n[1]-(a[0][1]+(a[1][1]-a[0][1])/2)),t[2]&&(o[2]=n[2]-(a[0][2]+(a[1][2]-a[0][2])/2)),translate(o,r)},center=(e,...r)=>{const{axes:t,relativeTo:n}=Object.assign({},{axes:[!0,!0,!0],relativeTo:[0,0,0]},e);if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");if(3!==n.length)throw new Error("relativeTo must be an array of length 3");e={axes:t,relativeTo:n};const a=r.map(r=>path2.isA(r)?centerGeometry(e,r):geom2.isA(r)?centerGeometry(e,r):geom3.isA(r)?centerGeometry(e,r):r);return 1===a.length?a[0]:a},centerX=(...e)=>center({axes:[!0,!1,!1]},e),centerY=(...e)=>center({axes:[!1,!0,!1]},e),centerZ=(...e)=>center({axes:[!1,!1,!0]},e);module.exports={center:center,centerX:centerX,centerY:centerY,centerZ:centerZ};
1080
1083
 
1081
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../measurements/measureBoundingBox":258,"../../utils/flatten":397,"./translate":366}],361:[function(require,module,exports){
1084
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../measurements/measureBoundingBox":258,"../../utils/flatten":398,"./translate":367}],362:[function(require,module,exports){
1082
1085
  module.exports={align:require("./align"),center:require("./center").center,centerX:require("./center").centerX,centerY:require("./center").centerY,centerZ:require("./center").centerZ,mirror:require("./mirror").mirror,mirrorX:require("./mirror").mirrorX,mirrorY:require("./mirror").mirrorY,mirrorZ:require("./mirror").mirrorZ,rotate:require("./rotate").rotate,rotateX:require("./rotate").rotateX,rotateY:require("./rotate").rotateY,rotateZ:require("./rotate").rotateZ,scale:require("./scale").scale,scaleX:require("./scale").scaleX,scaleY:require("./scale").scaleY,scaleZ:require("./scale").scaleZ,transform:require("./transform"),translate:require("./translate").translate,translateX:require("./translate").translateX,translateY:require("./translate").translateY,translateZ:require("./translate").translateZ};
1083
1086
 
1084
- },{"./align":359,"./center":360,"./mirror":362,"./rotate":363,"./scale":364,"./transform":365,"./translate":366}],362:[function(require,module,exports){
1087
+ },{"./align":360,"./center":361,"./mirror":363,"./rotate":364,"./scale":365,"./transform":366,"./translate":367}],363:[function(require,module,exports){
1085
1088
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),plane=require("../../maths/plane"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),mirror=(r,...e)=>{const{origin:o,normal:m}=Object.assign({},{origin:[0,0,0],normal:[0,0,1]},r);if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const i=plane.fromNormalAndPoint(plane.create(),m,o);if(Number.isNaN(i[0]))throw new Error("the given origin and normal do not define a proper plane");const n=mat4.mirrorByPlane(mat4.create(),i),t=e.map(r=>path2.isA(r)?path2.transform(n,r):geom2.isA(r)?geom2.transform(n,r):geom3.isA(r)?geom3.transform(n,r):r);return 1===t.length?t[0]:t},mirrorX=(...r)=>mirror({normal:[1,0,0]},r),mirrorY=(...r)=>mirror({normal:[0,1,0]},r),mirrorZ=(...r)=>mirror({normal:[0,0,1]},r);module.exports={mirror:mirror,mirrorX:mirrorX,mirrorY:mirrorY,mirrorZ:mirrorZ};
1086
1089
 
1087
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../maths/plane":163,"../../utils/flatten":397}],363:[function(require,module,exports){
1090
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../maths/plane":163,"../../utils/flatten":398}],364:[function(require,module,exports){
1088
1091
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),rotate=(t,...e)=>{if(!Array.isArray(t))throw new Error("angles must be an array");if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");for(t=t.slice();t.length<3;)t.push(0);const r=t[2],o=t[1],a=t[0],m=mat4.fromTaitBryanRotation(mat4.create(),r,o,a),n=e.map(t=>path2.isA(t)?path2.transform(m,t):geom2.isA(t)?geom2.transform(m,t):geom3.isA(t)?geom3.transform(m,t):t);return 1===n.length?n[0]:n},rotateX=(t,...e)=>rotate([t,0,0],e),rotateY=(t,...e)=>rotate([0,t,0],e),rotateZ=(t,...e)=>rotate([0,0,t],e);module.exports={rotate:rotate,rotateX:rotateX,rotateY:rotateY,rotateZ:rotateZ};
1089
1092
 
1090
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":397}],364:[function(require,module,exports){
1093
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":398}],365:[function(require,module,exports){
1091
1094
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),scale=(e,...r)=>{if(!Array.isArray(e))throw new Error("factors must be an array");if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");for(e=e.slice();e.length<3;)e.push(1);if(e[0]<=0||e[1]<=0||e[2]<=0)throw new Error("factors must be positive");const a=mat4.fromScaling(mat4.create(),e),t=r.map(e=>path2.isA(e)?path2.transform(a,e):geom2.isA(e)?geom2.transform(a,e):geom3.isA(e)?geom3.transform(a,e):e);return 1===t.length?t[0]:t},scaleX=(e,...r)=>scale([e,1,1],r),scaleY=(e,...r)=>scale([1,e,1],r),scaleZ=(e,...r)=>scale([1,1,e],r);module.exports={scale:scale,scaleX:scaleX,scaleY:scaleY,scaleZ:scaleZ};
1092
1095
 
1093
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":397}],365:[function(require,module,exports){
1096
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":398}],366:[function(require,module,exports){
1094
1097
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),transform=(e,...r)=>{if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");const t=r.map(r=>path2.isA(r)?path2.transform(e,r):geom2.isA(r)?geom2.transform(e,r):geom3.isA(r)?geom3.transform(e,r):r);return 1===t.length?t[0]:t};module.exports=transform;
1095
1098
 
1096
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/flatten":397}],366:[function(require,module,exports){
1099
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../utils/flatten":398}],367:[function(require,module,exports){
1097
1100
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),translate=(t,...e)=>{if(!Array.isArray(t))throw new Error("offset must be an array");if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");for(t=t.slice();t.length<3;)t.push(0);const r=mat4.fromTranslation(mat4.create(),t),a=e.map(t=>path2.isA(t)?path2.transform(r,t):geom2.isA(t)?geom2.transform(r,t):geom3.isA(t)?geom3.transform(r,t):t);return 1===a.length?a[0]:a},translateX=(t,...e)=>translate([t,0,0],e),translateY=(t,...e)=>translate([0,t,0],e),translateZ=(t,...e)=>translate([0,0,t],e);module.exports={translate:translate,translateX:translateX,translateY:translateY,translateZ:translateZ};
1098
1101
 
1099
- },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":397}],367:[function(require,module,exports){
1102
+ },{"../../geometries/geom2":25,"../../geometries/geom3":41,"../../geometries/path2":62,"../../maths/mat4":143,"../../utils/flatten":398}],368:[function(require,module,exports){
1100
1103
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec2=require("../maths/vec2"),path2=require("../geometries/path2"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),arc=e=>{const r={center:[0,0],radius:1,startAngle:0,endAngle:TAU,makeTangent:!1,segments:32};let{center:t,radius:s,startAngle:n,endAngle:a,makeTangent:o,segments:c}=Object.assign({},r,e);if(!isNumberArray(t,2))throw new Error("center must be an array of X and Y values");if(!isGT(s,0))throw new Error("radius must be greater than zero");if(!isGTE(n,0))throw new Error("startAngle must be positive");if(!isGTE(a,0))throw new Error("endAngle must be positive");if(!isGTE(c,4))throw new Error("segments must be four or more");let i=TAU;(n%=TAU)<(a%=TAU)&&(i=a-n),n>a&&(i=a+(TAU-n));const m=Math.acos((s*s+s*s-EPS*EPS)/(2*s*s)),l=vec2.clone(t);let u;const A=[];if(i<m)u=vec2.fromAngleRadians(vec2.create(),n),vec2.scale(u,u,s),vec2.add(u,u,l),A.push(u);else{const e=Math.max(1,Math.floor(c*(i/TAU)))+1;let r=.5*e/i;r>.25&&(r=.25);const t=o?e+2:e;for(let a=0;a<=t;a++){let t=a;o&&((t=(a-1)*(e-2*r)/e+r)<0&&(t=0),t>e&&(t=e));const c=n+t*(i/e);u=vec2.fromAngleRadians(vec2.create(),c),vec2.scale(u,u,s),vec2.add(u,u,l),A.push(u)}}return path2.fromPoints({closed:!1},A)};module.exports=arc;
1101
1104
 
1102
- },{"../geometries/path2":62,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":369}],368:[function(require,module,exports){
1105
+ },{"../geometries/path2":62,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":370}],369:[function(require,module,exports){
1103
1106
  const{TAU:TAU}=require("../maths/constants"),ellipse=require("./ellipse"),{isGTE:isGTE}=require("./commonChecks"),circle=e=>{const s={center:[0,0],radius:1,startAngle:0,endAngle:TAU,segments:32};let{center:r,radius:t,startAngle:n,endAngle:i,segments:l}=Object.assign({},s,e);if(!isGTE(t,0))throw new Error("radius must be positive");return ellipse({center:r,radius:t=[t,t],startAngle:n,endAngle:i,segments:l})};module.exports=circle;
1104
1107
 
1105
- },{"../maths/constants":94,"./commonChecks":369,"./ellipse":374}],369:[function(require,module,exports){
1108
+ },{"../maths/constants":94,"./commonChecks":370,"./ellipse":375}],370:[function(require,module,exports){
1106
1109
  const isNumberArray=(i,r)=>!!(Array.isArray(i)&&i.length>=r)&&i.every(i=>Number.isFinite(i)),isGT=(i,r)=>Number.isFinite(i)&&i>r,isGTE=(i,r)=>Number.isFinite(i)&&i>=r;module.exports={isNumberArray:isNumberArray,isGT:isGT,isGTE:isGTE};
1107
1110
 
1108
- },{}],370:[function(require,module,exports){
1111
+ },{}],371:[function(require,module,exports){
1109
1112
  const cuboid=require("./cuboid"),{isGTE:isGTE}=require("./commonChecks"),cube=e=>{let{center:i,size:r}=Object.assign({},{center:[0,0,0],size:2},e);if(!isGTE(r,0))throw new Error("size must be positive");return cuboid({center:i,size:r=[r,r,r]})};module.exports=cube;
1110
1113
 
1111
- },{"./commonChecks":369,"./cuboid":371}],371:[function(require,module,exports){
1114
+ },{"./commonChecks":370,"./cuboid":372}],372:[function(require,module,exports){
1112
1115
  const geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{isNumberArray:isNumberArray}=require("./commonChecks"),cuboid=e=>{const{center:r,size:o}=Object.assign({},{center:[0,0,0],size:[2,2,2]},e);if(!isNumberArray(r,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(o,3))throw new Error("size must be an array of width, depth and height values");if(!o.every(e=>e>=0))throw new Error("size values must be positive");return 0===o[0]||0===o[1]||0===o[2]?geom3.create():geom3.create([[[0,4,6,2],[-1,0,0]],[[1,3,7,5],[1,0,0]],[[0,1,5,4],[0,-1,0]],[[2,6,7,3],[0,1,0]],[[0,2,3,1],[0,0,-1]],[[4,5,7,6],[0,0,1]]].map(e=>{const t=e[0].map(e=>{return[r[0]+o[0]/2*(2*!!(1&e)-1),r[1]+o[1]/2*(2*!!(2&e)-1),r[2]+o[2]/2*(2*!!(4&e)-1)]});return poly3.create(t)}))};module.exports=cuboid;
1113
1116
 
1114
- },{"../geometries/geom3":41,"../geometries/poly3":79,"./commonChecks":369}],372:[function(require,module,exports){
1117
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"./commonChecks":370}],373:[function(require,module,exports){
1115
1118
  const geom3=require("../geometries/geom3"),cylinderElliptic=require("./cylinderElliptic"),{isGTE:isGTE}=require("./commonChecks"),cylinder=e=>{const{center:i,height:r,radius:s,segments:t}=Object.assign({},{center:[0,0,0],height:2,radius:1,segments:32},e);if(!isGTE(s,0))throw new Error("radius must be positive");return 0===r||0===s?geom3.create():cylinderElliptic({center:i,height:r,startRadius:[s,s],endRadius:[s,s],segments:t})};module.exports=cylinder;
1116
1119
 
1117
- },{"../geometries/geom3":41,"./commonChecks":369,"./cylinderElliptic":373}],373:[function(require,module,exports){
1120
+ },{"../geometries/geom3":41,"./commonChecks":370,"./cylinderElliptic":374}],374:[function(require,module,exports){
1118
1121
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),cylinderElliptic=e=>{const r={center:[0,0,0],height:2,startRadius:[1,1],startAngle:0,endRadius:[1,1],endAngle:TAU,segments:32};let{center:s,height:t,startRadius:a,startAngle:i,endRadius:o,endAngle:n,segments:u}=Object.assign({},r,e);if(!isNumberArray(s,3))throw new Error("center must be an array of X, Y and Z values");if(!isGT(t,0))throw new Error("height must be greater then zero");if(!isNumberArray(a,2))throw new Error("startRadius must be an array of X and Y values");if(!a.every(e=>e>=0))throw new Error("startRadius values must be positive");if(!isNumberArray(o,2))throw new Error("endRadius must be an array of X and Y values");if(!o.every(e=>e>=0))throw new Error("endRadius values must be positive");if(o.every(e=>0===e)&&a.every(e=>0===e))throw new Error("at least one radius must be positive");if(!isGTE(i,0))throw new Error("startAngle must be positive");if(!isGTE(n,0))throw new Error("endAngle must be positive");if(!isGTE(u,4))throw new Error("segments must be four or more");let c=TAU;(i%=TAU)<(n%=TAU)&&(c=n-i),i>n&&(c=n+(TAU-i));const l=Math.min(a[0],a[1],o[0],o[1]),m=Math.acos((l*l+l*l-EPS*EPS)/(2*l*l));if(c<m)throw new Error("startAngle and endAngle do not define a significant rotation");const h=Math.floor(u*(c/TAU)),d=vec3.fromValues(0,0,-t/2),v=vec3.fromValues(0,0,t/2),f=vec3.subtract(vec3.create(),v,d),g=vec3.fromValues(1,0,0),p=vec3.fromValues(0,1,0),A=vec3.create(),w=vec3.create(),E=vec3.create(),y=(e,r,s)=>{const t=r*c+i;return vec3.scale(A,g,s[0]*cos(t)),vec3.scale(w,p,s[1]*sin(t)),vec3.add(A,A,w),vec3.scale(E,f,e),vec3.add(E,E,d),vec3.add(vec3.create(),A,E)},T=(...e)=>{const r=e.map(e=>vec3.add(vec3.create(),e,s));return poly3.create(r)},b=[];for(let e=0;e<h;e++){const r=e/h;let s=(e+1)/h;c===TAU&&e===h-1&&(s=0),o[0]===a[0]&&o[1]===a[1]?(b.push(T(d,y(0,s,o),y(0,r,o))),b.push(T(y(0,s,o),y(1,s,o),y(1,r,o),y(0,r,o))),b.push(T(v,y(1,r,o),y(1,s,o)))):(a[0]>0&&a[1]>0&&b.push(T(d,y(0,s,a),y(0,r,a))),(a[0]>0||a[1]>0)&&b.push(T(y(0,r,a),y(0,s,a),y(1,r,o))),o[0]>0&&o[1]>0&&b.push(T(v,y(1,r,o),y(1,s,o))),(o[0]>0||o[1]>0)&&b.push(T(y(1,r,o),y(0,s,a),y(1,s,o))))}return c<TAU&&(b.push(T(d,y(0,0,a),v)),b.push(T(y(0,0,a),y(1,0,o),v)),b.push(T(d,v,y(0,1,a))),b.push(T(y(0,1,a),v,y(1,1,o)))),geom3.create(b)};module.exports=cylinderElliptic;
1119
1122
 
1120
- },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":369}],374:[function(require,module,exports){
1123
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":370}],375:[function(require,module,exports){
1121
1124
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipse=e=>{const r={center:[0,0],radius:[1,1],startAngle:0,endAngle:TAU,segments:32};let{center:s,radius:t,startAngle:n,endAngle:o,segments:i}=Object.assign({},r,e);if(!isNumberArray(s,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(t,2))throw new Error("radius must be an array of X and Y values");if(!t.every(e=>e>=0))throw new Error("radius values must be positive");if(!isGTE(n,0))throw new Error("startAngle must be positive");if(!isGTE(o,0))throw new Error("endAngle must be positive");if(!isGTE(i,3))throw new Error("segments must be three or more");if(0===t[0]||0===t[1])return geom2.create();let a=TAU;(n%=TAU)<(o%=TAU)&&(a=o-n),n>o&&(a=o+(TAU-n));const m=Math.min(t[0],t[1]);if(a<Math.acos((m*m+m*m-EPS*EPS)/(2*m*m)))throw new Error("startAngle and endAngle do not define a significant rotation");i=Math.floor(i*(a/TAU));const u=vec2.clone(s),c=a/i,l=[];i=a<TAU?i+1:i;for(let e=0;e<i;e++){const r=c*e+n,s=vec2.fromValues(t[0]*cos(r),t[1]*sin(r));vec2.add(s,u,s),l.push(s)}return a<TAU&&l.push(u),geom2.fromPoints(l)};module.exports=ellipse;
1122
1125
 
1123
- },{"../geometries/geom2":25,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec2":191,"./commonChecks":369}],375:[function(require,module,exports){
1126
+ },{"../geometries/geom2":25,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec2":191,"./commonChecks":370}],376:[function(require,module,exports){
1124
1127
  const{TAU:TAU}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipsoid=e=>{const{center:c,radius:r,segments:s,axes:a}=Object.assign({},{center:[0,0,0],radius:[1,1,1],segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(r,3))throw new Error("radius must be an array of X, Y and Z values");if(!r.every(e=>e>=0))throw new Error("radius values must be positive");if(!isGTE(s,4))throw new Error("segments must be four or more");if(0===r[0]||0===r[1]||0===r[2])return geom3.create();const t=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),a[0]),r[0]),v=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),a[1]),r[1]),o=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),a[2]),r[2]),i=Math.round(s/4);let l;const u=[],d=vec3.create(),n=vec3.create();for(let e=0;e<=s;e++){const r=TAU*e/s,a=vec3.add(vec3.create(),vec3.scale(d,t,cos(r)),vec3.scale(n,v,sin(r)));if(e>0){let e,r;for(let s=0;s<=i;s++){const t=TAU/4*s/i,v=cos(t),m=sin(t);if(s>0){let t,h=[];t=vec3.subtract(vec3.create(),vec3.scale(d,l,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),t=vec3.subtract(vec3.create(),vec3.scale(d,a,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),s<i&&(t=vec3.subtract(vec3.create(),vec3.scale(d,a,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c))),t=vec3.subtract(vec3.create(),vec3.scale(d,l,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c)),u.push(poly3.create(h)),h=[],t=vec3.add(vec3.create(),vec3.scale(d,l,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),t=vec3.add(t,vec3.scale(d,a,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),s<i&&(t=vec3.add(t,vec3.scale(d,a,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t))),t=vec3.add(t,vec3.scale(d,l,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t)),h.reverse(),u.push(poly3.create(h))}e=v,r=m}}l=a}return geom3.create(u)};module.exports=ellipsoid;
1125
1128
 
1126
- },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":369}],376:[function(require,module,exports){
1129
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":370}],377:[function(require,module,exports){
1127
1130
  const mat4=require("../maths/mat4"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),polyhedron=require("./polyhedron"),{isGTE:isGTE}=require("./commonChecks"),geodesicSphere=e=>{let{radius:r,frequency:t}=Object.assign({},{radius:1,frequency:6},e);if(!isGTE(r,0))throw new Error("radius must be positive");if(!isGTE(t,6))throw new Error("frequency must be six or more");if(0===r)return geom3.create();t=Math.floor(t/6);const o=[[.850651,0,-.525731],[.850651,-0,.525731],[-.850651,-0,.525731],[-.850651,0,-.525731],[0,-.525731,.850651],[0,.525731,.850651],[0,.525731,-.850651],[0,-.525731,-.850651],[-.525731,-.850651,-0],[.525731,-.850651,-0],[.525731,.850651,0],[-.525731,.850651,0]],s=[[0,9,1],[1,10,0],[6,7,0],[10,6,0],[7,9,0],[5,1,4],[4,1,9],[5,10,1],[2,8,3],[3,11,2],[2,5,4],[4,8,2],[2,11,5],[3,7,6],[6,11,3],[8,7,3],[9,8,4],[11,10,5],[10,11,6],[8,9,7]],n=(e,r,t)=>{const o=e[0],s=e[1],n=e[2];let c=t;const f=[],l=[];for(let e=0;e<r;e++)for(let t=0;t<r-e;t++){const a=e/r,u=(e+1)/r,m=t/(r-e),h=(t+1)/(r-e),g=r-e-1?t/(r-e-1):1,p=[];p[0]=i(i(o,s,m),n,a),p[1]=i(i(o,s,h),n,a),p[2]=i(i(o,s,g),n,u);for(let e=0;e<3;e++){const r=vec3.length(p[e]);for(let t=0;t<3;t++)p[e][t]/=r}if(f.push(p[0],p[1],p[2]),l.push([c,c+1,c+2]),c+=3,t<r-e-1){const m=r-e-1?(t+1)/(r-e-1):1;p[0]=i(i(o,s,h),n,a),p[1]=i(i(o,s,m),n,u),p[2]=i(i(o,s,g),n,u);for(let e=0;e<3;e++){const r=vec3.length(p[e]);for(let t=0;t<3;t++)p[e][t]/=r}f.push(p[0],p[1],p[2]),l.push([c,c+1,c+2]),c+=3}}return{points:f,triangles:l,offset:c}},i=(e,r,t)=>{const o=1-t,s=[];for(let n=0;n<3;n++)s[n]=e[n]*o+r[n]*t;return s};let c=[],f=[],l=0;for(let e=0;e<s.length;e++){const r=n([o[s[e][0]],o[s[e][1]],o[s[e][2]]],t,l);c=c.concat(r.points),f=f.concat(r.triangles),l=r.offset}let a=polyhedron({points:c,faces:f,orientation:"inward"});return 1!==r&&(a=geom3.transform(mat4.fromScaling(mat4.create(),[r,r,r]),a)),a};module.exports=geodesicSphere;
1128
1131
 
1129
- },{"../geometries/geom3":41,"../maths/mat4":143,"../maths/vec3":222,"./commonChecks":369,"./polyhedron":380}],377:[function(require,module,exports){
1132
+ },{"../geometries/geom3":41,"../maths/mat4":143,"../maths/vec3":222,"./commonChecks":370,"./polyhedron":381}],378:[function(require,module,exports){
1130
1133
  module.exports={arc:require("./arc"),circle:require("./circle"),cube:require("./cube"),cuboid:require("./cuboid"),cylinder:require("./cylinder"),cylinderElliptic:require("./cylinderElliptic"),ellipse:require("./ellipse"),ellipsoid:require("./ellipsoid"),geodesicSphere:require("./geodesicSphere"),line:require("./line"),polygon:require("./polygon"),polyhedron:require("./polyhedron"),rectangle:require("./rectangle"),roundedCuboid:require("./roundedCuboid"),roundedCylinder:require("./roundedCylinder"),roundedRectangle:require("./roundedRectangle"),sphere:require("./sphere"),square:require("./square"),star:require("./star"),torus:require("./torus"),triangle:require("./triangle")};
1131
1134
 
1132
- },{"./arc":367,"./circle":368,"./cube":370,"./cuboid":371,"./cylinder":372,"./cylinderElliptic":373,"./ellipse":374,"./ellipsoid":375,"./geodesicSphere":376,"./line":378,"./polygon":379,"./polyhedron":380,"./rectangle":381,"./roundedCuboid":382,"./roundedCylinder":383,"./roundedRectangle":384,"./sphere":385,"./square":386,"./star":387,"./torus":388,"./triangle":389}],378:[function(require,module,exports){
1135
+ },{"./arc":368,"./circle":369,"./cube":371,"./cuboid":372,"./cylinder":373,"./cylinderElliptic":374,"./ellipse":375,"./ellipsoid":376,"./geodesicSphere":377,"./line":379,"./polygon":380,"./polyhedron":381,"./rectangle":382,"./roundedCuboid":383,"./roundedCylinder":384,"./roundedRectangle":385,"./sphere":386,"./square":387,"./star":388,"./torus":389,"./triangle":390}],379:[function(require,module,exports){
1133
1136
  const path2=require("../geometries/path2"),line=r=>{if(!Array.isArray(r))throw new Error("points must be an array");return path2.fromPoints({},r)};module.exports=line;
1134
1137
 
1135
- },{"../geometries/path2":62}],379:[function(require,module,exports){
1138
+ },{"../geometries/path2":62}],380:[function(require,module,exports){
1136
1139
  const geom2=require("../geometries/geom2"),polygon=r=>{const{points:o,paths:t,orientation:e}=Object.assign({},{points:[],paths:[],orientation:"counterclockwise"},r);if(!Array.isArray(o)||!Array.isArray(t))throw new Error("points and paths must be arrays");let s=o;Array.isArray(o[0])&&(Array.isArray(o[0][0])||(s=[o])),s.forEach((r,o)=>{if(!Array.isArray(r))throw new Error("list of points "+o+" must be an array");if(r.length<3)throw new Error("list of points "+o+" must contain three or more points");r.forEach((r,t)=>{if(!Array.isArray(r))throw new Error("list of points "+o+", point "+t+" must be an array");if(r.length<2)throw new Error("list of points "+o+", point "+t+" must contain by X and Y values")})});let a=t;if(0===t.length){let r=0;a=s.map(o=>o.map(o=>r++))}const n=[];s.forEach(r=>r.forEach(r=>n.push(r)));let i=[];a.forEach(r=>{const o=r.map(r=>n[r]),t=geom2.fromPoints(o);i=i.concat(geom2.toSides(t))});let c=geom2.create(i);return"clockwise"==e&&(c=geom2.reverse(c)),c};module.exports=polygon;
1137
1140
 
1138
- },{"../geometries/geom2":25}],380:[function(require,module,exports){
1141
+ },{"../geometries/geom2":25}],381:[function(require,module,exports){
1139
1142
  const geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{isNumberArray:isNumberArray}=require("./commonChecks"),polyhedron=r=>{const e={points:[],faces:[],colors:void 0,orientation:"outward"},{points:o,faces:a,colors:t,orientation:n}=Object.assign({},e,r);if(!Array.isArray(o)||!Array.isArray(a))throw new Error("points and faces must be arrays");if(o.length<3)throw new Error("three or more points are required");if(a.length<1)throw new Error("one or more faces are required");if(t){if(!Array.isArray(t))throw new Error("colors must be an array");if(t.length!==a.length)throw new Error("faces and colors must have the same length")}o.forEach((r,e)=>{if(!isNumberArray(r,3))throw new Error(`point ${e} must be an array of X, Y, Z values`)}),a.forEach((r,e)=>{if(r.length<3)throw new Error(`face ${e} must contain 3 or more indexes`);if(!isNumberArray(r,r.length))throw new Error(`face ${e} must be an array of numbers`)}),"outward"!==n&&a.forEach(r=>r.reverse());const s=a.map((r,e)=>{const a=poly3.create(r.map(r=>o[r]));return t&&t[e]&&(a.color=t[e]),a});return geom3.create(s)};module.exports=polyhedron;
1140
1143
 
1141
- },{"../geometries/geom3":41,"../geometries/poly3":79,"./commonChecks":369}],381:[function(require,module,exports){
1144
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"./commonChecks":370}],382:[function(require,module,exports){
1142
1145
  const vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isNumberArray:isNumberArray}=require("./commonChecks"),rectangle=e=>{const{center:r,size:t}=Object.assign({},{center:[0,0],size:[2,2]},e);if(!isNumberArray(r,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(t,2))throw new Error("size must be an array of X and Y values");if(!t.every(e=>e>=0))throw new Error("size values must be positive");if(0===t[0]||0===t[1])return geom2.create();const a=[t[0]/2,t[1]/2],c=[a[0],-a[1]],s=[vec2.subtract(vec2.create(),r,a),vec2.add(vec2.create(),r,c),vec2.add(vec2.create(),r,a),vec2.subtract(vec2.create(),r,c)];return geom2.fromPoints(s)};module.exports=rectangle;
1143
1146
 
1144
- },{"../geometries/geom2":25,"../maths/vec2":191,"./commonChecks":369}],382:[function(require,module,exports){
1147
+ },{"../geometries/geom2":25,"../maths/vec2":191,"./commonChecks":370}],383:[function(require,module,exports){
1145
1148
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),cuboid=require("./cuboid"),createCorners=(e,r,t,s,c,o)=>{const a=TAU/4*c/s,n=cos(a),i=sin(a),u=s-c;let l=t*n,h=r[2]-(t-t*i);o||(h=t-t*i-r[2]),l=l>EPS?l:0;const d=vec3.add(vec3.create(),e,[r[0]-t,r[1]-t,h]),v=vec3.add(vec3.create(),e,[t-r[0],r[1]-t,h]),m=vec3.add(vec3.create(),e,[t-r[0],t-r[1],h]),p=vec3.add(vec3.create(),e,[r[0]-t,t-r[1],h]),f=[],g=[],E=[],b=[];for(let e=0;e<=u;e++){const r=u>0?TAU/4*e/u:0,t=vec2.fromAngleRadians(vec2.create(),r);vec2.scale(t,t,l);const s=vec3.fromVec2(vec3.create(),t);f.push(vec3.add(vec3.create(),d,s)),vec3.rotateZ(s,s,[0,0,0],TAU/4),g.push(vec3.add(vec3.create(),v,s)),vec3.rotateZ(s,s,[0,0,0],TAU/4),E.push(vec3.add(vec3.create(),m,s)),vec3.rotateZ(s,s,[0,0,0],TAU/4),b.push(vec3.add(vec3.create(),p,s))}return o?[f,g,E,b]:(f.reverse(),g.reverse(),E.reverse(),b.reverse(),[b,E,g,f])},stitchCorners=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){const c=e[s],o=r[s];for(let e=0;e<c.length-1;e++)t.push(poly3.create([c[e],c[e+1],o[e]])),e<o.length-1&&t.push(poly3.create([o[e],c[e+1],o[e+1]]))}return t},stitchWalls=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){let c=e[s],o=r[s];const a=c[c.length-1],n=o[o.length-1],i=(s+1)%e.length;c=e[i],o=r[i];const u=c[0],l=o[0];t.push(poly3.create([a,u,l,n]))}return t},stitchSides=(e,r)=>{e=(e=[e[3],e[2],e[1],e[0]]).map(e=>e.slice().reverse());const t=[];e.forEach(e=>{e.forEach(e=>t.push(e))});const s=[];r.forEach(e=>{e.forEach(e=>s.push(e))});const c=[];for(let e=0;e<s.length;e++){const r=(e+1)%s.length;c.push(poly3.create([t[e],t[r],s[r],s[e]]))}return c},roundedCuboid=e=>{let{center:r,size:t,roundRadius:s,segments:c}=Object.assign({},{center:[0,0,0],size:[2,2,2],roundRadius:.2,segments:32},e);if(!isNumberArray(r,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(t,3))throw new Error("size must be an array of X, Y and Z values");if(!t.every(e=>e>=0))throw new Error("size values must be positive");if(!isGTE(s,0))throw new Error("roundRadius must be positive");if(!isGTE(c,4))throw new Error("segments must be four or more");if(0===t[0]||0===t[1]||0===t[2])return geom3.create();if(0===s)return cuboid({center:r,size:t});if(s>(t=t.map(e=>e/2))[0]-EPS||s>t[1]-EPS||s>t[2]-EPS)throw new Error("roundRadius must be smaller than the radius of all dimensions");c=Math.floor(c/4);let o=null,a=null,n=[];for(let e=0;e<=c;e++){const i=createCorners(r,t,s,c,e,!0),u=createCorners(r,t,s,c,e,!1);if(0===e&&(n=n.concat(stitchSides(u,i))),o&&(n=n.concat(stitchCorners(o,i),stitchWalls(o,i))),a&&(n=n.concat(stitchCorners(a,u),stitchWalls(a,u))),e===c){let e=i.map(e=>e[0]);n.push(poly3.create(e)),e=u.map(e=>e[0]),n.push(poly3.create(e))}o=i,a=u}return geom3.create(n)};module.exports=roundedCuboid;
1146
1149
 
1147
- },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec2":191,"../maths/vec3":222,"./commonChecks":369,"./cuboid":371}],383:[function(require,module,exports){
1150
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec2":191,"../maths/vec3":222,"./commonChecks":370,"./cuboid":372}],384:[function(require,module,exports){
1148
1151
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),cylinder=require("./cylinder"),roundedCylinder=e=>{const{center:c,height:r,radius:s,roundRadius:a,segments:t}=Object.assign({},{center:[0,0,0],height:2,radius:1,roundRadius:.2,segments:32},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isGTE(r,0))throw new Error("height must be positive");if(!isGTE(s,0))throw new Error("radius must be positive");if(!isGTE(a,0))throw new Error("roundRadius must be positive");if(a>s)throw new Error("roundRadius must be smaller than the radius");if(!isGTE(t,4))throw new Error("segments must be four or more");if(0===r||0===s)return geom3.create();if(0===a)return cylinder({center:c,height:r,radius:s});const v=[0,0,-r/2],o=[0,0,r/2],i=vec3.subtract(vec3.create(),o,v);if(2*a>vec3.length(i)-EPS)throw new Error("height must be larger than twice roundRadius");let u;u=Math.abs(i[0])>Math.abs(i[1])?vec3.fromValues(0,1,0):vec3.fromValues(1,0,0);const d=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),i),a),n=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),d,u)),s),l=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),n,d)),s);vec3.add(v,v,d),vec3.subtract(o,o,d);const h=Math.floor(.25*t),m=e=>{const r=e.map(e=>vec3.add(e,e,c));return poly3.create(r)},p=[],b=vec3.create(),f=vec3.create();let g;for(let e=0;e<=t;e++){const c=TAU*e/t,r=vec3.add(vec3.create(),vec3.scale(b,n,cos(c)),vec3.scale(f,l,sin(c)));if(e>0){let e,c,s=[];s.push(vec3.add(vec3.create(),v,r)),s.push(vec3.add(vec3.create(),v,g)),s.push(vec3.add(vec3.create(),o,g)),s.push(vec3.add(vec3.create(),o,r)),p.push(m(s));for(let a=0;a<=h;a++){const t=TAU/4*a/h,i=cos(t),u=sin(t);if(a>0){let t;s=[],t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,g,e),vec3.scale(f,d,c))),s.push(t),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,e),vec3.scale(f,d,c))),s.push(t),a<h&&(t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,i),vec3.scale(f,d,u))),s.push(t)),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,g,i),vec3.scale(f,d,u))),s.push(t),p.push(m(s)),s=[],t=vec3.add(vec3.create(),vec3.scale(b,g,e),vec3.scale(f,d,c)),vec3.add(t,t,o),s.push(t),t=vec3.add(vec3.create(),vec3.scale(b,r,e),vec3.scale(f,d,c)),vec3.add(t,t,o),s.push(t),a<h&&(t=vec3.add(vec3.create(),vec3.scale(b,r,i),vec3.scale(f,d,u)),vec3.add(t,t,o),s.push(t)),t=vec3.add(vec3.create(),vec3.scale(b,g,i),vec3.scale(f,d,u)),vec3.add(t,t,o),s.push(t),s.reverse(),p.push(m(s))}e=i,c=u}}g=r}return geom3.create(p)};module.exports=roundedCylinder;
1149
1152
 
1150
- },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":369,"./cylinder":372}],384:[function(require,module,exports){
1153
+ },{"../geometries/geom3":41,"../geometries/poly3":79,"../maths/constants":94,"../maths/utils/trigonometry":173,"../maths/vec3":222,"./commonChecks":370,"./cylinder":373}],385:[function(require,module,exports){
1151
1154
  const{EPS:EPS,TAU:TAU}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),rectangle=require("./rectangle"),roundedRectangle=e=>{let{center:r,size:t,roundRadius:a,segments:c}=Object.assign({},{center:[0,0],size:[2,2],roundRadius:.2,segments:32},e);if(!isNumberArray(r,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(t,2))throw new Error("size must be an array of X and Y values");if(!t.every(e=>e>=0))throw new Error("size values must be positive");if(!isGTE(a,0))throw new Error("roundRadius must be positive");if(!isGTE(c,4))throw new Error("segments must be four or more");if(0===t[0]||0===t[1])return geom2.create();if(0===a)return rectangle({center:r,size:t});if(a>(t=t.map(e=>e/2))[0]-EPS||a>t[1]-EPS)throw new Error("roundRadius must be smaller than the radius of all dimensions");const s=Math.floor(c/4),o=vec2.add(vec2.create(),r,[t[0]-a,t[1]-a]),n=vec2.add(vec2.create(),r,[a-t[0],t[1]-a]),i=vec2.add(vec2.create(),r,[a-t[0],a-t[1]]),u=vec2.add(vec2.create(),r,[t[0]-a,a-t[1]]),d=[],v=[],m=[],l=[];for(let e=0;e<=s;e++){const r=TAU/4*e/s,t=vec2.fromAngleRadians(vec2.create(),r);vec2.scale(t,t,a),d.push(vec2.add(vec2.create(),o,t)),vec2.rotate(t,t,vec2.create(),TAU/4),v.push(vec2.add(vec2.create(),n,t)),vec2.rotate(t,t,vec2.create(),TAU/4),m.push(vec2.add(vec2.create(),i,t)),vec2.rotate(t,t,vec2.create(),TAU/4),l.push(vec2.add(vec2.create(),u,t))}return geom2.fromPoints(d.concat(v,m,l))};module.exports=roundedRectangle;
1152
1155
 
1153
- },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":369,"./rectangle":381}],385:[function(require,module,exports){
1156
+ },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":370,"./rectangle":382}],386:[function(require,module,exports){
1154
1157
  const ellipsoid=require("./ellipsoid"),{isGTE:isGTE}=require("./commonChecks"),sphere=e=>{let{center:s,radius:r,segments:i,axes:t}=Object.assign({},{center:[0,0,0],radius:1,segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},e);if(!isGTE(r,0))throw new Error("radius must be positive");return ellipsoid({center:s,radius:r=[r,r,r],segments:i,axes:t})};module.exports=sphere;
1155
1158
 
1156
- },{"./commonChecks":369,"./ellipsoid":375}],386:[function(require,module,exports){
1159
+ },{"./commonChecks":370,"./ellipsoid":376}],387:[function(require,module,exports){
1157
1160
  const rectangle=require("./rectangle"),{isGTE:isGTE}=require("./commonChecks"),square=e=>{let{center:r,size:s}=Object.assign({},{center:[0,0],size:2},e);if(!isGTE(s,0))throw new Error("size must be positive");return rectangle({center:r,size:s=[s,s]})};module.exports=square;
1158
1161
 
1159
- },{"./commonChecks":369,"./rectangle":381}],387:[function(require,module,exports){
1162
+ },{"./commonChecks":370,"./rectangle":382}],388:[function(require,module,exports){
1160
1163
  const{TAU:TAU}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),getRadiusRatio=(e,r)=>e>0&&r>1&&r<e/2?Math.cos(Math.PI*r/e)/Math.cos(Math.PI*(r-1)/e):0,getPoints=(e,r,t,s)=>{const o=TAU/e,i=[];for(let a=0;a<e;a++){const e=vec2.fromAngleRadians(vec2.create(),o*a+t);vec2.scale(e,e,r),vec2.add(e,s,e),i.push(e)}return i},star=e=>{let{center:r,vertices:t,outerRadius:s,innerRadius:o,density:i,startAngle:a}=Object.assign({},{center:[0,0],vertices:5,outerRadius:1,innerRadius:0,density:2,startAngle:0},e);if(!isNumberArray(r,2))throw new Error("center must be an array of X and Y values");if(!isGTE(t,2))throw new Error("vertices must be two or more");if(!isGT(s,0))throw new Error("outerRadius must be greater than zero");if(!isGTE(o,0))throw new Error("innerRadius must be greater than zero");if(!isGTE(a,0))throw new Error("startAngle must be greater than zero");if(t=Math.floor(t),i=Math.floor(i),a%=TAU,0===o){if(!isGTE(i,2))throw new Error("density must be two or more");o=s*getRadiusRatio(t,i)}const n=vec2.clone(r),u=getPoints(t,s,a,n),c=getPoints(t,o,a+Math.PI/t,n),h=[];for(let e=0;e<t;e++)h.push(u[e]),h.push(c[e]);return geom2.fromPoints(h)};module.exports=star;
1161
1164
 
1162
- },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":369}],388:[function(require,module,exports){
1165
+ },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":370}],389:[function(require,module,exports){
1163
1166
  const{TAU:TAU}=require("../maths/constants"),extrudeRotate=require("../operations/extrusions/extrudeRotate"),{rotate:rotate}=require("../operations/transforms/rotate"),{translate:translate}=require("../operations/transforms/translate"),circle=require("./circle"),{isGT:isGT,isGTE:isGTE}=require("./commonChecks"),torus=e=>{const r={innerRadius:1,innerSegments:32,outerRadius:4,outerSegments:32,innerRotation:0,startAngle:0,outerRotation:TAU},{innerRadius:t,innerSegments:o,outerRadius:n,outerSegments:s,innerRotation:i,startAngle:a,outerRotation:u}=Object.assign({},r,e);if(!isGT(t,0))throw new Error("innerRadius must be greater than zero");if(!isGTE(o,3))throw new Error("innerSegments must be three or more");if(!isGT(n,0))throw new Error("outerRadius must be greater than zero");if(!isGTE(s,3))throw new Error("outerSegments must be three or more");if(!isGTE(a,0))throw new Error("startAngle must be positive");if(!isGT(u,0))throw new Error("outerRotation must be greater than zero");if(t>=n)throw new Error("inner circle is two large to rotate about the outer circle");let m=circle({radius:t,segments:o});return 0!==i&&(m=rotate([0,0,i],m)),m=translate([n,0],m),extrudeRotate({startAngle:a,angle:u,segments:s},m)};module.exports=torus;
1164
1167
 
1165
- },{"../maths/constants":94,"../operations/extrusions/extrudeRotate":316,"../operations/transforms/rotate":363,"../operations/transforms/translate":366,"./circle":368,"./commonChecks":369}],389:[function(require,module,exports){
1168
+ },{"../maths/constants":94,"../operations/extrusions/extrudeRotate":316,"../operations/transforms/rotate":364,"../operations/transforms/translate":367,"./circle":369,"./commonChecks":370}],390:[function(require,module,exports){
1166
1169
  const{NEPS:NEPS}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isNumberArray:isNumberArray}=require("./commonChecks"),solveAngleFromSSS=(e,r,t)=>Math.acos((e*e+r*r-t*t)/(2*e*r)),solveSideFromSAS=(e,r,t)=>r>NEPS?Math.sqrt(e*e+t*t-2*e*t*Math.cos(r)):Math.sqrt((e-t)*(e-t)+e*t*r*r*(1-r*r/12)),solveAAA=e=>{if(Math.abs(e[0]+e[1]+e[2]-Math.PI)>NEPS)throw new Error("AAA triangles require angles that sum to PI");const r=e[0],t=e[1],s=Math.PI-r-t,a=1/Math.sin(s)*Math.sin(r),n=1/Math.sin(s)*Math.sin(t);return createTriangle(r,t,s,a,n,1)},solveAAS=e=>{const r=e[0],t=e[1],s=Math.PI+NEPS-r-t;if(s<NEPS)throw new Error("AAS triangles require angles that sum to PI");const a=e[2],n=a/Math.sin(r)*Math.sin(t),o=a/Math.sin(r)*Math.sin(s);return createTriangle(r,t,s,a,n,o)},solveASA=e=>{const r=e[0],t=e[2],s=Math.PI+NEPS-r-t;if(s<NEPS)throw new Error("ASA triangles require angles that sum to PI");const a=e[1],n=a/Math.sin(s)*Math.sin(r),o=a/Math.sin(s)*Math.sin(t);return createTriangle(r,t,s,n,o,a)},solveSAS=e=>{const r=e[0],t=e[1],s=e[2],a=solveSideFromSAS(r,t,s),n=solveAngleFromSSS(a,r,s),o=Math.PI-n-t;return createTriangle(n,t,o,s,a,r)},solveSSA=e=>{const r=e[0],t=e[1],s=e[2],a=Math.asin(t*Math.sin(s)/r),n=Math.PI-a-s,o=r/Math.sin(s)*Math.sin(n);return createTriangle(a,n,s,t,o,r)},solveSSS=e=>{const r=e[1],t=e[2],s=e[0];if(r+t<=s||t+s<=r||s+r<=t)throw new Error("SSS triangle is incorrect, as the longest side is longer than the sum of the other sides");const a=solveAngleFromSSS(t,s,r),n=solveAngleFromSSS(s,r,t),o=Math.PI-a-n;return createTriangle(a,n,o,r,t,s)},createTriangle=(e,r,t,s,a,n)=>{const o=vec2.fromValues(0,0),i=vec2.fromValues(n,0),S=vec2.fromValues(s,0);return vec2.add(S,vec2.rotate(S,S,[0,0],Math.PI-r),i),geom2.fromPoints([o,i,S])},triangle=e=>{let{type:r,values:t}=Object.assign({},{type:"SSS",values:[1,1,1]},e);if("string"!=typeof r)throw new Error("triangle type must be a string");if("A"!==(r=r.toUpperCase())[0]&&"S"!==r[0]||"A"!==r[1]&&"S"!==r[1]||"A"!==r[2]&&"S"!==r[2])throw new Error("triangle type must contain three letters; A or S");if(!isNumberArray(t,3))throw new Error("triangle values must contain three values");if(!t.every(e=>e>0))throw new Error("triangle values must be greater than zero");switch(r){case"AAA":return solveAAA(t);case"AAS":return solveAAS(t);case"ASA":return solveASA(t);case"SAS":return solveSAS(t);case"SSA":return solveSSA(t);case"SSS":return solveSSS(t);default:throw new Error("invalid triangle type, try again")}};module.exports=triangle;
1167
1170
 
1168
- },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":369}],390:[function(require,module,exports){
1171
+ },{"../geometries/geom2":25,"../maths/constants":94,"../maths/vec2":191,"./commonChecks":370}],391:[function(require,module,exports){
1169
1172
  module.exports={height:14,32:[16],33:[10,5,21,5,7,void 0,5,2,4,1,5,0,6,1,5,2],34:[16,4,21,4,14,void 0,12,21,12,14],35:[21,11,25,4,-7,void 0,17,25,10,-7,void 0,4,12,18,12,void 0,3,6,17,6],36:[20,8,25,8,-4,void 0,12,25,12,-4,void 0,17,18,15,20,12,21,8,21,5,20,3,18,3,16,4,14,5,13,7,12,13,10,15,9,16,8,17,6,17,3,15,1,12,0,8,0,5,1,3,3],37:[24,21,21,3,0,void 0,8,21,10,19,10,17,9,15,7,14,5,14,3,16,3,18,4,20,6,21,8,21,10,20,13,19,16,19,19,20,21,21,void 0,17,7,15,6,14,4,14,2,16,0,18,0,20,1,21,3,21,5,19,7,17,7],38:[26,23,12,23,13,22,14,21,14,20,13,19,11,17,6,15,3,13,1,11,0,7,0,5,1,4,2,3,4,3,6,4,8,5,9,12,13,13,14,14,16,14,18,13,20,11,21,9,20,8,18,8,16,9,13,11,10,16,3,18,1,20,0,22,0,23,1,23,2],39:[10,5,19,4,20,5,21,6,20,6,18,5,16,4,15],40:[14,11,25,9,23,7,20,5,16,4,11,4,7,5,2,7,-2,9,-5,11,-7],41:[14,3,25,5,23,7,20,9,16,10,11,10,7,9,2,7,-2,5,-5,3,-7],42:[16,8,21,8,9,void 0,3,18,13,12,void 0,13,18,3,12],43:[26,13,18,13,0,void 0,4,9,22,9],44:[10,6,1,5,0,4,1,5,2,6,1,6,-1,5,-3,4,-4],45:[26,4,9,22,9],46:[10,5,2,4,1,5,0,6,1,5,2],47:[22,20,25,2,-7],48:[20,9,21,6,20,4,17,3,12,3,9,4,4,6,1,9,0,11,0,14,1,16,4,17,9,17,12,16,17,14,20,11,21,9,21],49:[20,6,17,8,18,11,21,11,0],50:[20,4,16,4,17,5,19,6,20,8,21,12,21,14,20,15,19,16,17,16,15,15,13,13,10,3,0,17,0],51:[20,5,21,16,21,10,13,13,13,15,12,16,11,17,8,17,6,16,3,14,1,11,0,8,0,5,1,4,2,3,4],52:[20,13,21,3,7,18,7,void 0,13,21,13,0],53:[20,15,21,5,21,4,12,5,13,8,14,11,14,14,13,16,11,17,8,17,6,16,3,14,1,11,0,8,0,5,1,4,2,3,4],54:[20,16,18,15,20,12,21,10,21,7,20,5,17,4,12,4,7,5,3,7,1,10,0,11,0,14,1,16,3,17,6,17,7,16,10,14,12,11,13,10,13,7,12,5,10,4,7],55:[20,17,21,7,0,void 0,3,21,17,21],56:[20,8,21,5,20,4,18,4,16,5,14,7,13,11,12,14,11,16,9,17,7,17,4,16,2,15,1,12,0,8,0,5,1,4,2,3,4,3,7,4,9,6,11,9,12,13,13,15,14,16,16,16,18,15,20,12,21,8,21],57:[20,16,14,15,11,13,9,10,8,9,8,6,9,4,11,3,14,3,15,4,18,6,20,9,21,10,21,13,20,15,18,16,14,16,9,15,4,13,1,10,0,8,0,5,1,4,3],58:[10,5,14,4,13,5,12,6,13,5,14,void 0,5,2,4,1,5,0,6,1,5,2],59:[10,5,14,4,13,5,12,6,13,5,14,void 0,6,1,5,0,4,1,5,2,6,1,6,-1,5,-3,4,-4],60:[24,20,18,4,9,20,0],61:[26,4,12,22,12,void 0,4,6,22,6],62:[24,4,18,20,9,4,0],63:[18,3,16,3,17,4,19,5,20,7,21,11,21,13,20,14,19,15,17,15,15,14,13,13,12,9,10,9,7,void 0,9,2,8,1,9,0,10,1,9,2],64:[27,18,13,17,15,15,16,12,16,10,15,9,14,8,11,8,8,9,6,11,5,14,5,16,6,17,8,void 0,12,16,10,14,9,11,9,8,10,6,11,5,void 0,18,16,17,8,17,6,19,5,21,5,23,7,24,10,24,12,23,15,22,17,20,19,18,20,15,21,12,21,9,20,7,19,5,17,4,15,3,12,3,9,4,6,5,4,7,2,9,1,12,0,15,0,18,1,20,2,21,3,void 0,19,16,18,8,18,6,19,5],65:[18,9,21,1,0,void 0,9,21,17,0,void 0,4,7,14,7],66:[21,4,21,4,0,void 0,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,void 0,4,11,13,11,16,10,17,9,18,7,18,4,17,2,16,1,13,0,4,0],67:[21,18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5],68:[21,4,21,4,0,void 0,4,21,11,21,14,20,16,18,17,16,18,13,18,8,17,5,16,3,14,1,11,0,4,0],69:[19,4,21,4,0,void 0,4,21,17,21,void 0,4,11,12,11,void 0,4,0,17,0],70:[18,4,21,4,0,void 0,4,21,17,21,void 0,4,11,12,11],71:[21,18,16,17,18,15,20,13,21,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,18,8,void 0,13,8,18,8],72:[22,4,21,4,0,void 0,18,21,18,0,void 0,4,11,18,11],73:[8,4,21,4,0],74:[16,12,21,12,5,11,2,10,1,8,0,6,0,4,1,3,2,2,5,2,7],75:[21,4,21,4,0,void 0,18,21,4,7,void 0,9,12,18,0],76:[17,4,21,4,0,void 0,4,0,16,0],77:[24,4,21,4,0,void 0,4,21,12,0,void 0,20,21,12,0,void 0,20,21,20,0],78:[22,4,21,4,0,void 0,4,21,18,0,void 0,18,21,18,0],79:[22,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21],80:[21,4,21,4,0,void 0,4,21,13,21,16,20,17,19,18,17,18,14,17,12,16,11,13,10,4,10],81:[22,9,21,7,20,5,18,4,16,3,13,3,8,4,5,5,3,7,1,9,0,13,0,15,1,17,3,18,5,19,8,19,13,18,16,17,18,15,20,13,21,9,21,void 0,12,4,18,-2],82:[21,4,21,4,0,void 0,4,21,13,21,16,20,17,19,18,17,18,15,17,13,16,12,13,11,4,11,void 0,11,11,18,0],83:[20,17,18,15,20,12,21,8,21,5,20,3,18,3,16,4,14,5,13,7,12,13,10,15,9,16,8,17,6,17,3,15,1,12,0,8,0,5,1,3,3],84:[16,8,21,8,0,void 0,1,21,15,21],85:[22,4,21,4,6,5,3,7,1,10,0,12,0,15,1,17,3,18,6,18,21],86:[18,1,21,9,0,void 0,17,21,9,0],87:[24,2,21,7,0,void 0,12,21,7,0,void 0,12,21,17,0,void 0,22,21,17,0],88:[20,3,21,17,0,void 0,17,21,3,0],89:[18,1,21,9,11,9,0,void 0,17,21,9,11],90:[20,17,21,3,0,void 0,3,21,17,21,void 0,3,0,17,0],91:[14,4,25,4,-7,void 0,5,25,5,-7,void 0,4,25,11,25,void 0,4,-7,11,-7],92:[14,0,21,14,-3],93:[14,9,25,9,-7,void 0,10,25,10,-7,void 0,3,25,10,25,void 0,3,-7,10,-7],94:[16,6,15,8,18,10,15,void 0,3,12,8,17,13,12,void 0,8,17,8,0],95:[16,0,-2,16,-2],96:[10,6,21,5,20,4,18,4,16,5,15,6,16,5,17],97:[19,15,14,15,0,void 0,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],98:[19,4,21,4,0,void 0,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3],99:[18,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],100:[19,15,21,15,0,void 0,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],101:[18,3,8,15,8,15,10,14,12,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],102:[12,10,21,8,21,6,20,5,17,5,0,void 0,2,14,9,14],103:[19,15,14,15,-2,14,-5,13,-6,11,-7,8,-7,6,-6,void 0,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],104:[19,4,21,4,0,void 0,4,10,7,13,9,14,12,14,14,13,15,10,15,0],105:[8,3,21,4,20,5,21,4,22,3,21,void 0,4,14,4,0],106:[10,5,21,6,20,7,21,6,22,5,21,void 0,6,14,6,-3,5,-6,3,-7,1,-7],107:[17,4,21,4,0,void 0,14,14,4,4,void 0,8,8,15,0],108:[8,4,21,4,0],109:[30,4,14,4,0,void 0,4,10,7,13,9,14,12,14,14,13,15,10,15,0,void 0,15,10,18,13,20,14,23,14,25,13,26,10,26,0],110:[19,4,14,4,0,void 0,4,10,7,13,9,14,12,14,14,13,15,10,15,0],111:[19,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3,16,6,16,8,15,11,13,13,11,14,8,14],112:[19,4,14,4,-7,void 0,4,11,6,13,8,14,11,14,13,13,15,11,16,8,16,6,15,3,13,1,11,0,8,0,6,1,4,3],113:[19,15,14,15,-7,void 0,15,11,13,13,11,14,8,14,6,13,4,11,3,8,3,6,4,3,6,1,8,0,11,0,13,1,15,3],114:[13,4,14,4,0,void 0,4,8,5,11,7,13,9,14,12,14],115:[17,14,11,13,13,10,14,7,14,4,13,3,11,4,9,6,8,11,7,13,6,14,4,14,3,13,1,10,0,7,0,4,1,3,3],116:[12,5,21,5,4,6,1,8,0,10,0,void 0,2,14,9,14],117:[19,4,14,4,4,5,1,7,0,10,0,12,1,15,4,void 0,15,14,15,0],118:[16,2,14,8,0,void 0,14,14,8,0],119:[22,3,14,7,0,void 0,11,14,7,0,void 0,11,14,15,0,void 0,19,14,15,0],120:[17,3,14,14,0,void 0,14,14,3,0],121:[16,2,14,8,0,void 0,14,14,8,0,6,-4,4,-6,2,-7,1,-7],122:[17,14,14,3,0,void 0,3,14,14,14,void 0,3,0,14,0],123:[14,9,25,7,24,6,23,5,21,5,19,6,17,7,16,8,14,8,12,6,10,void 0,7,24,6,22,6,20,7,18,8,17,9,15,9,13,8,11,4,9,8,7,9,5,9,3,8,1,7,0,6,-2,6,-4,7,-6,void 0,6,8,8,6,8,4,7,2,6,1,5,-1,5,-3,6,-5,7,-6,9,-7],124:[8,4,25,4,-7],125:[14,5,25,7,24,8,23,9,21,9,19,8,17,7,16,6,14,6,12,8,10,void 0,7,24,8,22,8,20,7,18,6,17,5,15,5,13,6,11,10,9,6,7,5,5,5,3,6,1,7,0,8,-2,8,-4,7,-6,void 0,8,8,6,6,6,4,7,2,8,1,9,-1,9,-3,8,-5,7,-6,5,-7],126:[24,3,6,3,8,4,11,6,12,8,12,10,11,14,8,16,7,18,7,20,8,21,10,void 0,3,8,4,10,6,11,8,11,10,10,14,7,16,6,18,6,20,7,21,10,21,12]};
1170
1173
 
1171
- },{}],391:[function(require,module,exports){
1174
+ },{}],392:[function(require,module,exports){
1172
1175
  module.exports={vectorChar:require("./vectorChar"),vectorText:require("./vectorText")};
1173
1176
 
1174
- },{"./vectorChar":392,"./vectorText":394}],392:[function(require,module,exports){
1177
+ },{"./vectorChar":393,"./vectorText":395}],393:[function(require,module,exports){
1175
1178
  const vectorParams=require("./vectorParams"),vectorChar=(t,e)=>{const{xOffset:r,yOffset:s,input:h,font:o,height:c,extrudeOffset:n}=vectorParams(t,e);let a=h.charCodeAt(0);a&&o[a]||(a=63);const f=[].concat(o[a]),i=(c-n)/o.height,u=n/2,g=f.shift()*i,l=[];let v=[];for(let t=0,e=f.length;t<e;t+=2){const e=i*f[t]+r,h=i*f[t+1]+s+u;void 0===f[t]?(l.push(v),v=[],t--):v.push([e,h])}return v.length&&l.push(v),{width:g,height:c,segments:l}};module.exports=vectorChar;
1176
1179
 
1177
- },{"./vectorParams":393}],393:[function(require,module,exports){
1180
+ },{"./vectorParams":394}],394:[function(require,module,exports){
1178
1181
  const defaultFont=require("./fonts/single-line/hershey/simplex.js"),defaultsVectorParams={xOffset:0,yOffset:0,input:"?",align:"left",font:defaultFont,height:14,lineSpacing:2.142857142857143,letterSpacing:1,extrudeOffset:0},vectorParams=(t,e)=>{e||"string"!=typeof t||(t={input:t}),t=t||{};const s=Object.assign({},defaultsVectorParams,t);return s.input=e||s.input,s};module.exports=vectorParams;
1179
1182
 
1180
- },{"./fonts/single-line/hershey/simplex.js":390}],394:[function(require,module,exports){
1183
+ },{"./fonts/single-line/hershey/simplex.js":391}],395:[function(require,module,exports){
1181
1184
  const vectorChar=require("./vectorChar"),vectorParams=require("./vectorParams"),translateLine=(t,e)=>{const{x:n,y:s}=Object.assign({x:0,y:0},t||{}),r=e.segments;let h=null,a=null;for(let t=0,e=r.length;t<e;t++)for(let e=0,o=(h=r[t]).length;e<o;e++)a=h[e],h[e]=[a[0]+n,a[1]+s];return e},vectorText=(t,e)=>{const{xOffset:n,yOffset:s,input:r,font:h,height:a,align:o,extrudeOffset:i,lineSpacing:c,letterSpacing:g}=vectorParams(t,e);let l,f,m,x,u,d,[v,w]=[n,s],O={width:0,segments:[]};const p=[];let y=[],C=0;const L=v,P=()=>{p.push(O),C=Math.max(C,O.width),O={width:0,segments:[]}};for(l=0,f=r.length;l<f;l++)m=r[l],x=vectorChar({xOffset:v,yOffset:w,font:h,height:a,extrudeOffset:i},m),"\n"!==m?(u=x.width*g,O.width+=u,v+=u," "!==m&&(O.segments=O.segments.concat(x.segments))):(v=L,w-=x.height*c,P());for(O.segments.length&&P(),l=0,f=p.length;l<f;l++)O=p[l],C>O.width&&(d=C-O.width,"right"===o?O=translateLine({x:d},O):"center"===o&&(O=translateLine({x:d/2},O))),y=y.concat(O.segments);return y};module.exports=vectorText;
1182
1185
 
1183
- },{"./vectorChar":392,"./vectorParams":393}],395:[function(require,module,exports){
1186
+ },{"./vectorChar":393,"./vectorParams":394}],396:[function(require,module,exports){
1184
1187
  const geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),areAllShapesTheSameType=e=>{let r;for(const o of e){let e=0;if(geom2.isA(o)&&(e=1),geom3.isA(o)&&(e=2),path2.isA(o)&&(e=3),r&&e!==r)return!1;r=e}return!0};module.exports=areAllShapesTheSameType;
1185
1188
 
1186
- },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62}],396:[function(require,module,exports){
1189
+ },{"../geometries/geom2":25,"../geometries/geom3":41,"../geometries/path2":62}],397:[function(require,module,exports){
1187
1190
  const degToRad=d=>.017453292519943295*d;module.exports=degToRad;
1188
1191
 
1189
- },{}],397:[function(require,module,exports){
1192
+ },{}],398:[function(require,module,exports){
1190
1193
  const flatten=t=>t.reduce((t,a)=>Array.isArray(a)?t.concat(flatten(a)):t.concat(a),[]);module.exports=flatten;
1191
1194
 
1192
- },{}],398:[function(require,module,exports){
1195
+ },{}],399:[function(require,module,exports){
1193
1196
  const fnNumberSort=(o,r)=>o-r;module.exports=fnNumberSort;
1194
1197
 
1195
- },{}],399:[function(require,module,exports){
1198
+ },{}],400:[function(require,module,exports){
1196
1199
  module.exports={areAllShapesTheSameType:require("./areAllShapesTheSameType"),degToRad:require("./degToRad"),flatten:require("./flatten"),fnNumberSort:require("./fnNumberSort"),insertSorted:require("./insertSorted"),radiusToSegments:require("./radiusToSegments"),radToDeg:require("./radToDeg")};
1197
1200
 
1198
- },{"./areAllShapesTheSameType":395,"./degToRad":396,"./flatten":397,"./fnNumberSort":398,"./insertSorted":400,"./radToDeg":402,"./radiusToSegments":403}],400:[function(require,module,exports){
1201
+ },{"./areAllShapesTheSameType":396,"./degToRad":397,"./flatten":398,"./fnNumberSort":399,"./insertSorted":401,"./radToDeg":403,"./radiusToSegments":404}],401:[function(require,module,exports){
1199
1202
  const insertSorted=(t,e,o)=>{let r=0,s=t.length;for(;s>r;){const l=Math.floor((r+s)/2);o(e,t[l])>0?r=l+1:s=l}t.splice(r,0,e)};module.exports=insertSorted;
1200
1203
 
1201
- },{}],401:[function(require,module,exports){
1204
+ },{}],402:[function(require,module,exports){
1202
1205
  const padArrayToLength=(r,e,o)=>{for(r=r.slice();r.length<o;)r.push(e);return r};module.exports=padArrayToLength;
1203
1206
 
1204
- },{}],402:[function(require,module,exports){
1207
+ },{}],403:[function(require,module,exports){
1205
1208
  const radToDeg=o=>57.29577951308232*o;module.exports=radToDeg;
1206
1209
 
1207
- },{}],403:[function(require,module,exports){
1210
+ },{}],404:[function(require,module,exports){
1208
1211
  const{TAU:TAU}=require("../maths/constants"),radiusToSegments=(t,e,s)=>{const a=e>0?t*TAU/e:0,n=s>0?TAU/s:0;return Math.ceil(Math.max(a,n,4))};module.exports=radiusToSegments;
1209
1212
 
1210
1213
  },{"../maths/constants":94}]},{},[92])(92)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/modeling",
3
- "version": "2.12.2",
3
+ "version": "2.12.3",
4
4
  "description": "Constructive Solid Geometry (CSG) Library for JSCAD",
5
5
  "homepage": "https://openjscad.xyz/",
6
6
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -61,5 +61,5 @@
61
61
  "nyc": "15.1.0",
62
62
  "uglifyify": "5.0.2"
63
63
  },
64
- "gitHead": "5fbb5fea458c28b0d96450dde9231e1d4d8ce6a4"
64
+ "gitHead": "4627312c2337120447a607ff3ac3da10056ce132"
65
65
  }
@@ -1,3 +1,4 @@
1
+ import Plane from '../../maths/plane/type'
1
2
  import Vec3 from '../../maths/vec3/type'
2
3
  import { Color } from '../types'
3
4
 
@@ -6,4 +7,5 @@ export default Poly3
6
7
  declare interface Poly3 {
7
8
  vertices: Array<Vec3>
8
9
  color?: Color
10
+ plane?: Plane
9
11
  }
@@ -3,5 +3,4 @@ import RecursiveArray from '../../utils/recursiveArray'
3
3
 
4
4
  export default scission
5
5
 
6
- declare function scission(...geometries: RecursiveArray<Geom2>): Geom2
7
- declare function scission(...geometries: RecursiveArray<Geom3>): Geom3
6
+ declare function scission(...geometries: RecursiveArray<Geom3>): Geom3[]
@@ -2,7 +2,9 @@ const test = require('ava')
2
2
 
3
3
  const { geom2, geom3, path2 } = require('../../geometries')
4
4
 
5
- const { sphere, cuboid, ellipsoid } = require('../../primitives')
5
+ const { measureVolume } = require('../../measurements')
6
+
7
+ const { sphere, cuboid, ellipsoid, torus } = require('../../primitives')
6
8
 
7
9
  const { center } = require('../transforms/center')
8
10
 
@@ -274,3 +276,9 @@ test('hull (multiple, overlapping, geom3)', (t) => {
274
276
  t.notThrows(() => geom3.validate(obs))
275
277
  t.is(pts.length, 92)
276
278
  })
279
+
280
+ test('hull (single, unconvex, geom3)', (t) => {
281
+ const geometry = torus()
282
+ const obs = hull(geometry)
283
+ t.assert(measureVolume(obs) > measureVolume(geometry))
284
+ })
@@ -7,6 +7,9 @@ const toUniquePoints = require('./toUniquePoints')
7
7
 
8
8
  /*
9
9
  * Create a convex hull of the given geom2 geometries.
10
+ *
11
+ * NOTE: The given geometries must be valid geom2 geometries.
12
+ *
10
13
  * @param {...geometries} geometries - list of geom2 geometries
11
14
  * @returns {geom2} new geometry
12
15
  */
@@ -1,32 +1,27 @@
1
1
  const flatten = require('../../utils/flatten')
2
2
 
3
3
  const geom3 = require('../../geometries/geom3')
4
- const poly3 = require('../../geometries/poly3')
5
4
 
6
- const quickhull = require('./quickhull')
7
5
  const toUniquePoints = require('./toUniquePoints')
6
+ const hullPoints3 = require('./hullPoints3')
8
7
 
9
8
  /*
10
- * Create a convex hull of the given geometries (geom3).
9
+ * Create a convex hull of the given geom3 geometries.
10
+ *
11
+ * NOTE: The given geometries must be valid geom3 geometries.
12
+ *
11
13
  * @param {...geometries} geometries - list of geom3 geometries
12
14
  * @returns {geom3} new geometry
13
15
  */
14
16
  const hullGeom3 = (...geometries) => {
15
17
  geometries = flatten(geometries)
16
18
 
17
- if (geometries.length === 1) return geometries[0]
18
-
19
19
  // extract the unique vertices from the geometries
20
20
  const unique = toUniquePoints(geometries)
21
21
 
22
- const faces = quickhull(unique, { skipTriangulation: true })
23
-
24
- const polygons = faces.map((face) => {
25
- const vertices = face.map((index) => unique[index])
26
- return poly3.create(vertices)
27
- })
22
+ if (unique.length === 0) return geom3.create()
28
23
 
29
- return geom3.create(polygons)
24
+ return geom3.create(hullPoints3(unique))
30
25
  }
31
26
 
32
27
  module.exports = hullGeom3
@@ -6,7 +6,10 @@ const hullPoints2 = require('./hullPoints2')
6
6
  const toUniquePoints = require('./toUniquePoints')
7
7
 
8
8
  /*
9
- * Create a convex hull of the given geometries (path2).
9
+ * Create a convex hull of the given path2 geometries.
10
+ *
11
+ * NOTE: The given geometries must be valid path2 geometry.
12
+ *
10
13
  * @param {...geometries} geometries - list of path2 geometries
11
14
  * @returns {path2} new geometry
12
15
  */
@@ -0,0 +1,5 @@
1
+ import Vec2 from '../../maths/vec2/type'
2
+
3
+ export default hullPoints2
4
+
5
+ declare function hullPoints2(uniquePoints: Array<Vec2>): Array<Vec2>
@@ -1,10 +1,12 @@
1
1
  const vec2 = require('../../maths/vec2')
2
2
 
3
- /*
3
+ /**
4
4
  * Create a convex hull of the given set of points, where each point is an array of [x,y].
5
- * Uses https://en.wikipedia.org/wiki/Graham_scan
5
+ * @see https://en.wikipedia.org/wiki/Graham_scan
6
+ *
6
7
  * @param {Array} uniquePoints - list of UNIQUE points from which to create a hull
7
8
  * @returns {Array} a list of points that form the hull
9
+ * @alias module:modeling/hulls.hullPoints2
8
10
  */
9
11
  const hullPoints2 = (uniquePoints) => {
10
12
  // find min point
@@ -0,0 +1,6 @@
1
+ import Vec3 from '../../maths/vec3/type'
2
+ import Poly3 from '../../geometries/poly3/type'
3
+
4
+ export default hullPoints3
5
+
6
+ declare function hullPoints3(uniquePoints: Array<Vec3>): Array<Poly3>
@@ -0,0 +1,23 @@
1
+ const poly3 = require('../../geometries/poly3')
2
+
3
+ const quickhull = require('./quickhull')
4
+
5
+ /**
6
+ * Create a convex hull of the given set of points, where each point is an array of [x,y,z].
7
+ *
8
+ * @param {Array} uniquePoints - list of UNIQUE points from which to create a hull
9
+ * @returns {Array} a list of polygons (poly3)
10
+ * @alias module:modeling/hulls.hullPoints3
11
+ */
12
+ const hullPoints3 = (uniquePoints) => {
13
+ const faces = quickhull(uniquePoints, { skipTriangulation: true })
14
+
15
+ const polygons = faces.map((face) => {
16
+ const vertices = face.map((index) => uniquePoints[index])
17
+ return poly3.create(vertices)
18
+ })
19
+
20
+ return polygons
21
+ }
22
+
23
+ module.exports = hullPoints3
@@ -1,4 +1,6 @@
1
1
  export { default as hull } from './hull'
2
2
  export { default as hullChain } from './hullChain'
3
+ export { default as hullPoints2 } from './hullPoints2'
4
+ export { default as hullPoints3 } from './hullPoints3'
3
5
 
4
6
  export as namespace hulls
@@ -8,5 +8,7 @@
8
8
  */
9
9
  module.exports = {
10
10
  hull: require('./hull'),
11
- hullChain: require('./hullChain')
11
+ hullChain: require('./hullChain'),
12
+ hullPoints2: require('./hullPoints2'),
13
+ hullPoints3: require('./hullPoints3')
12
14
  }