diff --git a/build/verb.js b/build/verb.js index a057b8aa..f441389e 100644 --- a/build/verb.js +++ b/build/verb.js @@ -26,7 +26,7 @@ verb.eval.mesh = verb.eval.mesh || {}; // ####verb.EPSILON // // Used for numeric comparisons -verb.EPSILON = 1e-8; +verb.EPSILON = 1e-10; // ####verb.TOLERANCE // @@ -3594,14 +3594,12 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de }; // todo: need to be able to predict the number of divisions - var tessOptions = { minDivsU: 20, minDivsV: 20, tol: 5e-2 }; var tess1 = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj1.degree_u, srfObj1.knots_u, srfObj1.degree_v, srfObj1.knots_v, - srfObj1.homo_control_points, - tessOptions ); + srfObj1.homo_control_points); var srfObj2 = { degree_u : degree_u2, @@ -3615,8 +3613,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de srfObj2.knots_u, srfObj2.degree_v, srfObj2.knots_v, - srfObj2.homo_control_points, - tessOptions ); + srfObj2.homo_control_points); var resApprox = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, tess1.uvs, tess2.points, tess2.faces, tess2.uvs ); @@ -3630,7 +3627,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de // 3) perform cubic interpolation return exactPls.map(function(x){ - return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 2 ); + return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 3 ); }); // TODO: represent this in uv space @@ -3660,11 +3657,10 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points res[1].tri2id = ids[1]; return res; - }) - .filter(function(x){ return x; }) + }).filter(function(x){ return x; }) .filter(function(x){ var dif = numeric.sub( x[0].pt, x[1].pt ); - return numeric.dot( dif, dif ) > verb.TOLERANCE + return numeric.dot( dif, dif ) > verb.EPSILON }); // TODO: this is too expensive and this only occurs when the intersection @@ -3684,8 +3680,8 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points var s4 = numeric.sub( a[1].uvtri1, b[0].uvtri1 ); var d4 = numeric.dot( s4, s4 ); - return ( d1 < verb.TOLERANCE && d2 < verb.TOLERANCE ) || - ( d3 < verb.TOLERANCE && d4 < verb.TOLERANCE ); + return ( d1 < verb.EPSILON && d2 < verb.EPSILON ) || + ( d3 < verb.EPSILON && d4 < verb.EPSILON ); }); @@ -3805,7 +3801,7 @@ verb.eval.mesh.lookup_adj_segment = function( segEnd, tree, numSegments ) { // we expect one result to be self, one to be neighbor and no more var adj = tree.nearest({ x: segEnd.pt[0], y: segEnd.pt[1], z: segEnd.pt[2] }, numResults) .filter(function(r){ - return segEnd != r[0].ele && r[1] < verb.TOLERANCE; + return segEnd != r[0].ele && r[1] < verb.EPSILON; }) .map(function(r){ return r[0].ele; }); @@ -4760,14 +4756,6 @@ verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide = function( option this.splitHoriz = numeric.norm2Squared( numeric.sub( this.corners[1].normal, this.corners[2].normal ) ) > options.normTol || numeric.norm2Squared( numeric.sub( this.corners[3].normal, this.corners[0].normal ) ) > options.normTol; - // is curved in u direction? - // this.splitVert = verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[0].point, this.corners[1].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[2].point, this.midpoints[2].point, this.corners[3].point ) > options.edgeTol; - - // // is curved in v direction? - // this.splitHoriz = verb.eval.nurbs.dist_to_seg( this.corners[1].point, this.midpoints[1].point, this.corners[2].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[3].point, this.corners[3].point ) > options.edgeTol; - if ( this.splitVert || this.splitHoriz ) return true; var center = this.center(); diff --git a/build/verb.min.js b/build/verb.min.js index fbd27866..56700302 100644 --- a/build/verb.min.js +++ b/build/verb.min.js @@ -1,4 +1,4 @@ /*! verb 2014-11-29 */ -"use strict";function Node(e,r,n){this.obj=e,this.left=null,this.right=null,this.parent=n,this.dimension=r}function KdTree(e,r,n){function t(e,r,i){var s,o,u=r%n.length;return 0===e.length?null:1===e.length?new Node(e[0],u,i):(e.sort(function(e,r){return e[n[u]]-r[n[u]]}),s=Math.floor(e.length/2),o=new Node(e[s],u,i),o.left=t(e.slice(0,s),r+1,o),o.right=t(e.slice(s+1),r+1,o),o)}var i=this;this.root=t(e,0,null),this.insert=function(e){function r(t,i){if(null===t)return i;var s=n[t.dimension];return e[s]s&&(a=o),null!==u&&u.obj[i]>a.obj[i]&&(a=u),a))}function s(e,r){var t,i,o,u,a;return null===e?null:(t=n[r],e.dimension===r?null!==e.left?s(e.left,r):e:(i=e.obj[t],o=s(e.left,r),u=s(e.right,r),a=e,null!==o&&i>o.obj[t]&&(a=o),null!==u&&u.obj[t]t&&v.pop()}var u,a,l,c,h=n[i.dimension],b=r(e,i.obj),m={};for(c=0;n.length>c;c+=1)m[n[c]]=c===i.dimension?e[n[c]]:i.obj[n[c]];return a=r(m,i.obj),null===i.right&&null===i.left?((t>v.size()||v.peek()[1]>b)&&s(i,b),void 0):(u=null===i.right?i.left:null===i.left?i.right:e[h]v.size()||v.peek()[1]>b)&&s(i,b),(t>v.size()||Math.abs(a)u;u+=1)v.push([null,s]);for(o(i.root),a=[],u=0;t>u;u+=1)v.content[u][0]&&a.push([v.content[u][0].obj,v.content[u][1]]);return a},this.balanceFactor=function(){function e(r){return null===r?0:Math.max(e(r.left),e(r.right))+1}function r(e){return null===e?0:r(e.left)+r(e.right)+1}return e(i.root)/(Math.log(r(i.root))/Math.log(2))}}function BinaryHeap(e){this.content=[],this.scoreFunction=e}function crossprod(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]}if("object"!=typeof exports||void 0===exports)var verb={},numeric=window.numeric,binomial=window.binomial,labor=window.labor;else var verb=module.exports={},numeric=require("numeric"),binomial=require("binomial"),labor=require("labor");verb.geom=verb.geom||{},verb.core=verb.core||{},verb.eval=verb.eval||{},verb.intersect=verb.intersect||{},verb.eval.nurbs=verb.eval.nurbs||{},verb.eval.geom=verb.eval.geom||{},verb.eval.mesh=verb.eval.mesh||{},verb.EPSILON=1e-8,verb.TOLERANCE=1e-6,verb.init=function(){verb.nurbsEngine=new verb.core.Engine(verb.eval.nurbs),verb.geom.NurbsGeometry.prototype.nurbsEngine=verb.nurbsEngine},Function.prototype.method=function(e,r){return this.prototype[e]=r,this},Function.method("inherits",function(e){return this.prototype=new e,this.prototype,this.prototype.constructor=e,this}),Array.prototype.flatten=function(){if(0==this.length)return[];for(var e=[],r=0;this.length>r;r++)e=this[r]instanceof Array?e.concat(this[r].flatten()):e.concat(this[r]);return e},numeric.normalized=function(e){return numeric.div(e,numeric.norm2(e))},numeric.cross=function(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]},verb.left=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(0,r)},verb.right=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r)},verb.last=function(e){return e.length?e[e.length-1]:void 0},verb.rightWithPivot=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r-1)},verb.unique=function(e,r){if(0===e.length)return[];for(var n=[e.pop()];e.length>0;){for(var t=e.pop(),i=!0,s=0;n.length>s;s++)if(r(t,n[s])){i=!1;break}i&&n.push(t)}return n},verb.range=function(e,r,n){1>=arguments.length&&(r=e||0,e=0),n=arguments[2]||1;for(var t=Math.max(Math.ceil((r-e)/n),0),i=0,s=Array(t);t>i;)s[i++]=e,e+=n;return s},BinaryHeap.prototype={push:function(e){this.content.push(e),this.bubbleUp(this.content.length-1)},pop:function(){var e=this.content[0],r=this.content.pop();return this.content.length>0&&(this.content[0]=r,this.sinkDown(0)),e},peek:function(){return this.content[0]},remove:function(e){for(var r=this.content.length,n=0;r>n;n++)if(this.content[n]==e){var t=this.content.pop();return n!=r-1&&(this.content[n]=t,this.scoreFunction(t)0;){var n=Math.floor((e+1)/2)-1,t=this.content[n];if(!(this.scoreFunction(r)s){var u=this.content[s],a=this.scoreFunction(u);t>a&&(o=s)}if(r>i){var v=this.content[i],l=this.scoreFunction(v);(null==o?t:a)>l&&(o=i)}if(null==o)break;this.content[e]=this.content[o],this.content[o]=n,e=o}}},verb.core.Engine=function(e){var r="function"==typeof Worker&&(e.use_pool||void 0===e.use_pool),n=e.num_workers||2,t=e.tolerance||1e-4,i=e.url||"js/verbEval.js",s=e.library||verb.eval.nurbs,o=e.error_handler||function(e){console.warn(e)},u=void 0,a=function(){try{u=new labor.Pool(i,n),u.start()}catch(e){return o("Failed to initialize labor.Pool: "+e),!1}return!0},v=function(e,r){return s[e].apply(null,r)};this.start=function(){r&&a()},this.eval=function(e,n,t){return t?(r&&(u||void 0===u&&a())?u.addWork(e,n,t):setTimeout(function(){t(v(e,n))},0),void 0):v(e,n)},this.setTolerance=function(e){t=e},this.setUsePool=function(e){return e&&void 0===u&&a()?(r=e,!0):e?!1:(u=null,!0)},this.setErrorHandler=function(e){o=e},this.setNumThreads=function(e){n=e}},verb.core.WatchObject=function(){var e={change:{}},r={},n=0,t=this,i=function(r,n){if("string"==typeof r){for(var t in e[r])e[r][t](n);for(var t in e.change)e.change[t](n)}else for(var s in r)i(s,n)};this.get=function(e){return r[e]},this.set=function(n,s){var o=r[n];r[n]=s,e[n]=e[n]||{},i(n,{name:n,old:o,"new":s,target:t,type:"full"})},this.setAll=function(n){var s={};for(var o in n)s[o]=r[o],r[o]=n[o],e[o]=e[o]||{};i(n,{old:s,"new":n,target:t,type:"multi"})},this.setAt=function(e,n,s){var o=r[e];if(!(void 0===o||o.length>=n||0>n)){var u=r[e][n];r[e][n]=s,i(e,{name:e,index:n,old:u,"new":s,target:t,type:"index"})}},this.watch=function(t,i){return void 0!==r[t]&&i?(n++,e[t][n]=i,n++):void 0},this.watchAll=function(e,r){for(var n=[],t=0;e.length>t;t++)n.push(this.watch(e[t],r));return n},this.ignore=function(r,n){void 0!==e[r]&&void 0!==e[r][n]&&(e[r][n]=void 0)}},verb.core.uid=function(){var e=0;return function(){return e++}}(),verb.geom.Geometry=function(){verb.core.WatchObject.call(this);var e=verb.core.uid();this.uniqueId=function(){return e}}.inherits(verb.core.WatchObject),verb.geom.NurbsGeometry=function(){verb.geom.Geometry.call(this)}.inherits(verb.geom.Geometry),verb.geom.NurbsCurve=function(e,r,n,t){verb.geom.NurbsGeometry.call(this),this.setAll({controlPoints:r,weights:n,knots:t?t.slice(0):[],degree:e})}.inherits(verb.geom.NurbsGeometry),verb.geom.NurbsCurve.prototype.point=function(e,r){return this.nurbsEngine.eval("rational_curve_point",[this.get("degree"),this.get("knots"),this.homogenize(),e],r)},verb.geom.NurbsCurve.prototype.derivatives=function(e,r,n){return this.nurbsEngine.eval("rational_curve_derivs",[this.get("degree"),this.get("knots"),this.homogenize(),e,r||1],n)},verb.geom.NurbsCurve.prototype.tessellate=function(e,r){var e=e||{};return e.tolerance=e.tolerance||verb.EPSILON,this.nurbsEngine.eval("rational_curve_adaptive_sample",[this.get("degree"),this.get("knots"),this.homogenize(),e.tolerance],r)},verb.geom.NurbsCurve.prototype.split=function(e,r){function n(e){var r=verb.eval.nurbs.dehomogenize_1d(e[0].control_points),n=verb.eval.nurbs.weight_1d(e[0].control_points),t=new verb.geom.NurbsCurve(e[0].degree,r,n,e[0].knots),i=verb.eval.nurbs.dehomogenize_1d(e[1].control_points),s=verb.eval.nurbs.weight_1d(e[1].control_points),o=new verb.geom.NurbsCurve(e[1].degree,i,s,e[1].knots);return[t,o]}var t=this.domain();if(t[0]>=e||e>=t[1])throw Error("Cannot split outside of the domain of the curve!");return r?this.nurbsEngine.eval("curve_split",[this.get("degree"),this.get("knots"),this.homogenize(),e],function(e){return r(n(e))}):n(this.nurbsEngine.eval("curve_split",[this.get("degree"),this.get("knots"),this.homogenize(),e]))},verb.geom.NurbsCurve.prototype.domain=function(){var e=this.get("knots");return[e[0],e[e.length-1]]},verb.geom.NurbsCurve.prototype.transform=function(e){for(var r=this.get("controlPoints"),n=0;r.length>n;n++){var t=r[1].push(1);r[n]=numeric.mul(e,t).slice(0,t.length-2)}return this.set("controlPoints",r),this},verb.geom.NurbsCurve.prototype.clone=function(){for(var e=this.get("controlPoints"),r=[],n=0;e.length>n;n++)r.push(e[n].slice(0));return new verb.geom.NurbsCurve(this.get("degree"),r,this.get("weights").slice(0),this.get("knots").slice)},verb.geom.NurbsCurve.prototype.homogenize=function(){return verb.eval.nurbs.homogenize_1d(this.get("controlPoints"),this.get("weights"))},verb.geom.NurbsCurve.prototype.update=function(){if(this.nurbsRep){var e=this.nurbsRep();this.setAll({controlPoints:e.control_points,weights:e.weights,knots:e.knots,degree:e.degree})}},verb.geom.NurbsSurface=function(e,r,n,t,i,s){verb.geom.NurbsGeometry.call(this),this.setAll({controlPoints:i,weights:s,knotsU:r?r.slice(0):[],knotsV:t?t.slice(0):[],degreeU:e,degreeV:n})}.inherits(verb.geom.NurbsGeometry),verb.geom.NurbsSurface.prototype.point=function(e,r,n){return this.nurbsEngine.eval("rational_surface_point",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),e,r],n)},verb.geom.NurbsSurface.prototype.derivatives=function(e,r,n,t){return this.nurbsEngine.eval("rational_surface_derivs",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),n||1,e,r],t)},verb.geom.NurbsSurface.prototype.tessellate=function(e,r){var n=20,t=20;return e&&(n=e.minDivsV||n,t=e.minDivsU||t),this.nurbsEngine.eval("tessellate_rational_surface_naive",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),t,n],r)},verb.geom.NurbsSurface.prototype.domain=function(){var e=this.get("knotsU"),r=this.get("knotsV");return[[e[0],e[e.length-1]],[r[0],r[r.length-1]]]},verb.geom.NurbsSurface.prototype.transform=function(e){for(var r=this.get("controlPoints"),n=0;r.length>n;n++)for(var t=0;r[n].length>t;t++){var i=r[1].push(1);r[n]=numeric.mul(e,i).slice(0,i.length-2)}return this.set("controlPoints",r),this},verb.geom.NurbsSurface.prototype.clone=function(){for(var e=this.get("controlPoints"),r=[],n=0;e.length>n;n++){r.push([]);for(var t=0;e[n].length>t;t++)r[n].push(e[n][t].slice(0))}for(var i=this.get("weights"),s=[],n=0;i.length>n;n++)s.push(i[n].slice(0));return new verb.geom.NurbsSurface(this.get("degreeU"),this.get("knotsU").slice(0),this.get("degreeV"),this.get("knotsV").slice(0),r,s)},verb.geom.NurbsSurface.prototype.homogenize=function(){return verb.eval.nurbs.homogenize_2d(this.get("controlPoints"),this.get("weights"))},verb.geom.NurbsSurface.prototype.update=function(){if(this.nurbsRep){var e=this.nurbsRep();this.setAll({controlPoints:e.control_points,weights:e.weights,knotsU:e.knots_u,knotsV:e.knots_v,degreeU:e.degree_u,degreeV:e.degree_v})}},verb.geom.Arc=function(e,r,n,t,i){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,radius:t,interval:i}),this.update(),this.watchAll(["center","xaxis","yaxis","radius","interval"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Arc.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("radius"),this.get("interval").get("min"),this.get("interval").get("max")])},verb.geom.BezierCurve=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({controlPoints:e?e.slice(0):[],weights:r?r.slice(0):void 0}),this.update()}.inherits(verb.geom.NurbsCurve),verb.geom.BezierCurve.prototype.nurbsRep=function(){for(var e=this.get("controlPoints"),r=this.get("weights"),n=e.length-1,t=[],i=0;n+1>i;i++)t.push(0);for(var i=0;n+1>i;i++)t.push(1);if(void 0===r){r=[];for(var i=0;e.length>i;i++)r.push(1)}return{degree:n,knots:t,control_points:e,weights:r}},verb.geom.BoundingBox=function(){this.initialized=!1,this.min=[0,0,0],this.max=[0,0,0];var e=Array.prototype.slice.call(arguments,0);1===e.length&&e[0]instanceof Array&&e[0][0]instanceof Array?this.add_elements_sync(e[0]):this.add_elements_sync(e)},verb.geom.BoundingBox.prototype.add_elements=function(e,r){var n=this;setTimeout(function(){e.forEach(function(e){n.add(e)}),r(n)},0)},verb.geom.BoundingBox.prototype.add_elements_sync=function(e){var r=this;return e.forEach(function(e){r.add(e)}),this},verb.geom.BoundingBox.prototype.add=function(e){return this.initialized?(e[0]>this.max[0]&&(this.max[0]=e[0]),e[1]>this.max[1]&&(this.max[1]=e[1]),e[2]>this.max[2]&&(this.max[2]=e[2]),e[0]=u&&a>=s||o>=u&&a>=o||u>=s&&o>=u||a>=s&&o>=a?!0:!1},verb.geom.BoundingBox.prototype.intersects=function(e,r){if(!this.initialized||!e.initialized)return!1;var n=this.min,t=this.max,i=e.min,s=e.max;return this.intervals_overlap(n[0],t[0],i[0],s[0],r)&&this.intervals_overlap(n[1],t[1],i[1],s[1],r)&&this.intervals_overlap(n[2],t[2],i[2],s[2],r)?!0:!1},verb.geom.BoundingBox.prototype.clear=function(){return this.initialized=!1,this},verb.geom.BoundingBox.prototype.get_longest_axis=function(){var e=[this.get_axis_length(0),this.get_axis_length(1),this.get_axis_length(2)];return e.indexOf(Math.max.apply(Math,e))},verb.geom.BoundingBox.prototype.get_axis_length=function(e){return 0>e||e>2?0:Math.abs(this.min[e]-this.max[e])},verb.geom.BoundingBox.prototype.intersect=function(e,r){if(!this.initialized)return null;var n=this.min,t=this.max,i=e.min,s=e.max;if(!this.intersects(e,r))return null;var o=Math.min(t[0],s[0]),u=Math.max(n[0],i[0]),a=Math.min(t[1],s[1]),v=Math.max(n[1],i[1]),l=Math.min(t[2],s[2]),c=Math.max(n[2],i[2]),h=[o,a,l],b=[u,v,c];return new verb.geom.BoundingBox(b,h)},verb.geom.Circle=function(e,r,n,t){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,radius:t}),this.update(),this.watchAll(["center","xaxis","yaxis","radius"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Circle.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("radius"),0,2*Math.PI])},verb.geom.Cone=function(e,r,n,t,i){verb.geom.NurbsSurface.call(this),this.setAll({axis:e,xaxis:r,base:n,height:t,radius:i});var s=this.nurbsRep();verb.geom.NurbsSurface.call(this,s.degree_u,s.knots_u,s.degree_v,s.knots_v,s.control_points,s.weights),this.watchAll(["axis","xaxis","base","height","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Cone.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_cone_surface",[this.get("axis"),this.get("xaxis"),this.get("base"),this.get("height"),this.get("radius")])},verb.geom.Cylinder=function(e,r,n,t,i){this.setAll({axis:e,xaxis:r,base:n,height:t,radius:i});var s=this.nurbsRep();verb.geom.NurbsSurface.call(this,s.degree_u,s.knots_u,s.degree_v,s.knots_v,s.control_points,s.weights),this.watchAll(["axis","xaxis","base","height","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Cylinder.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_cylinder_surface",[this.get("axis"),this.get("xaxis"),this.get("base"),this.get("height"),this.get("radius")])},verb.geom.Ellipse=function(e,r,n,t,i){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,xradius:t,yradius:i}),this.update(),this.watchAll(["center","xaxis","yaxis","xradius","yradius"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Ellipse.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_ellipse_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("xradius"),this.get("yradius"),0,2*Math.PI])},verb.geom.EllipseArc=function(e,r,n,t,i,s){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,xradius:t,yradius:i,interval:s}),this.update(),this.watchAll(["center","xaxis","yaxis","xradius","yradius","interval"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.EllipseArc.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_ellipse_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("xradius"),this.get("yradius"),this.get("interval").get("min"),this.get("interval").get("max")])},verb.geom.Extrusion=function(e,r,n){verb.geom.NurbsSurface.call(this),this.setAll({profile:e,axis:r,length:n}),this.update(),this.watchAll(["axis","length"],this.update),e.watchAll(["knots","degree","controlPoints","weights"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Extrusion.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_extruded_surface",[this.get("axis"),this.get("length"),this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights")])},verb.geom.FourPointSurface=function(e,r,n,t){verb.geom.NurbsSurface.call(this),this.setAll({p1:e,p2:r,p3:n,p4:t}),this.update(),this.watchAll(["p1","p2","p3","p4"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.FourPointSurface.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_4pt_surface",[this.get("p1"),this.get("p2"),this.get("p3"),this.get("p4")])},verb.geom.InterpCurve=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({pts:e?e.slice(0):[],degree:r?r:3}),this.update(),this.watchAll(["pts","degree"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.InterpCurve.prototype.nurbsRep=function(){return this.nurbsEngine.eval("rational_interp_curve",[this.get("pts"),this.get("degree")])},verb.geom.Interval=function(e,r){verb.core.WatchObject.call(this),this.setAll({min:e,max:r})}.inherits(verb.core.WatchObject),verb.geom.Interval2=function(e,r,n,t){verb.core.WatchObject.call(this),this.setAll({uinterval:new verb.geom.Interval(e,r),vinterval:new verb.geom.Interval(n,t)})}.inherits(verb.core.WatchObject),verb.geom.Line=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({start:e,end:r}),this.update(),this.watchAll(["start","end"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Line.prototype.nurbsRep=function(){return{knots:[0,0,1,1],control_points:[this.get("start"),this.get("end")],weights:[1,1],degree:1}},verb.geom.PlanarSurface=function(e,r,n,t,i){verb.geom.NurbsSurface.call(this),this.setAll({base:e,uaxis:r,vaxis:n,ulength:t,vlength:i}),this.update(),this.watchAll(["base","uaxis","vaxis","ulength","vlength"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.PlanarSurface.prototype.nurbsRep=function(){var e=this.get("base"),r=numeric.mul(this.get("uaxis"),this.get("ulength")),n=numeric.mul(this.get("vaxis"),this.get("vlength")),t=numeric.add(e,r),i=numeric.add(e,n,r),s=numeric.add(e,n);return this.nurbsEngine.eval("get_4pt_surface",[e,t,i,s])},verb.geom.PolyLine=function(e){verb.geom.NurbsCurve.call(this),this.setAll({control_points:e?e.slice(0):[]}),this.update()}.inherits(verb.geom.NurbsCurve),verb.geom.PolyLine.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_polyline_curve",[this.get("control_points")])},verb.geom.RevolvedSurface=function(e,r,n,t){verb.geom.NurbsSurface.call(this),this.setAll({center:e,axis:r,angle:n,profile:t}),this.update(),this.watchAll(["center","axis","angle","profile"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.RevolvedSurface.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_revolved_surface",[this.get("center"),this.get("axis"),this.get("angle"),this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights")])},verb.geom.Sphere=function(e,r){verb.geom.NurbsSurface.call(this),this.setAll({center:e,radius:r}),this.update(),this.watchAll(["center","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Sphere.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_sphere_surface",[this.get("center"),[0,0,1],[1,0,0],this.get("radius")])},verb.geom.SweepOneRail=function(e,r){verb.geom.NurbsSurface.call(this),this.setAll({rail:e,profile:r}),this.update(),this.watchAll(["rail","profile"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.SweepOneRail.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_sweep1_surface",[this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights"),this.get("rail").get("knots"),this.get("rail").get("degree"),this.get("rail").get("controlPoints"),this.get("rail").get("weights")])},verb.intersect.curveCurve=function(e,r,n){return verb.nurbsEngine.eval("intersect_rational_curves_by_aabb_refine",[e.get("degree"),e.get("knots"),e.homogenize(),r.get("degree"),r.get("knots"),r.homogenize(),verb.TOLERANCE,verb.TOLERANCE],n)},verb.intersect.curveSurface=function(e,r,n,t){return n=n||{tolerance:verb.TOLERANCE,sampleTolerance:verb.TOLERANCE,uDivs:20,vDivs:20},verb.nurbsEngine.eval("intersect_rational_curve_surface_by_aabb_refine",[r.get("degreeU"),r.get("knotsU"),r.get("degreeV"),r.get("knotsV"),r.homogenize(),e.get("degree"),e.get("knots"),e.homogenize(),n.sampleTolerance,n.tolerance,n.uDivs,n.vDivs],t)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb_refine=function(e,r,n,t,i,s,o,u,a,v,l,c){var h=verb.eval.nurbs.intersect_rational_curve_surface_by_aabb(e,r,n,t,i,s,o,u,a,v,l,c);return h.map(function(a){var v=[a.p,a.uv[0],a.uv[1]],l=verb.eval.nurbs.refine_rational_curve_surface_intersection(e,r,n,t,i,s,o,u,v);return a.p=l[0],a.uv[0]=l[1],a.uv[1]=l[2],a.distance=l[3],delete a.face,a})},verb.eval.nurbs.refine_rational_curve_surface_intersection=function(e,r,n,t,i,s,o,u,a){var v=function(a){var v=verb.eval.nurbs.rational_curve_point(s,o,u,a[0]),l=verb.eval.nurbs.rational_surface_point(e,r,n,t,i,a[1],a[2]),c=numeric.sub(v,l);return numeric.dot(c,c)},l=numeric.uncmin(v,a);return l.solution.concat(l.f)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb=function(e,r,n,t,i,s,o,u,a,v,l,c){var h=verb.eval.nurbs.rational_curve_adaptive_sample(s,o,u,a,!0),b=verb.eval.nurbs.tessellate_rational_surface_naive(e,r,n,t,i,l,c),m=h.map(function(e){return e[0]}),g=h.map(function(e){return e.slice(1)}),_=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb(g,m,b,verb.range(b.faces.length),v);return verb.unique(_,function(e,r){return v>numeric.norm2(numeric.sub(e.point,r.point))&&v>Math.abs(e.p-r.p)&&v>numeric.norm2(numeric.sub(e.uv,r.uv))})},verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),o=verb.eval.mesh.make_mesh_aabb(n.points,n.faces,t),u=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb;if(!s.intersects(o,i))return[];if(2!==e.length||1!==t.length){if(1===t.length){var a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return u(a,l,n,t,i).concat(u(v,c,n,t,i))}if(2===e.length){var h=verb.eval.mesh.sort_tris_on_longest_axis(o,n.points,n.faces,t),b=verb.left(h),m=verb.right(h);return u(e,r,n,b,i).concat(u(e,r,n,m,i))}var h=verb.eval.mesh.sort_tris_on_longest_axis(o,n.points,n.faces,t),b=verb.left(h),m=verb.right(h),a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return u(a,l,n,b,i).concat(u(a,l,n,m,i)).concat(u(v,c,n,b,i)).concat(u(v,c,n,m,i))}var g=verb.eval.geom.intersect_segment_with_tri(e[0],e[1],n.points,n.faces[t[0]]);if(null!=g){var _=g.p*(r[1]-r[0])+r[0],f=n.faces[t][0],d=n.faces[t][1],p=n.faces[t][2],y=n.uvs[f],x=n.uvs[d],k=n.uvs[p],N=numeric.sub(x,y),w=numeric.sub(k,y),E=numeric.add(y,numeric.mul(g.s,N),numeric.mul(g.t,w));return[{point:g.point,p:_,uv:E,face:t[0]}]}return[]},verb.eval.geom.intersect_segment_with_tri=function(e,r,n,t){var i=n[t[0]],s=n[t[1]],o=n[t[2]],u=numeric.sub(s,i),a=numeric.sub(o,i),v=numeric.cross(u,a),l=numeric.sub(r,e),c=numeric.sub(e,i),h=-numeric.dot(v,c),b=numeric.dot(v,l);if(Math.abs(b)m||m>1)return null;var g=numeric.add(e,numeric.mul(m,l)),_=numeric.dot(u,a),f=numeric.dot(u,u),d=numeric.dot(a,a),p=numeric.sub(g,i),y=numeric.dot(p,u),x=numeric.dot(p,a),k=_*_-f*d,N=(_*x-d*y)/k,w=(_*y-f*x)/k;return N>1+verb.EPSILON||w>1+verb.EPSILON||-verb.EPSILON>w||-verb.EPSILON>N||N+w>1+verb.EPSILON?null:{point:g,s:N,t:w,p:m}},verb.eval.geom.intersect_segment_with_plane=function(e,r,n,t){var i=numeric.dot(t,numeric.sub(e,r));if(EPSILON>abs(i))return null;var s=numeric.dot(t,numeric.sub(n,e));return{p:s/i}},verb.eval.geom.intersect_aabb_trees=function(e,r,n,t,i,s){var o=i.bounding_box.intersects(s.bounding_box),u=verb.eval.geom.intersect_aabb_trees;return o?0===i.children.length&&0===s.children.length?[[i.triangle,s.triangle]]:0===i.children.length&&0!=s.children.length?u(e,r,n,t,i,s.children[0]).concat(u(e,r,n,t,i,s.children[1])):0!=i.children.length&&0===s.children.length?u(e,r,n,t,i.children[0],s).concat(u(e,r,n,t,i.children[1],s)):0!=i.children.length&&0!=s.children.length?u(e,r,n,t,i.children[0],s.children[0]).concat(u(e,r,n,t,i.children[0],s.children[1])).concat(u(e,r,n,t,i.children[1],s.children[0])).concat(u(e,r,n,t,i.children[1],s.children[1])):void 0:[]},verb.eval.mesh.make_mesh_aabb_tree=function(e,r,n){var t={bounding_box:verb.eval.mesh.make_mesh_aabb(e,r,n),children:[]};if(1===n.length)return t.triangle=n[0],t;var i=verb.eval.mesh.sort_tris_on_longest_axis(t.bounding_box,e,r,n),s=i.slice(0,Math.floor(i.length/2)),o=i.slice(Math.floor(i.length/2),i.length);return t.children=[verb.eval.mesh.make_mesh_aabb_tree(e,r,s),verb.eval.mesh.make_mesh_aabb_tree(e,r,o)],t},verb.eval.mesh.make_mesh_aabb=function(e,r,n){var t=new verb.geom.BoundingBox;return n.forEach(function(n){t.add(e[r[n][0]]),t.add(e[r[n][1]]),t.add(e[r[n][2]])}),t},verb.eval.mesh.sort_tris_on_longest_axis=function(e,r,n,t){for(var i=e.get_longest_axis(),s=[],o=t.length-1;o>=0;o--){var u=t[o],a=verb.eval.mesh.get_min_coordinate_on_axis(r,n[u],i);s.push([a,u])}s.sort(function(e,r){return e[0]>r[0]});for(var v=[],o=0,l=s.length;l>o;o++)v.push(s[o][1]);return v},verb.eval.mesh.get_min_coordinate_on_axis=function(e,r,n){for(var t=[],i=0;3>i;i++)t.push(e[r[i]][n]);return Math.min.apply(Math,t)},verb.eval.geom.get_tri_centroid=function(e,r){for(var n=[0,0,0],t=0;3>t;t++)for(var i=0;3>i;i++)n[i]+=e[r[t]][i];for(var t=0;3>t;t++)n[t]/=3;return n},verb.eval.geom.get_tri_norm=function(e,r){var n=e[r[0]],t=e[r[1]],i=e[r[2]],s=numeric.sub(t,n),o=numeric.sub(i,n),u=numeric.cross(s,o);return numeric.mul(1/numeric.norm2(u),u)},verb.eval.nurbs.intersect_rational_curves_by_aabb_refine=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.intersect_rational_curves_by_aabb(e,r,n,t,i,s,o,u);return a.map(function(o){return verb.eval.nurbs.refine_rational_curve_intersection(e,r,n,t,i,s,o)})},verb.eval.nurbs.refine_rational_curve_intersection=function(e,r,n,t,i,s,o){var u=function(o){var u=verb.eval.nurbs.rational_curve_point(e,r,n,o[0]),a=verb.eval.nurbs.rational_curve_point(t,i,s,o[1]),v=numeric.sub(u,a);return numeric.dot(v,v)},a=numeric.uncmin(u,o);return a.solution.concat(a.f)},verb.eval.nurbs.intersect_rational_curves_by_aabb=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.rational_curve_adaptive_sample(e,r,n,o,!0),v=verb.eval.nurbs.rational_curve_adaptive_sample(t,i,s,o,!0),l=a.map(function(e){return e[0]}),c=v.map(function(e){return e[0]}),h=a.map(function(e){return e.slice(1)}),b=v.map(function(e){return e.slice(1)});return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,b,l,c,u)},verb.eval.nurbs.intersect_parametric_polylines_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),o=new verb.geom.BoundingBox(r);if(!s.intersects(o,i))return[];if(2!==e.length||2!==r.length){if(2===e.length){var u=Math.ceil(r.length/2),a=r.slice(0,u),v=r.slice(u-1),l=t.slice(0,u),c=t.slice(u-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,a,n,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,v,n,c,i))}if(2===r.length){var h=Math.ceil(e.length/2),b=e.slice(0,h),m=e.slice(h-1),g=n.slice(0,h),_=n.slice(h-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,r,g,t,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,r,_,t,i))}var h=Math.ceil(e.length/2),b=e.slice(0,h),m=e.slice(h-1),g=n.slice(0,h),_=n.slice(h-1),u=Math.ceil(r.length/2),a=r.slice(0,u),v=r.slice(u-1),l=t.slice(0,u),c=t.slice(u-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,a,g,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,v,g,c,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,a,_,l,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,v,_,c,i))}var f=verb.eval.geom.intersect_segments(e[0],e[1],r[0],r[1],i);return null!=f?(f[0][0]=f[0][0]*(n[1]-n[0])+n[0],f[1][0]=f[1][0]*(t[1]-t[0])+t[0],[[f[0][0],f[1][0]]]):[]},verb.eval.geom.intersect_segments=function(e,r,n,t,i){var s=numeric.sub(r,e),o=Math.sqrt(numeric.dot(s,s)),u=numeric.mul(1/o,s),a=numeric.sub(t,n),v=Math.sqrt(numeric.dot(a,a)),l=numeric.mul(1/v,a),c=verb.eval.geom.intersect_rays(e,u,n,l);if(null!=c){var h=Math.min(Math.max(0,c[0]/o),1),b=Math.min(Math.max(0,c[1]/v),1),m=numeric.add(numeric.mul(h,s),e),g=numeric.add(numeric.mul(b,a),n),_=numeric.norm2Squared(numeric.sub(m,g));if(i*i>_)return[[h].concat(m),[b].concat(g)]}return null},verb.eval.geom.closest_point_on_ray=function(e,r,n){var t=numeric.sub(e,r),i=numeric.dot(t,n),s=numeric.add(r,numeric.mul(i,n));return s},verb.eval.geom.dist_to_ray=function(e,r,n){var t=verb.eval.geom.closest_point_on_ray(e,r,n),i=numeric.sub(t,e);return numeric.norm2(i)},verb.eval.geom.intersect_rays=function(e,r,n,t){var i=numeric.dot(r,t),s=numeric.dot(r,n),o=numeric.dot(r,e),u=numeric.dot(t,n),a=numeric.dot(t,e),v=numeric.dot(r,r),l=numeric.dot(t,t),c=v*l-i*i;if(Math.abs(c)E)break; -var P=numeric.normalized(numeric.cross(g,x)),C=numeric.dot(P,m),R=verb.eval.geom.intersect_3_planes(g,d,x,w,P,C);if(null===R)throw Error("panic!");var I=numeric.sub(R,m),O=numeric.sub(R,y),B=numeric.cross(_,g),L=numeric.cross(f,g),j=numeric.cross(k,x),T=numeric.cross(N,x),U=numeric.dot(L,I)/numeric.dot(L,_),D=numeric.dot(B,I)/numeric.dot(B,f),V=numeric.dot(T,O)/numeric.dot(T,k),q=numeric.dot(j,O)/numeric.dot(j,N);e=numeric.add([U,D],e),r=numeric.add([V,q],r),A++}while(z>A);return{uv1:e,uv2:r,pt:m,d:E}},verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine=function(e,r,n,t,i,s,o,u,a,v,l){var c={degree_u:e,degree_v:n,knots_u:r,knots_v:t,homo_control_points:i},h={minDivsU:20,minDivsV:20,tol:.05},b=verb.eval.nurbs.tessellate_rational_surface_adaptive(c.degree_u,c.knots_u,c.degree_v,c.knots_v,c.homo_control_points,h),m={degree_u:s,degree_v:u,knots_u:o,knots_v:a,homo_control_points:v},g=verb.eval.nurbs.tessellate_rational_surface_adaptive(m.degree_u,m.knots_u,m.degree_v,m.knots_v,m.homo_control_points,h),_=verb.eval.mesh.intersect_meshes_by_aabb(b.points,b.faces,b.uvs,g.points,g.faces,g.uvs),f=_.map(function(c){return c.map(function(c){return verb.eval.nurbs.refine_rational_surface_intersect_point(c.uvtri1,c.uvtri2,e,r,n,t,i,s,o,u,a,v,l)})});return f.map(function(e){return verb.eval.nurbs.rational_interp_curve(e.map(function(e){return e.pt}),2)})},verb.eval.mesh.intersect_meshes_by_aabb=function(e,r,n,t,i,s){var o=verb.range(r.length),u=verb.range(i.length),a=verb.eval.mesh.make_mesh_aabb_tree(e,r,o),v=verb.eval.mesh.make_mesh_aabb_tree(t,i,u),l=verb.eval.geom.intersect_aabb_trees(e,r,t,i,a,v),c=l.map(function(o){var u=verb.eval.geom.intersect_tris(e,r[o[0]],n,t,i[o[1]],s);return u?(u[0].tri1id=o[0],u[1].tri1id=o[0],u[0].tri2id=o[1],u[1].tri2id=o[1],u):u}).filter(function(e){return e}).filter(function(e){var r=numeric.sub(e[0].pt,e[1].pt);return numeric.dot(r,r)>verb.TOLERANCE});return c=verb.unique(c,function(e,r){var n=numeric.sub(e[0].uvtri1,r[0].uvtri1),t=numeric.dot(n,n),i=numeric.sub(e[1].uvtri1,r[1].uvtri1),s=numeric.dot(i,i),o=numeric.sub(e[0].uvtri1,r[1].uvtri1),u=numeric.dot(o,o),a=numeric.sub(e[1].uvtri1,r[0].uvtri1),v=numeric.dot(a,a);return verb.TOLERANCE>t&&verb.TOLERANCE>s||verb.TOLERANCE>u&&verb.TOLERANCE>v}),0===c.length?[]:verb.eval.mesh.make_intersect_polylines(c)},verb.eval.mesh.make_intersect_polylines=function(e){e.forEach(function(e){e[1].opp=e[0],e[0].opp=e[1]});var r=verb.eval.mesh.kdtree_from_segs(e),n=e.flatten();n.forEach(function(n){if(!n.adj){var t=verb.eval.mesh.lookup_adj_segment(n,r,e.length);t&&!t.adj&&(n.adj=t,t.adj=n)}});var t=n.filter(function(e){return!e.adj});0===t.length&&(t=n);var i=[];return t.forEach(function(e){if(!e.v){for(var r=[],n=e;n;){if(n.v)throw Error("Segment end encountered twice!");if(n.v=!0,n.opp.v=!0,r.push(n),n=n.opp.adj,n===e)break}r.length>0&&(r.push(r[r.length-1].opp),i.push(r))}}),i},verb.eval.mesh.pt_dist=function(e,r){return Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2)+Math.pow(e.z-r.z,2)},verb.eval.mesh.kdtree_from_segs=function(e){var r=[];return e.forEach(function(e){r.push({x:e[0].pt[0],y:e[0].pt[1],z:e[0].pt[2],ele:e[0]}),r.push({x:e[1].pt[0],y:e[1].pt[1],z:e[1].pt[2],ele:e[1]})}),new KdTree(r,verb.eval.mesh.pt_dist,["x","y","z"])},verb.eval.mesh.lookup_adj_segment=function(e,r,n){var t=n?Math.min(n,3):3,i=r.nearest({x:e.pt[0],y:e.pt[1],z:e.pt[2]},t).filter(function(r){return e!=r[0].ele&&r[1]h;h++){var b=s[h],m=a[h],g=verb.eval.geom.intersect_rays(b,m,e,r);if(null!==g){var _=g[0],f=g[1];-verb.EPSILON>_||_>v[h]+verb.EPSILON||((null===l||l.u>f)&&(l={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[h],numeric.mul(_/v[h],o[h]))}),(null===c||f>c.u)&&(c={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[h],numeric.mul(_/v[h],o[h]))}))}}return null===c||null===l?null:{min:l,max:c}},verb.eval.geom.point_on_ray=function(e,r,n){return numeric.add(e,numeric.mul(n,r))},verb.eval.geom.merge_tri_clip_intervals=function(e,r,n,t,i,s,o,u){if(r.min.u>e.max.u+verb.EPSILON||e.min.u>r.max.u+verb.EPSILON)return null;e.min.tri=0,e.max.tri=0,r.min.tri=1,r.max.tri=1;var a=e.min.u>r.min.u?e.min:r.min,v=e.max.uo&&(s=1,o=u),a>o&&(s=2,o=a);var v,l,c,h;0===s?(v=r[1],l=r[2],c=t[1],h=t[2]):1===s?(v=r[0],l=r[2],c=t[0],h=t[2]):(v=r[0],l=r[1],c=t[0],h=t[1]);var b,m=-numeric.dot(e,r),g=-numeric.dot(n,t),_=v*h-l*c,f=(l*g-m*h)/_,d=(m*c-v*g)/_;return b=0===s?[0,f,d]:1===s?[f,0,d]:[f,d,0],{intersects:!0,origin:b,dir:numeric.normalized(i)}},verb.eval.geom.tri_uv_from_point=function(e,r,n,t){var i=e[r[0]],s=e[r[1]],o=e[r[2]],u=n[r[0]],a=n[r[1]],v=n[r[2]],l=numeric.sub(i,t),c=numeric.sub(s,t),h=numeric.sub(o,t),b=numeric.norm2(numeric.cross(numeric.sub(i,s),numeric.sub(i,o))),m=numeric.norm2(numeric.cross(c,h))/b,g=numeric.norm2(numeric.cross(h,l))/b,_=numeric.norm2(numeric.cross(l,c))/b;return numeric.add(numeric.mul(m,u),numeric.mul(g,a),numeric.mul(_,v))},verb.eval.nurbs.tessellate_rational_surface_naive=function(e,r,n,t,i,s,o){1>s&&(s=1),1>o&&(o=1);for(var u=r[r.length-1]-r[0],a=t[t.length-1]-t[0],v=u/s,l=a/o,c=[],h=[],b=[],m=0;s+1>m;m++)for(var g=0;o+1>g;g++){var _=m*v,f=g*l;h.push([_,f]);var d=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,_,f),p=d[0][0];c.push(p);var y=numeric.normalized(numeric.cross(d[0][1],d[1][0]));b.push(y)}for(var x=[],m=0;s>m;m++)for(var g=0;o>g;g++){var k=m*(o+1)+g,N=(m+1)*(o+1)+g,w=N+1,E=k+1,z=[k,N,w],A=[k,w,E];x.push(z),x.push(A)}return{points:c,faces:x,uvs:h,normals:b}},verb.eval.nurbs.rational_curve_regular_sample=function(e,r,n,t,i){return verb.eval.nurbs.rational_curve_regular_sample_range(e,r,n,0,1,t,i)},verb.eval.nurbs.rational_curve_regular_sample_range=function(e,r,n,t,i,s,o){1>s&&(s=2);for(var u=[],a=(i-t)/(s-1),v=0,l=0;s>l;l++)v=t+a*l,o?u.push([v].concat(verb.eval.nurbs.rational_curve_point(e,r,n,v))):u.push(verb.eval.nurbs.rational_curve_point(e,r,n,v));return u},verb.eval.nurbs.rational_curve_adaptive_sample=function(e,r,n,t,i){return 1===e?i?n.map(function(e,n){return[r[n+1]].concat(verb.eval.nurbs.dehomogenize(e))}):n.map(verb.eval.nurbs.dehomogenize):verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,r[0],r[r.length-1],t,i)},verb.eval.nurbs.rational_curve_adaptive_sample_range=function(e,r,n,t,i,s,o){var u=verb.eval.nurbs.rational_curve_point(e,r,n,t),a=verb.eval.nurbs.rational_curve_point(e,r,n,i),v=.5+.2*Math.random(),l=t+(i-t)*v,c=verb.eval.nurbs.rational_curve_point(e,r,n,l),h=numeric.sub(u,a),b=numeric.sub(u,c);if(s>numeric.dot(h,h)&&numeric.dot(b,b)>s||!verb.eval.nurbs.three_points_are_flat(u,c,a,s)){var m=t+.5*(i-t),g=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,t,m,s,o),_=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,m,i,s,o);return g.slice(0,-1).concat(_)}return o?[[t].concat(u),[i].concat(a)]:[u,a]},verb.eval.nurbs.three_points_are_flat=function(e,r,n,t){var i=numeric.sub(r,e),s=numeric.sub(n,e),o=crossprod(i,s),u=numeric.dot(o,o);return t>u},verb.eval.nurbs.divide_rational_surface_adaptive=function(e,r,n,t,i,s){var o,u,a,v,l={degree_u:e,knots_u:r,degree_v:n,knots_v:t,homo_control_points:i};s=s||{},s.minDivsU=s.minDivsU||1,s.minDivsV=s.minDivsV||1,s.refine=void 0!=s.refine?s.refine:!0;var c=s.minDivsU=Math.max(s.minDivsU,3*(i.length-1)),h=s.minDivsV=Math.max(s.minDivsV,3*(i.length-1)),b=verb.last(r),m=r[0],g=verb.last(t),_=t[0],f=(b-m)/c,d=(g-_)/h,p=[],y=[];for(o=0,a=h+1;a>o;o++){var x=[];for(u=0,v=c+1;v>u;u++){var k=m+f*u,N=_+d*o,w=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,k,N),E=numeric.normalized(numeric.cross(w[0][1],w[1][0]));x.push(new verb.geom.SurfacePoint(w[0][0],E,[k,N],null,verb.isZero(E)))}y.push(x)}for(o=0;h>o;o++)for(u=0;c>u;u++){var z=[y[h-o-1][u],y[h-o-1][u+1],y[h-o][u+1],y[h-o][u]];p.push(new verb.eval.nurbs.AdaptiveRefinementNode(l,z))}if(!s.refine)return p;for(o=0;h>o;o++)for(u=0;c>u;u++){var A=o*c+u,M=verb.north(A,o,u,c,h,p),S=verb.east(A,o,u,c,h,p),P=verb.south(A,o,u,c,h,p),C=verb.west(A,o,u,c,h,p);p[A].neighbors=[P,S,M,C],p[A].divide(s)}return p},verb.north=function(e,r,n,t,i,s){return 0===r?null:s[e-t]},verb.south=function(e,r,n,t,i,s){return r===i-1?null:s[e+t]},verb.east=function(e,r,n,t,i,s){return n===t-1?null:s[e+1]},verb.west=function(e,r,n,t,i,s){return 0===n?null:s[e-1]},verb.eval.nurbs.triangulate_adaptive_refinement_node_tree=function(e){var r=verb.geom.TriMesh.empty();return e.forEach(function(e){e.triangulate(r)}),r},verb.eval.nurbs.tessellate_rational_surface_adaptive=function(e,r,n,t,i,s){var o=verb.eval.nurbs.divide_rational_surface_adaptive(e,r,n,t,i,s);return verb.eval.nurbs.triangulate_adaptive_refinement_node_tree(o)},verb.eval.nurbs.dist_to_seg=function(e,r,n){var t=numeric.sub(n,e),i=numeric.norm2(t),s=numeric.sub(r,e);if(verb.TOLERANCE>i)return numeric.norm2(s);var o=numeric.mul(1/i,t),u=numeric.dot(s,o),a=numeric.add(e,numeric.mul(u,o));return numeric.norm2(numeric.sub(a,r))},verb.geom.SurfacePoint=function(e,r,n,t,i){this.uv=n,this.point=e,this.normal=r,this.id=t,this.degen=i},verb.geom.SurfacePoint.fromUv=function(e,r){return new verb.geom.SurfacePoint(null,null,[e,r],null,null)},verb.geom.TriMesh=function(e,r,n,t){this.faces=e,this.points=r,this.uvs=n,this.normals=t},verb.geom.TriMesh.empty=function(){return new verb.geom.TriMesh([],[],[],[])},verb.eval.nurbs.AdaptiveRefinementNode=function(e,r,n,t){if(this.srf=e,this.parentNode=n,this.neighbors=t||[null,null,null,null],!r){var i=e?e.knots_u[0]:null,s=e?verb.last(e.knots_u):null,o=e?e.knots_v[0]:null,u=e?verb.last(e.knots_v):null;r=[verb.geom.SurfacePoint.fromUv(i,o),verb.geom.SurfacePoint.fromUv(s,o),verb.geom.SurfacePoint.fromUv(s,u),verb.geom.SurfacePoint.fromUv(i,u)]}this.corners=r},verb.eval.nurbs.AdaptiveRefinementNode.prototype.isLeaf=function(){return void 0===this.children},verb.eval.nurbs.AdaptiveRefinementNode.prototype.center=function(){return this.centerPoint||this.evalSrf(this.u05,this.v05)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalCorners=function(){this.u05=this.u05||(this.corners[0].uv[0]+this.corners[2].uv[0])/2,this.v05=this.v05||(this.corners[0].uv[1]+this.corners[2].uv[1])/2;for(var e=0;4>e;e++)if(!this.corners[e].point){var r=this.corners[e];this.evalSrf(r.uv[0],r.uv[1],r)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalSrf=function(e,r,n){var t=verb.eval.nurbs.rational_surface_derivs(this.srf.degree_u,this.srf.knots_u,this.srf.degree_v,this.srf.knots_v,this.srf.homo_control_points,1,e,r),i=t[0][0],s=numeric.cross(t[0][1],t[1][0]),o=verb.isZero(s);return o||(s=numeric.normalized(s)),n?(n.degen=o,n.point=i,n.normal=s,n):new verb.geom.SurfacePoint(i,s,[e,r],null,o)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getEdgeCorners=function(e){if(this.isLeaf())return[this.corners[e]];if(this.horizontal)switch(e){case 0:return this.children[0].getEdgeCorners(0);case 1:return this.children[0].getEdgeCorners(1).concat(this.children[1].getEdgeCorners(1));case 2:return this.children[1].getEdgeCorners(2);case 3:return this.children[1].getEdgeCorners(3).concat(this.children[0].getEdgeCorners(3))}switch(e){case 0:return this.children[0].getEdgeCorners(0).concat(this.children[1].getEdgeCorners(0));case 1:return this.children[1].getEdgeCorners(1);case 2:return this.children[1].getEdgeCorners(2).concat(this.children[0].getEdgeCorners(2));case 3:return this.children[0].getEdgeCorners(3)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getAllCorners=function(e){var r=[this.corners[e]];if(!this.neighbors[e])return r;var n=this.neighbors[e].getEdgeCorners((e+2)%4),t=e%2,i=verb.EPSILON,s=this,o=[function(e){return e.uv[0]>s.corners[0].uv[0]+i&&e.uv[0]s.corners[0].uv[1]+i&&e.uv[1]r;r++)if(Math.abs(e[r])>verb.TOLERANCE)return!1;return!0},verb.eval.nurbs.AdaptiveRefinementNode.prototype.hasBadNormals=function(){return this.corners[0].degen||this.corners[1].degen||this.corners[2].degen||this.corners[3].degen},verb.eval.nurbs.AdaptiveRefinementNode.prototype.fixNormals=function(){for(var e=0,r=this.corners.length;r>e;e++)if(this.corners[e],this.corners[e].degen){var n=this.corners[(e+1)%r],t=this.corners[(e+3)%r];this.corners[e].normal=n.degen?t.normal:n.normal}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide=function(e,r){if(e.minDepth>r)return!0;if(r>=e.maxDepth)return!1;if(this.hasBadNormals())return this.fixNormals(),!1;if(this.splitVert=numeric.norm2Squared(numeric.sub(this.corners[0].normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[2].normal,this.corners[3].normal))>e.normTol,this.splitHoriz=numeric.norm2Squared(numeric.sub(this.corners[1].normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[3].normal,this.corners[0].normal))>e.normTol,this.splitVert||this.splitHoriz)return!0;var n=this.center();return numeric.norm2Squared(numeric.sub(n.normal,this.corners[0].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[3].normal))>e.normTol},verb.eval.nurbs.AdaptiveRefinementNode.prototype.divide=function(e){e=e||{},e.edgeTol=e.edgeTol||.1,e.normTol=e.normTol||.05,e.minDepth=void 0!=e.minDepth?e.minDepth:0,e.maxDepth=void 0!=e.maxDepth?e.maxDepth:10,this._divide(e,0,!0)},verb.eval.nurbs.AdaptiveRefinementNode.prototype._divide=function(e,r,n){if(this.evalCorners(),this.shouldDivide(e,r)){if(r++,this.splitVert&&!this.splitHoriz?n=!1:!this.splitVert&&this.splitHoriz&&(n=!0),this.horizontal=n,this.horizontal){var t=[this.corners[0],this.corners[1],this.midpoint(1),this.midpoint(3)],i=[this.midpoint(3),this.midpoint(1),this.corners[2],this.corners[3]];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,t,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,i,this)],this.children[0].neighbors=[this.neighbors[0],this.neighbors[1],this.children[1],this.neighbors[3]],this.children[1].neighbors=[this.children[0],this.neighbors[1],this.neighbors[2],this.neighbors[3]]}else{var s=[this.corners[0],this.midpoint(0),this.midpoint(2),this.corners[3]],o=[this.midpoint(0),this.corners[1],this.corners[2],this.midpoint(2)];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,s,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,o,this)],this.children[0].neighbors=[this.neighbors[0],this.children[1],this.neighbors[2],this.neighbors[3]],this.children[1].neighbors=[this.neighbors[0],this.neighbors[1],this.neighbors[2],this.children[0]]}this.children.forEach(function(t){t._divide(e,r,!n)})}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulate=function(e){return e=e||verb.geom.TriMesh.empty(),this.isLeaf()?this.triangulateLeaf(e):(this.children.forEach(function(r){r&&r.triangulate(e)}),e)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulateLeaf=function(e){var r,n,t,i,s=e.points.length,o=[],u=[],a=0;for(a=0;4>a;a++){var v=this.getAllCorners(a);for(2===v.length&&(i=a+1),t=0;v.length>t;t++)o.push(v[t])}for(a=0,n=o.length;n>a;a++)r=o[a],void 0==r.id?(e.uvs.push(r.uv),e.points.push(r.point),e.normals.push(r.normal),r.id=s,u.push(s),s++):u.push(r.id);if(4===o.length)return e.faces.push([u[0],u[3],u[1]]),e.faces.push([u[3],u[2],u[1]]),e;if(5===o.length){var l=u.length;return e.faces.push([u[i],u[(i+1)%l],u[(i+2)%l]]),e.faces.push([u[(i+4)%l],u[(i+3)%l],u[i]]),e.faces.push([u[i],u[(i+2)%l],u[(i+3)%l]]),e}var c=this.center();e.uvs.push(c.uv),e.points.push(c.point),e.normals.push(c.normal);var h=e.points.length-1;for(a=0,t=o.length-1;o.length>a;t=a++)e.faces.push([h,u[t],u[a]]);return e},verb.eval.nurbs.rational_interp_curve=function(e,r){if(r=r||3,r+1>e.length)throw Error("You need to supply at least degree + 1 points!");for(var n=[0],t=1;e.length>t;t++){var i=numeric.norm2(numeric.sub(e[t],e[t-1])),s=n[n.length-1];n.push(s+i)}for(var o=n[n.length-1],t=0;n.length>t;t++)n[t]=n[t]/o;for(var u=numeric.rep([r+1],0),a=e.length-1,t=1,v=n.length-r;v>t;t++){for(var l=0,c=0;r>c;c++)l+=n[t+c];u.push(1/r*l)}for(var h=u.concat(numeric.rep([r+1],1)),b=[],t=0;n.length>t;t++){var m=n[t],g=verb.eval.nurbs.knot_span_given_n(a,r,m,h),_=verb.eval.nurbs.basis_functions_given_knot_span_index(g,m,r,h),f=g-r,d=verb.eval.nurbs.zeros_1d(f),p=verb.eval.nurbs.zeros_1d(e.length-(r+1)-f);b.push(d.concat(_).concat(p))}for(var y=e[0].length,x=[],t=0;y>t;t++){var k=e.map(function(e){return e[t]}),N=numeric.solve(b,k);x.push(N)}var w=numeric.transpose(x),E=numeric.rep([w.length],1);return{control_points:w,knots:h,degree:r,weights:E}},verb.eval.nurbs.get_sweep1_surface=function(e,r,n,t,i,s,o,u){for(var a=verb.eval.nurbs.homogenize_1d(o,u),v=verb.eval.nurbs.rational_curve_point(s,i,a,0),l=1/o.length,c=[],h=[],b=0;o.length>b;b++){for(var m=verb.eval.nurbs.rational_curve_point(s,i,a,b*l),g=numeric.sub(m,v),_=[],f=[],d=0;n.length>d;d++)_.push(numeric.add(g,n[d])),f.push(t[d]*u[b]);c.push(_),h.push(f)}return{knots_u:i,knots_v:e,control_points:c,degree_u:s,degree_v:r,weights:h}},verb.eval.nurbs.get_ellipse_arc=function(e,r,n,t,i,s,o){s>o&&(o=2*Math.PI+s);var u=o-s,a=0;a=Math.PI/2>=u?1:Math.PI>=u?2:3*Math.PI/2>=u?3:4;var v=u/a,l=Math.cos(v/2),c=numeric.add(e,numeric.mul(t,Math.cos(s),r),numeric.mul(i,Math.sin(s),n)),h=numeric.sub(numeric.mul(Math.cos(s),n),numeric.mul(Math.sin(s),r)),b=verb.eval.nurbs.zeros_1d(2*a),m=verb.eval.nurbs.zeros_1d(2*a+3),g=0,_=s,f=verb.eval.nurbs.zeros_1d(2*a);b[0]=c,f[0]=1;for(var d=1;a>=d;d++){_+=v;var p=numeric.add(e,numeric.mul(t,Math.cos(_),r),numeric.mul(i,Math.sin(_),n));f[g+2]=1,b[g+2]=p;var y=numeric.sub(numeric.mul(Math.cos(_),n),numeric.mul(Math.sin(_),r)),x=verb.eval.geom.intersect_rays(c,numeric.mul(1/numeric.norm2(h),h),p,numeric.mul(1/numeric.norm2(y),y)),k=numeric.add(c,numeric.mul(h,x[0]));f[g+1]=l,b[g+1]=k,g+=2,a>d&&(c=p,h=y)}for(var N=2*a+1,d=0;3>d;d++)m[d]=0,m[d+N]=1;switch(a){case 1:break;case 2:m[3]=m[4]=.5;break;case 3:m[3]=m[4]=1/3,m[5]=m[6]=2/3;break;case 4:m[3]=m[4]=.25,m[5]=m[6]=.5,m[7]=m[8]=.75}return{knots:m,control_points:b,degree:2,weights:f}},verb.eval.nurbs.get_sphere_surface=function(e,r,n,t){var i=verb.eval.nurbs.get_arc(e,numeric.mul(r,-1),n,t,0,Math.PI);return verb.eval.nurbs.get_revolved_surface(e,r,2*Math.PI,i.knots,i.degree,i.control_points,i.weights)},verb.eval.nurbs.get_polyline_curve=function(e){for(var r=e.length-1,n=1/r,t=[0,0],i=1;r>i;i++)t.push(i*n);t.push(1),t.push(1);for(var s=[],i=0;e.length>i;i++)s.push(1);return{knots:t,control_points:e.slice(0),degree:1,weights:s}},verb.eval.nurbs.get_4pt_surface=function(e,r,n,t){var i=numeric.mul(.5,numeric.add(e,t)),s=numeric.mul(.5,numeric.add(r,n)),o=numeric.mul(.5,numeric.add(n,t)),u=numeric.mul(.5,numeric.add(e,r)),a=numeric.mul(.5,numeric.add(i,s));return{knots_u:[0,0,0,1,1,1],knots_v:[0,0,0,1,1,1],control_points:[[e,i,t],[u,a,o],[r,s,n]],degree_u:2,degree_v:2,weights:[[1,1,1],[1,1,1],[1,1,1]]}},verb.eval.nurbs.get_cylinder_surface=function(e,r,n,t,i){var s=crossprod(e,r),o=(2*Math.PI,verb.eval.nurbs.get_arc(n,r,s,i,0,2*Math.PI));return verb.eval.nurbs.get_extruded_surface(e,t,o.knots,o.degree,o.control_points,o.weights)},verb.eval.nurbs.get_cone_surface=function(e,r,n,t,i){var s=2*Math.PI,o=1,u=[numeric.add(n,numeric.mul(t,e)),numeric.add(n,numeric.mul(i,r))],a=[0,0,1,1],v=[1,1];return verb.eval.nurbs.get_revolved_surface(n,e,s,a,o,u,v)},verb.eval.nurbs.get_extruded_surface=function(e,r,n,t,i,s){for(var o=verb.eval.nurbs.zeros_2d(3,i.length),u=verb.eval.nurbs.zeros_2d(3,i.length),a=numeric.mul(e,r),v=numeric.mul(e,.5*r),l=0;i.length>l;l++)o[2][l]=i[l],o[1][l]=numeric.add(v,i[l]),o[0][l]=numeric.add(a,i[l]),u[0][l]=s[l],u[1][l]=s[l],u[2][l]=s[l];return{knots_u:[0,0,0,1,1,1],knots_v:n,control_points:o,degree_u:2,degree_v:t,weights:u}},verb.eval.nurbs.get_revolved_surface=function(e,r,n,t,i,s,o){var u,a,v,l;Math.PI/2>=n?(u=1,a=verb.eval.nurbs.zeros_1d(6+2*(u-1))):Math.PI>=n?(u=2,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=.5):3*Math.PI/2>=n?(u=3,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=1/3,a[5]=a[6]=2/3):(u=4,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=.25,a[5]=a[6]=.5,a[7]=a[8]=.75);for(var c=n/u,h=3+2*(u-1),b=0;3>b;h++,b++)a[b]=0,a[h]=1;for(var m=Math.cos(c/2),g=0,_=verb.eval.nurbs.zeros_1d(u+1),f=verb.eval.nurbs.zeros_1d(u+1),v=verb.eval.nurbs.zeros_2d(2*u+1,s.length),l=verb.eval.nurbs.zeros_2d(2*u+1,s.length),b=1;u>=b;b++)g+=c,f[b]=Math.cos(g),_[b]=Math.sin(g);for(h=0;s.length>h;h++){var d=verb.eval.geom.closest_point_on_ray(s[h],e,r),p=numeric.sub(s[h],d),y=numeric.norm2(p),x=crossprod(r,p);y>verb.EPSILON&&(p=numeric.mul(1/y,p),x=numeric.mul(1/y,x)),v[0][h]=s[h];var k=s[h];l[0][h]=o[h];for(var N=x,w=0,g=0,b=1;u>=b;b++){var E=0==y?d:numeric.add(d,numeric.mul(y,f[b],p),numeric.mul(y,_[b],x));v[w+2][h]=E,l[w+2][h]=o[h];var z=numeric.sub(numeric.mul(f[b],x),numeric.mul(_[b],p));if(0==y)v[w+1][h]=d;else{var A=verb.eval.geom.intersect_rays(k,numeric.mul(1/numeric.norm2(N),N),E,numeric.mul(1/numeric.norm2(z),z)),M=numeric.add(k,numeric.mul(N,A[0]));v[w+1][h]=M}l[w+1][h]=m*o[h],w+=2,u>b&&(k=E,N=z)}}return{knots_u:a,knots_v:t,control_points:v,degree_u:2,degree_v:i,weights:l}},verb.eval.nurbs.get_arc=function(e,r,n,t,i,s){return verb.eval.nurbs.get_ellipse_arc(e,r,n,t,t,i,s)},verb.eval.nurbs.curve_bezier_decompose=function(e,r,n){for(var t=verb.eval.nurbs.knot_multiplicities(r),i=e+1,s=verb.eval.nurbs.curve_knot_refine,o=0;t.length>o;o++)if(i>t[o][1]){var u=numeric.rep([i-t[o][1]],t[o][0]),a=s(e,r,n,u);r=a.knots,n=a.control_points}r.length/i-1;for(var v=2*i,l=[],o=0;n.length>o;o+=i){var c=r.slice(o,o+v),h=n.slice(o,o+i);l.push({degree:e,knots:c,control_points:h})}return l},verb.eval.nurbs.knot_multiplicities=function(e){for(var r=[[e[0],0]],n=r[0],t=0;e.length>t;t++)Math.abs(e[t]-n[0])>verb.EPSILON&&(n=[e[t],0],r.push(n)),n[1]++;return r},verb.eval.nurbs.curve_split=function(e,r,n,t){for(var i=[],s=0;e+1>s;s++)i.push(t);var o=verb.eval.nurbs.curve_knot_refine(e,r,n,i),u=verb.eval.nurbs.knot_span(e,t,r),a=o.knots.slice(0,u+e+2),v=o.knots.slice(u+1),l=o.control_points.slice(0,u+1),c=o.control_points.slice(u+1);return[{degree:e,knots:a,control_points:l},{degree:e,knots:v,control_points:c}]},verb.eval.nurbs.curve_knot_refine=function(e,r,n,t){var i=n.length-1,s=i+e+1,o=t.length-1,u=verb.eval.nurbs.knot_span(e,t[0],r),a=verb.eval.nurbs.knot_span(e,t[o],r),v=Array(n.length+o+1),l=Array(r.length+o+1),c=0,h=0;for(c=0;u-e>=c;c++)v[c]=n[c];for(c=a-1;i>=c;c++)v[c+o+1]=n[c];for(c=0;u>=c;c++)l[c]=r[c];for(c=a+e;s>=c;c++)l[c+o+1]=r[c];c=a+e-1;var b=a+e+o;for(h=o;h>=0;h--){for(;t[h]<=r[c]&&c>u;)v[b-e-1]=n[c-e-1],l[b]=r[c],b-=1,c-=1;v[b-e-1]=v[b-e];for(var m=1;e>=m;m++){var g=b-e+m,_=l[b+m]-t[h];Math.abs(_)=h;h++)l[h]=r[h];for(h=1;i>=h;h++)l[u+h]=t;for(h=u+1;r.length>h;h++)l[h+i]=r[h];for(h=0;u-e>=h;h++)c[h]=n[h];for(h=u-s;o>h;h++)c[h+i]=n[h];for(h=0;e-s>=h;h++)v[h]=n[u-e+h];for(var b=0,m=0,g=1;i>=g;g++){for(b=u-e+g,h=0;e-g-s>=h;h++)m=(t-r[b+h])/(r[h+u+1]-r[b+h]),v[h]=numeric.add(numeric.mul(m,v[h+1]),numeric.mul(1-m,v[h]));c[b]=v[0],c[u+i-g-s]=v[e-g-s]}for(h=b+1;u-s>h;h++)c[h]=v[h-b];return{knots:l,control_points:c}},verb.eval.nurbs.rational_surface_curvature=function(e,r,n,t,i,s,o){var u=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,2,s,o),a=u[0][1],v=u[1][0],l=u[0][2],c=u[2][0],h=u[1][1],b=numeric.cross(a,v),m=numeric.dot(l,b),g=numeric.dot(h,b),_=numeric.dot(c,b),f=[[m,g],[g,_]],d=numeric.eig(f),p=d.lambda.x[0],y=d.lambda.x[1],x=.5*(p+y),k=p*y,N=numeric.add(numeric.mul(d.E.x[0][0],a),numeric.mul(d.E.x[0][1],v)),w=numeric.add(numeric.mul(d.E.x[1][0],a),numeric.mul(d.E.x[1][1],v));return{point:u[0][0],normal:b,mean:x,gaussian:k,shapeOperator:f,k1:p,k2:y,p1:N,p2:w,p1p:d.E.x[0],p2p:d.E.x[1]}},verb.eval.nurbs.rational_surface_derivs=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.surface_derivs(e,r,n,t,i,s,o,u),v=verb.eval.nurbs.separate_homo_derivs_2d(a),l=v[0],c=v[1],h=0,b=0,m=0,g=0,_=[],f=l[0][0].length;for(h=0;s>=h;h++)for(_.push([]),g=0;s-h>=g;g++){var u=l[h][g];for(m=1;g>=m;m++)u=numeric.sub(u,numeric.mul(numeric.mul(binomial.get(g,m),c[0][m]),_[h][g-m]));for(b=1;h>=b;b++){u=numeric.sub(u,numeric.mul(numeric.mul(binomial.get(h,b),c[b][0]),_[h-b][g]));var d=verb.eval.nurbs.zeros_1d(f);for(m=1;g>=m;m++)d=numeric.add(d,numeric.mul(numeric.mul(binomial.get(g,m),c[b][m]),_[h-b][g-m]));u=numeric.sub(u,numeric.mul(binomial.get(h,b),d))}_[h].push(numeric.mul(1/c[0][0],u))}return _},verb.eval.nurbs.rational_surface_point=function(e,r,n,t,i,s,o){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.surface_point(e,r,n,t,i,s,o))},verb.eval.nurbs.rational_curve_derivs=function(e,r,n,t,i){var s=verb.eval.nurbs.separate_homo_derivs_1d(verb.eval.nurbs.curve_derivs(e,r,n,t,i)),o=s[0],u=s[1],a=0,v=0,l=[];for(a=0;i>=a;a++){var c=o[a];for(v=1;a>=v;v++)c=numeric.sub(c,numeric.mul(numeric.mul(binomial.get(a,v),u[v]),l[a-v]));l.push(numeric.mul(1/u[0],c))}return l},verb.eval.nurbs.separate_homo_derivs_1d=function(e){for(var r=e[0].length,n=r-1,t=[],i=[],s=0,o=e.length;o>s;s++)t.push(e[s].slice(0,n)),i.push(e[s][n]);return[t,i]},verb.eval.nurbs.separate_homo_derivs_2d=function(e){for(var r=[],n=[],t=0,i=e.length;i>t;t++){var s=verb.eval.nurbs.separate_homo_derivs_1d(e[t]);r.push(s[0]),n.push(s[1])}return[r,n]},verb.eval.nurbs.rational_curve_point=function(e,r,n,t){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.curve_point(e,r,n,t))},verb.eval.nurbs.dehomogenize=function(e){for(var r=e.length,n=[],t=e[r-1],i=0;e.length-1>i;i++)n.push(e[i]/t);return n},verb.eval.nurbs.weight_1d=function(e){var r=e[0].length-1;return e.map(function(e){return e[r]})},verb.eval.nurbs.dehomogenize_1d=function(e){return e.map(function(e){return verb.eval.nurbs.dehomogenize(e)})},verb.eval.nurbs.homogenize_1d=function(e,r){for(var n=e.length,t=e[0].length,i=0,s=[],o=0,u=[],a=0;n>a;a++){var v=[];for(u=e[a],o=r[a],i=0;t>i;i++)v.push(u[i]*o);v.push(o),s.push(v)}return s},verb.eval.nurbs.homogenize_2d=function(e,r){for(var n=e.length,t=(e[0].length,e[0][0].length,[]),i=0;n>i;i++)t.push(verb.eval.nurbs.homogenize_1d(e[i],r[i]));return t},verb.eval.nurbs.surface_derivs=function(e,r,n,t,i,s,o,u){var a=r.length-e-2,v=t.length-n-2;return verb.eval.nurbs.surface_derivs_given_n_m(a,e,r,v,n,t,i,s,o,u)},verb.eval.nurbs.surface_derivs_given_n_m=function(e,r,n,t,i,s,o,u,a,v){if(verb.eval.nurbs.are_valid_relations(r,o.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,o[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var l=o[0][0].length,c=Math.min(u,r),h=Math.min(u,i),b=verb.eval.nurbs.zeros_3d(c+1,h+1,l),m=verb.eval.nurbs.knot_span_given_n(e,r,a,n),g=verb.eval.nurbs.knot_span_given_n(t,i,v,s),_=verb.eval.nurbs.deriv_basis_functions_given_n_i(m,a,r,e,n),f=verb.eval.nurbs.deriv_basis_functions_given_n_i(g,v,i,t,s),d=verb.eval.nurbs.zeros_2d(i+1,l),p=0,y=0,x=0,k=0,N=0;for(p=0;c>=p;p++){for(y=0;i>=y;y++)for(d[y]=verb.eval.nurbs.zeros_1d(l),x=0;r>=x;x++)d[y]=numeric.add(d[y],numeric.mul(_[p][x],o[m-r+x][g-i+y]));for(N=Math.min(u-p,h),k=0;N>=k;k++)for(b[p][k]=verb.eval.nurbs.zeros_1d(l),y=0;i>=y;y++)b[p][k]=numeric.add(b[p][k],numeric.mul(f[k][y],d[y]))}return b},verb.eval.nurbs.surface_point=function(e,r,n,t,i,s,o){var u=r.length-e-2,a=t.length-n-2;return verb.eval.nurbs.surface_point_given_n_m(u,e,r,a,n,t,i,s,o)},verb.eval.nurbs.volume_point=function(e,r,n,t,i,s,o,u,a,v){var l=r.length-e-2,c=t.length-n-2,h=s.length-i-2;return verb.eval.nurbs.volume_point_given_n_m_l(l,e,r,c,n,t,h,i,s,o,u,a,v)},verb.eval.nurbs.volume_point_given_n_m_l=function(e,r,n,t,i,s,o,u,a,v,l,c,h){if(!verb.eval.nurbs.are_valid_relations(r,v.length,n.length)||!verb.eval.nurbs.are_valid_relations(i,v[0].length,s.length)||!verb.eval.nurbs.are_valid_relations(u,v[0][0].length,a.length))return console.error("Invalid relations between control points and knot vector"),null;for(var b=v[0][0][0].length,m=verb.eval.nurbs.knot_span_given_n(e,r,l,n),g=verb.eval.nurbs.knot_span_given_n(t,i,c,s),_=verb.eval.nurbs.knot_span_given_n(o,u,h,a),f=verb.eval.nurbs.basis_functions_given_knot_span_index(m,l,r,n),d=verb.eval.nurbs.basis_functions_given_knot_span_index(g,c,i,s),p=verb.eval.nurbs.basis_functions_given_knot_span_index(_,h,u,a),y=m-r,x=g,k=_,N=verb.eval.nurbs.zeros_1d(b),w=verb.eval.nurbs.zeros_1d(b),E=verb.eval.nurbs.zeros_1d(b),z=0,A=0,M=0;u>=M;M++){for(E=verb.eval.nurbs.zeros_1d(b),k=_-u+M,z=0;i>=z;z++){for(w=verb.eval.nurbs.zeros_1d(b),x=g-i+z,A=0;r>=A;A++)w=numeric.add(w,numeric.mul(f[A],v[y+A][x][k]));E=numeric.add(E,numeric.mul(d[z],w))}N=numeric.add(N,numeric.mul(p[M],E))}return N},verb.eval.nurbs.surface_point_given_n_m=function(e,r,n,t,i,s,o,u,a){if(verb.eval.nurbs.are_valid_relations(r,o.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,o[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var v=o[0][0].length,l=verb.eval.nurbs.knot_span_given_n(e,r,u,n),c=verb.eval.nurbs.knot_span_given_n(t,i,a,s),h=verb.eval.nurbs.basis_functions_given_knot_span_index(l,u,r,n),b=verb.eval.nurbs.basis_functions_given_knot_span_index(c,a,i,s),m=l-r,g=c,_=verb.eval.nurbs.zeros_1d(v),f=verb.eval.nurbs.zeros_1d(v),d=0,p=0;for(d=0;i>=d;d++){for(f=verb.eval.nurbs.zeros_1d(v),g=c-i+d,p=0;r>=p;p++)f=numeric.add(f,numeric.mul(h[p],o[m+p][g]));_=numeric.add(_,numeric.mul(b[d],f))}return _},verb.eval.nurbs.curve_derivs=function(e,r,n,t,i){var s=r.length-e-2;return verb.eval.nurbs.curve_derivs_given_n(s,e,r,n,t,i)},verb.eval.nurbs.curve_derivs_given_n=function(e,r,n,t,i,s){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null; +"use strict";function Node(e,r,n){this.obj=e,this.left=null,this.right=null,this.parent=n,this.dimension=r}function KdTree(e,r,n){function t(e,r,i){var s,o,u=r%n.length;return 0===e.length?null:1===e.length?new Node(e[0],u,i):(e.sort(function(e,r){return e[n[u]]-r[n[u]]}),s=Math.floor(e.length/2),o=new Node(e[s],u,i),o.left=t(e.slice(0,s),r+1,o),o.right=t(e.slice(s+1),r+1,o),o)}var i=this;this.root=t(e,0,null),this.insert=function(e){function r(t,i){if(null===t)return i;var s=n[t.dimension];return e[s]s&&(a=o),null!==u&&u.obj[i]>a.obj[i]&&(a=u),a))}function s(e,r){var t,i,o,u,a;return null===e?null:(t=n[r],e.dimension===r?null!==e.left?s(e.left,r):e:(i=e.obj[t],o=s(e.left,r),u=s(e.right,r),a=e,null!==o&&i>o.obj[t]&&(a=o),null!==u&&u.obj[t]t&&v.pop()}var u,a,l,c,h=n[i.dimension],b=r(e,i.obj),m={};for(c=0;n.length>c;c+=1)m[n[c]]=c===i.dimension?e[n[c]]:i.obj[n[c]];return a=r(m,i.obj),null===i.right&&null===i.left?((t>v.size()||v.peek()[1]>b)&&s(i,b),void 0):(u=null===i.right?i.left:null===i.left?i.right:e[h]v.size()||v.peek()[1]>b)&&s(i,b),(t>v.size()||Math.abs(a)u;u+=1)v.push([null,s]);for(o(i.root),a=[],u=0;t>u;u+=1)v.content[u][0]&&a.push([v.content[u][0].obj,v.content[u][1]]);return a},this.balanceFactor=function(){function e(r){return null===r?0:Math.max(e(r.left),e(r.right))+1}function r(e){return null===e?0:r(e.left)+r(e.right)+1}return e(i.root)/(Math.log(r(i.root))/Math.log(2))}}function BinaryHeap(e){this.content=[],this.scoreFunction=e}function crossprod(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]}if("object"!=typeof exports||void 0===exports)var verb={},numeric=window.numeric,binomial=window.binomial,labor=window.labor;else var verb=module.exports={},numeric=require("numeric"),binomial=require("binomial"),labor=require("labor");verb.geom=verb.geom||{},verb.core=verb.core||{},verb.eval=verb.eval||{},verb.intersect=verb.intersect||{},verb.eval.nurbs=verb.eval.nurbs||{},verb.eval.geom=verb.eval.geom||{},verb.eval.mesh=verb.eval.mesh||{},verb.EPSILON=1e-10,verb.TOLERANCE=1e-6,verb.init=function(){verb.nurbsEngine=new verb.core.Engine(verb.eval.nurbs),verb.geom.NurbsGeometry.prototype.nurbsEngine=verb.nurbsEngine},Function.prototype.method=function(e,r){return this.prototype[e]=r,this},Function.method("inherits",function(e){return this.prototype=new e,this.prototype,this.prototype.constructor=e,this}),Array.prototype.flatten=function(){if(0==this.length)return[];for(var e=[],r=0;this.length>r;r++)e=this[r]instanceof Array?e.concat(this[r].flatten()):e.concat(this[r]);return e},numeric.normalized=function(e){return numeric.div(e,numeric.norm2(e))},numeric.cross=function(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]},verb.left=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(0,r)},verb.right=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r)},verb.last=function(e){return e.length?e[e.length-1]:void 0},verb.rightWithPivot=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r-1)},verb.unique=function(e,r){if(0===e.length)return[];for(var n=[e.pop()];e.length>0;){for(var t=e.pop(),i=!0,s=0;n.length>s;s++)if(r(t,n[s])){i=!1;break}i&&n.push(t)}return n},verb.range=function(e,r,n){1>=arguments.length&&(r=e||0,e=0),n=arguments[2]||1;for(var t=Math.max(Math.ceil((r-e)/n),0),i=0,s=Array(t);t>i;)s[i++]=e,e+=n;return s},BinaryHeap.prototype={push:function(e){this.content.push(e),this.bubbleUp(this.content.length-1)},pop:function(){var e=this.content[0],r=this.content.pop();return this.content.length>0&&(this.content[0]=r,this.sinkDown(0)),e},peek:function(){return this.content[0]},remove:function(e){for(var r=this.content.length,n=0;r>n;n++)if(this.content[n]==e){var t=this.content.pop();return n!=r-1&&(this.content[n]=t,this.scoreFunction(t)0;){var n=Math.floor((e+1)/2)-1,t=this.content[n];if(!(this.scoreFunction(r)s){var u=this.content[s],a=this.scoreFunction(u);t>a&&(o=s)}if(r>i){var v=this.content[i],l=this.scoreFunction(v);(null==o?t:a)>l&&(o=i)}if(null==o)break;this.content[e]=this.content[o],this.content[o]=n,e=o}}},verb.core.Engine=function(e){var r="function"==typeof Worker&&(e.use_pool||void 0===e.use_pool),n=e.num_workers||2,t=e.tolerance||1e-4,i=e.url||"js/verbEval.js",s=e.library||verb.eval.nurbs,o=e.error_handler||function(e){console.warn(e)},u=void 0,a=function(){try{u=new labor.Pool(i,n),u.start()}catch(e){return o("Failed to initialize labor.Pool: "+e),!1}return!0},v=function(e,r){return s[e].apply(null,r)};this.start=function(){r&&a()},this.eval=function(e,n,t){return t?(r&&(u||void 0===u&&a())?u.addWork(e,n,t):setTimeout(function(){t(v(e,n))},0),void 0):v(e,n)},this.setTolerance=function(e){t=e},this.setUsePool=function(e){return e&&void 0===u&&a()?(r=e,!0):e?!1:(u=null,!0)},this.setErrorHandler=function(e){o=e},this.setNumThreads=function(e){n=e}},verb.core.WatchObject=function(){var e={change:{}},r={},n=0,t=this,i=function(r,n){if("string"==typeof r){for(var t in e[r])e[r][t](n);for(var t in e.change)e.change[t](n)}else for(var s in r)i(s,n)};this.get=function(e){return r[e]},this.set=function(n,s){var o=r[n];r[n]=s,e[n]=e[n]||{},i(n,{name:n,old:o,"new":s,target:t,type:"full"})},this.setAll=function(n){var s={};for(var o in n)s[o]=r[o],r[o]=n[o],e[o]=e[o]||{};i(n,{old:s,"new":n,target:t,type:"multi"})},this.setAt=function(e,n,s){var o=r[e];if(!(void 0===o||o.length>=n||0>n)){var u=r[e][n];r[e][n]=s,i(e,{name:e,index:n,old:u,"new":s,target:t,type:"index"})}},this.watch=function(t,i){return void 0!==r[t]&&i?(n++,e[t][n]=i,n++):void 0},this.watchAll=function(e,r){for(var n=[],t=0;e.length>t;t++)n.push(this.watch(e[t],r));return n},this.ignore=function(r,n){void 0!==e[r]&&void 0!==e[r][n]&&(e[r][n]=void 0)}},verb.core.uid=function(){var e=0;return function(){return e++}}(),verb.geom.Geometry=function(){verb.core.WatchObject.call(this);var e=verb.core.uid();this.uniqueId=function(){return e}}.inherits(verb.core.WatchObject),verb.geom.NurbsGeometry=function(){verb.geom.Geometry.call(this)}.inherits(verb.geom.Geometry),verb.geom.NurbsCurve=function(e,r,n,t){verb.geom.NurbsGeometry.call(this),this.setAll({controlPoints:r,weights:n,knots:t?t.slice(0):[],degree:e})}.inherits(verb.geom.NurbsGeometry),verb.geom.NurbsCurve.prototype.point=function(e,r){return this.nurbsEngine.eval("rational_curve_point",[this.get("degree"),this.get("knots"),this.homogenize(),e],r)},verb.geom.NurbsCurve.prototype.derivatives=function(e,r,n){return this.nurbsEngine.eval("rational_curve_derivs",[this.get("degree"),this.get("knots"),this.homogenize(),e,r||1],n)},verb.geom.NurbsCurve.prototype.tessellate=function(e,r){var e=e||{};return e.tolerance=e.tolerance||verb.EPSILON,this.nurbsEngine.eval("rational_curve_adaptive_sample",[this.get("degree"),this.get("knots"),this.homogenize(),e.tolerance],r)},verb.geom.NurbsCurve.prototype.split=function(e,r){function n(e){var r=verb.eval.nurbs.dehomogenize_1d(e[0].control_points),n=verb.eval.nurbs.weight_1d(e[0].control_points),t=new verb.geom.NurbsCurve(e[0].degree,r,n,e[0].knots),i=verb.eval.nurbs.dehomogenize_1d(e[1].control_points),s=verb.eval.nurbs.weight_1d(e[1].control_points),o=new verb.geom.NurbsCurve(e[1].degree,i,s,e[1].knots);return[t,o]}var t=this.domain();if(t[0]>=e||e>=t[1])throw Error("Cannot split outside of the domain of the curve!");return r?this.nurbsEngine.eval("curve_split",[this.get("degree"),this.get("knots"),this.homogenize(),e],function(e){return r(n(e))}):n(this.nurbsEngine.eval("curve_split",[this.get("degree"),this.get("knots"),this.homogenize(),e]))},verb.geom.NurbsCurve.prototype.domain=function(){var e=this.get("knots");return[e[0],e[e.length-1]]},verb.geom.NurbsCurve.prototype.transform=function(e){for(var r=this.get("controlPoints"),n=0;r.length>n;n++){var t=r[1].push(1);r[n]=numeric.mul(e,t).slice(0,t.length-2)}return this.set("controlPoints",r),this},verb.geom.NurbsCurve.prototype.clone=function(){for(var e=this.get("controlPoints"),r=[],n=0;e.length>n;n++)r.push(e[n].slice(0));return new verb.geom.NurbsCurve(this.get("degree"),r,this.get("weights").slice(0),this.get("knots").slice)},verb.geom.NurbsCurve.prototype.homogenize=function(){return verb.eval.nurbs.homogenize_1d(this.get("controlPoints"),this.get("weights"))},verb.geom.NurbsCurve.prototype.update=function(){if(this.nurbsRep){var e=this.nurbsRep();this.setAll({controlPoints:e.control_points,weights:e.weights,knots:e.knots,degree:e.degree})}},verb.geom.NurbsSurface=function(e,r,n,t,i,s){verb.geom.NurbsGeometry.call(this),this.setAll({controlPoints:i,weights:s,knotsU:r?r.slice(0):[],knotsV:t?t.slice(0):[],degreeU:e,degreeV:n})}.inherits(verb.geom.NurbsGeometry),verb.geom.NurbsSurface.prototype.point=function(e,r,n){return this.nurbsEngine.eval("rational_surface_point",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),e,r],n)},verb.geom.NurbsSurface.prototype.derivatives=function(e,r,n,t){return this.nurbsEngine.eval("rational_surface_derivs",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),n||1,e,r],t)},verb.geom.NurbsSurface.prototype.tessellate=function(e,r){var n=20,t=20;return e&&(n=e.minDivsV||n,t=e.minDivsU||t),this.nurbsEngine.eval("tessellate_rational_surface_naive",[this.get("degreeU"),this.get("knotsU"),this.get("degreeV"),this.get("knotsV"),this.homogenize(),t,n],r)},verb.geom.NurbsSurface.prototype.domain=function(){var e=this.get("knotsU"),r=this.get("knotsV");return[[e[0],e[e.length-1]],[r[0],r[r.length-1]]]},verb.geom.NurbsSurface.prototype.transform=function(e){for(var r=this.get("controlPoints"),n=0;r.length>n;n++)for(var t=0;r[n].length>t;t++){var i=r[1].push(1);r[n]=numeric.mul(e,i).slice(0,i.length-2)}return this.set("controlPoints",r),this},verb.geom.NurbsSurface.prototype.clone=function(){for(var e=this.get("controlPoints"),r=[],n=0;e.length>n;n++){r.push([]);for(var t=0;e[n].length>t;t++)r[n].push(e[n][t].slice(0))}for(var i=this.get("weights"),s=[],n=0;i.length>n;n++)s.push(i[n].slice(0));return new verb.geom.NurbsSurface(this.get("degreeU"),this.get("knotsU").slice(0),this.get("degreeV"),this.get("knotsV").slice(0),r,s)},verb.geom.NurbsSurface.prototype.homogenize=function(){return verb.eval.nurbs.homogenize_2d(this.get("controlPoints"),this.get("weights"))},verb.geom.NurbsSurface.prototype.update=function(){if(this.nurbsRep){var e=this.nurbsRep();this.setAll({controlPoints:e.control_points,weights:e.weights,knotsU:e.knots_u,knotsV:e.knots_v,degreeU:e.degree_u,degreeV:e.degree_v})}},verb.geom.Arc=function(e,r,n,t,i){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,radius:t,interval:i}),this.update(),this.watchAll(["center","xaxis","yaxis","radius","interval"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Arc.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("radius"),this.get("interval").get("min"),this.get("interval").get("max")])},verb.geom.BezierCurve=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({controlPoints:e?e.slice(0):[],weights:r?r.slice(0):void 0}),this.update()}.inherits(verb.geom.NurbsCurve),verb.geom.BezierCurve.prototype.nurbsRep=function(){for(var e=this.get("controlPoints"),r=this.get("weights"),n=e.length-1,t=[],i=0;n+1>i;i++)t.push(0);for(var i=0;n+1>i;i++)t.push(1);if(void 0===r){r=[];for(var i=0;e.length>i;i++)r.push(1)}return{degree:n,knots:t,control_points:e,weights:r}},verb.geom.BoundingBox=function(){this.initialized=!1,this.min=[0,0,0],this.max=[0,0,0];var e=Array.prototype.slice.call(arguments,0);1===e.length&&e[0]instanceof Array&&e[0][0]instanceof Array?this.add_elements_sync(e[0]):this.add_elements_sync(e)},verb.geom.BoundingBox.prototype.add_elements=function(e,r){var n=this;setTimeout(function(){e.forEach(function(e){n.add(e)}),r(n)},0)},verb.geom.BoundingBox.prototype.add_elements_sync=function(e){var r=this;return e.forEach(function(e){r.add(e)}),this},verb.geom.BoundingBox.prototype.add=function(e){return this.initialized?(e[0]>this.max[0]&&(this.max[0]=e[0]),e[1]>this.max[1]&&(this.max[1]=e[1]),e[2]>this.max[2]&&(this.max[2]=e[2]),e[0]=u&&a>=s||o>=u&&a>=o||u>=s&&o>=u||a>=s&&o>=a?!0:!1},verb.geom.BoundingBox.prototype.intersects=function(e,r){if(!this.initialized||!e.initialized)return!1;var n=this.min,t=this.max,i=e.min,s=e.max;return this.intervals_overlap(n[0],t[0],i[0],s[0],r)&&this.intervals_overlap(n[1],t[1],i[1],s[1],r)&&this.intervals_overlap(n[2],t[2],i[2],s[2],r)?!0:!1},verb.geom.BoundingBox.prototype.clear=function(){return this.initialized=!1,this},verb.geom.BoundingBox.prototype.get_longest_axis=function(){var e=[this.get_axis_length(0),this.get_axis_length(1),this.get_axis_length(2)];return e.indexOf(Math.max.apply(Math,e))},verb.geom.BoundingBox.prototype.get_axis_length=function(e){return 0>e||e>2?0:Math.abs(this.min[e]-this.max[e])},verb.geom.BoundingBox.prototype.intersect=function(e,r){if(!this.initialized)return null;var n=this.min,t=this.max,i=e.min,s=e.max;if(!this.intersects(e,r))return null;var o=Math.min(t[0],s[0]),u=Math.max(n[0],i[0]),a=Math.min(t[1],s[1]),v=Math.max(n[1],i[1]),l=Math.min(t[2],s[2]),c=Math.max(n[2],i[2]),h=[o,a,l],b=[u,v,c];return new verb.geom.BoundingBox(b,h)},verb.geom.Circle=function(e,r,n,t){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,radius:t}),this.update(),this.watchAll(["center","xaxis","yaxis","radius"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Circle.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("radius"),0,2*Math.PI])},verb.geom.Cone=function(e,r,n,t,i){verb.geom.NurbsSurface.call(this),this.setAll({axis:e,xaxis:r,base:n,height:t,radius:i});var s=this.nurbsRep();verb.geom.NurbsSurface.call(this,s.degree_u,s.knots_u,s.degree_v,s.knots_v,s.control_points,s.weights),this.watchAll(["axis","xaxis","base","height","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Cone.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_cone_surface",[this.get("axis"),this.get("xaxis"),this.get("base"),this.get("height"),this.get("radius")])},verb.geom.Cylinder=function(e,r,n,t,i){this.setAll({axis:e,xaxis:r,base:n,height:t,radius:i});var s=this.nurbsRep();verb.geom.NurbsSurface.call(this,s.degree_u,s.knots_u,s.degree_v,s.knots_v,s.control_points,s.weights),this.watchAll(["axis","xaxis","base","height","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Cylinder.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_cylinder_surface",[this.get("axis"),this.get("xaxis"),this.get("base"),this.get("height"),this.get("radius")])},verb.geom.Ellipse=function(e,r,n,t,i){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,xradius:t,yradius:i}),this.update(),this.watchAll(["center","xaxis","yaxis","xradius","yradius"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Ellipse.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_ellipse_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("xradius"),this.get("yradius"),0,2*Math.PI])},verb.geom.EllipseArc=function(e,r,n,t,i,s){verb.geom.NurbsCurve.call(this),this.setAll({center:e,xaxis:r,yaxis:n,xradius:t,yradius:i,interval:s}),this.update(),this.watchAll(["center","xaxis","yaxis","xradius","yradius","interval"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.EllipseArc.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_ellipse_arc",[this.get("center"),this.get("xaxis"),this.get("yaxis"),this.get("xradius"),this.get("yradius"),this.get("interval").get("min"),this.get("interval").get("max")])},verb.geom.Extrusion=function(e,r,n){verb.geom.NurbsSurface.call(this),this.setAll({profile:e,axis:r,length:n}),this.update(),this.watchAll(["axis","length"],this.update),e.watchAll(["knots","degree","controlPoints","weights"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Extrusion.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_extruded_surface",[this.get("axis"),this.get("length"),this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights")])},verb.geom.FourPointSurface=function(e,r,n,t){verb.geom.NurbsSurface.call(this),this.setAll({p1:e,p2:r,p3:n,p4:t}),this.update(),this.watchAll(["p1","p2","p3","p4"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.FourPointSurface.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_4pt_surface",[this.get("p1"),this.get("p2"),this.get("p3"),this.get("p4")])},verb.geom.InterpCurve=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({pts:e?e.slice(0):[],degree:r?r:3}),this.update(),this.watchAll(["pts","degree"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.InterpCurve.prototype.nurbsRep=function(){return this.nurbsEngine.eval("rational_interp_curve",[this.get("pts"),this.get("degree")])},verb.geom.Interval=function(e,r){verb.core.WatchObject.call(this),this.setAll({min:e,max:r})}.inherits(verb.core.WatchObject),verb.geom.Interval2=function(e,r,n,t){verb.core.WatchObject.call(this),this.setAll({uinterval:new verb.geom.Interval(e,r),vinterval:new verb.geom.Interval(n,t)})}.inherits(verb.core.WatchObject),verb.geom.Line=function(e,r){verb.geom.NurbsCurve.call(this),this.setAll({start:e,end:r}),this.update(),this.watchAll(["start","end"],this.update)}.inherits(verb.geom.NurbsCurve),verb.geom.Line.prototype.nurbsRep=function(){return{knots:[0,0,1,1],control_points:[this.get("start"),this.get("end")],weights:[1,1],degree:1}},verb.geom.PlanarSurface=function(e,r,n,t,i){verb.geom.NurbsSurface.call(this),this.setAll({base:e,uaxis:r,vaxis:n,ulength:t,vlength:i}),this.update(),this.watchAll(["base","uaxis","vaxis","ulength","vlength"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.PlanarSurface.prototype.nurbsRep=function(){var e=this.get("base"),r=numeric.mul(this.get("uaxis"),this.get("ulength")),n=numeric.mul(this.get("vaxis"),this.get("vlength")),t=numeric.add(e,r),i=numeric.add(e,n,r),s=numeric.add(e,n);return this.nurbsEngine.eval("get_4pt_surface",[e,t,i,s])},verb.geom.PolyLine=function(e){verb.geom.NurbsCurve.call(this),this.setAll({control_points:e?e.slice(0):[]}),this.update()}.inherits(verb.geom.NurbsCurve),verb.geom.PolyLine.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_polyline_curve",[this.get("control_points")])},verb.geom.RevolvedSurface=function(e,r,n,t){verb.geom.NurbsSurface.call(this),this.setAll({center:e,axis:r,angle:n,profile:t}),this.update(),this.watchAll(["center","axis","angle","profile"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.RevolvedSurface.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_revolved_surface",[this.get("center"),this.get("axis"),this.get("angle"),this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights")])},verb.geom.Sphere=function(e,r){verb.geom.NurbsSurface.call(this),this.setAll({center:e,radius:r}),this.update(),this.watchAll(["center","radius"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.Sphere.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_sphere_surface",[this.get("center"),[0,0,1],[1,0,0],this.get("radius")])},verb.geom.SweepOneRail=function(e,r){verb.geom.NurbsSurface.call(this),this.setAll({rail:e,profile:r}),this.update(),this.watchAll(["rail","profile"],this.update)}.inherits(verb.geom.NurbsSurface),verb.geom.SweepOneRail.prototype.nurbsRep=function(){return this.nurbsEngine.eval("get_sweep1_surface",[this.get("profile").get("knots"),this.get("profile").get("degree"),this.get("profile").get("controlPoints"),this.get("profile").get("weights"),this.get("rail").get("knots"),this.get("rail").get("degree"),this.get("rail").get("controlPoints"),this.get("rail").get("weights")])},verb.intersect.curveCurve=function(e,r,n){return verb.nurbsEngine.eval("intersect_rational_curves_by_aabb_refine",[e.get("degree"),e.get("knots"),e.homogenize(),r.get("degree"),r.get("knots"),r.homogenize(),verb.TOLERANCE,verb.TOLERANCE],n)},verb.intersect.curveSurface=function(e,r,n,t){return n=n||{tolerance:verb.TOLERANCE,sampleTolerance:verb.TOLERANCE,uDivs:20,vDivs:20},verb.nurbsEngine.eval("intersect_rational_curve_surface_by_aabb_refine",[r.get("degreeU"),r.get("knotsU"),r.get("degreeV"),r.get("knotsV"),r.homogenize(),e.get("degree"),e.get("knots"),e.homogenize(),n.sampleTolerance,n.tolerance,n.uDivs,n.vDivs],t)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb_refine=function(e,r,n,t,i,s,o,u,a,v,l,c){var h=verb.eval.nurbs.intersect_rational_curve_surface_by_aabb(e,r,n,t,i,s,o,u,a,v,l,c);return h.map(function(a){var v=[a.p,a.uv[0],a.uv[1]],l=verb.eval.nurbs.refine_rational_curve_surface_intersection(e,r,n,t,i,s,o,u,v);return a.p=l[0],a.uv[0]=l[1],a.uv[1]=l[2],a.distance=l[3],delete a.face,a})},verb.eval.nurbs.refine_rational_curve_surface_intersection=function(e,r,n,t,i,s,o,u,a){var v=function(a){var v=verb.eval.nurbs.rational_curve_point(s,o,u,a[0]),l=verb.eval.nurbs.rational_surface_point(e,r,n,t,i,a[1],a[2]),c=numeric.sub(v,l);return numeric.dot(c,c)},l=numeric.uncmin(v,a);return l.solution.concat(l.f)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb=function(e,r,n,t,i,s,o,u,a,v,l,c){var h=verb.eval.nurbs.rational_curve_adaptive_sample(s,o,u,a,!0),b=verb.eval.nurbs.tessellate_rational_surface_naive(e,r,n,t,i,l,c),m=h.map(function(e){return e[0]}),g=h.map(function(e){return e.slice(1)}),_=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb(g,m,b,verb.range(b.faces.length),v);return verb.unique(_,function(e,r){return v>numeric.norm2(numeric.sub(e.point,r.point))&&v>Math.abs(e.p-r.p)&&v>numeric.norm2(numeric.sub(e.uv,r.uv))})},verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),o=verb.eval.mesh.make_mesh_aabb(n.points,n.faces,t),u=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb;if(!s.intersects(o,i))return[];if(2!==e.length||1!==t.length){if(1===t.length){var a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return u(a,l,n,t,i).concat(u(v,c,n,t,i))}if(2===e.length){var h=verb.eval.mesh.sort_tris_on_longest_axis(o,n.points,n.faces,t),b=verb.left(h),m=verb.right(h);return u(e,r,n,b,i).concat(u(e,r,n,m,i))}var h=verb.eval.mesh.sort_tris_on_longest_axis(o,n.points,n.faces,t),b=verb.left(h),m=verb.right(h),a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return u(a,l,n,b,i).concat(u(a,l,n,m,i)).concat(u(v,c,n,b,i)).concat(u(v,c,n,m,i))}var g=verb.eval.geom.intersect_segment_with_tri(e[0],e[1],n.points,n.faces[t[0]]);if(null!=g){var _=g.p*(r[1]-r[0])+r[0],f=n.faces[t][0],d=n.faces[t][1],p=n.faces[t][2],y=n.uvs[f],x=n.uvs[d],k=n.uvs[p],N=numeric.sub(x,y),w=numeric.sub(k,y),E=numeric.add(y,numeric.mul(g.s,N),numeric.mul(g.t,w));return[{point:g.point,p:_,uv:E,face:t[0]}]}return[]},verb.eval.geom.intersect_segment_with_tri=function(e,r,n,t){var i=n[t[0]],s=n[t[1]],o=n[t[2]],u=numeric.sub(s,i),a=numeric.sub(o,i),v=numeric.cross(u,a),l=numeric.sub(r,e),c=numeric.sub(e,i),h=-numeric.dot(v,c),b=numeric.dot(v,l);if(Math.abs(b)m||m>1)return null;var g=numeric.add(e,numeric.mul(m,l)),_=numeric.dot(u,a),f=numeric.dot(u,u),d=numeric.dot(a,a),p=numeric.sub(g,i),y=numeric.dot(p,u),x=numeric.dot(p,a),k=_*_-f*d,N=(_*x-d*y)/k,w=(_*y-f*x)/k;return N>1+verb.EPSILON||w>1+verb.EPSILON||-verb.EPSILON>w||-verb.EPSILON>N||N+w>1+verb.EPSILON?null:{point:g,s:N,t:w,p:m}},verb.eval.geom.intersect_segment_with_plane=function(e,r,n,t){var i=numeric.dot(t,numeric.sub(e,r));if(EPSILON>abs(i))return null;var s=numeric.dot(t,numeric.sub(n,e));return{p:s/i}},verb.eval.geom.intersect_aabb_trees=function(e,r,n,t,i,s){var o=i.bounding_box.intersects(s.bounding_box),u=verb.eval.geom.intersect_aabb_trees;return o?0===i.children.length&&0===s.children.length?[[i.triangle,s.triangle]]:0===i.children.length&&0!=s.children.length?u(e,r,n,t,i,s.children[0]).concat(u(e,r,n,t,i,s.children[1])):0!=i.children.length&&0===s.children.length?u(e,r,n,t,i.children[0],s).concat(u(e,r,n,t,i.children[1],s)):0!=i.children.length&&0!=s.children.length?u(e,r,n,t,i.children[0],s.children[0]).concat(u(e,r,n,t,i.children[0],s.children[1])).concat(u(e,r,n,t,i.children[1],s.children[0])).concat(u(e,r,n,t,i.children[1],s.children[1])):void 0:[]},verb.eval.mesh.make_mesh_aabb_tree=function(e,r,n){var t={bounding_box:verb.eval.mesh.make_mesh_aabb(e,r,n),children:[]};if(1===n.length)return t.triangle=n[0],t;var i=verb.eval.mesh.sort_tris_on_longest_axis(t.bounding_box,e,r,n),s=i.slice(0,Math.floor(i.length/2)),o=i.slice(Math.floor(i.length/2),i.length);return t.children=[verb.eval.mesh.make_mesh_aabb_tree(e,r,s),verb.eval.mesh.make_mesh_aabb_tree(e,r,o)],t},verb.eval.mesh.make_mesh_aabb=function(e,r,n){var t=new verb.geom.BoundingBox;return n.forEach(function(n){t.add(e[r[n][0]]),t.add(e[r[n][1]]),t.add(e[r[n][2]])}),t},verb.eval.mesh.sort_tris_on_longest_axis=function(e,r,n,t){for(var i=e.get_longest_axis(),s=[],o=t.length-1;o>=0;o--){var u=t[o],a=verb.eval.mesh.get_min_coordinate_on_axis(r,n[u],i);s.push([a,u])}s.sort(function(e,r){return e[0]>r[0]});for(var v=[],o=0,l=s.length;l>o;o++)v.push(s[o][1]);return v},verb.eval.mesh.get_min_coordinate_on_axis=function(e,r,n){for(var t=[],i=0;3>i;i++)t.push(e[r[i]][n]);return Math.min.apply(Math,t)},verb.eval.geom.get_tri_centroid=function(e,r){for(var n=[0,0,0],t=0;3>t;t++)for(var i=0;3>i;i++)n[i]+=e[r[t]][i];for(var t=0;3>t;t++)n[t]/=3;return n},verb.eval.geom.get_tri_norm=function(e,r){var n=e[r[0]],t=e[r[1]],i=e[r[2]],s=numeric.sub(t,n),o=numeric.sub(i,n),u=numeric.cross(s,o);return numeric.mul(1/numeric.norm2(u),u)},verb.eval.nurbs.intersect_rational_curves_by_aabb_refine=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.intersect_rational_curves_by_aabb(e,r,n,t,i,s,o,u);return a.map(function(o){return verb.eval.nurbs.refine_rational_curve_intersection(e,r,n,t,i,s,o)})},verb.eval.nurbs.refine_rational_curve_intersection=function(e,r,n,t,i,s,o){var u=function(o){var u=verb.eval.nurbs.rational_curve_point(e,r,n,o[0]),a=verb.eval.nurbs.rational_curve_point(t,i,s,o[1]),v=numeric.sub(u,a);return numeric.dot(v,v)},a=numeric.uncmin(u,o);return a.solution.concat(a.f)},verb.eval.nurbs.intersect_rational_curves_by_aabb=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.rational_curve_adaptive_sample(e,r,n,o,!0),v=verb.eval.nurbs.rational_curve_adaptive_sample(t,i,s,o,!0),l=a.map(function(e){return e[0]}),c=v.map(function(e){return e[0]}),h=a.map(function(e){return e.slice(1)}),b=v.map(function(e){return e.slice(1)});return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,b,l,c,u)},verb.eval.nurbs.intersect_parametric_polylines_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),o=new verb.geom.BoundingBox(r);if(!s.intersects(o,i))return[];if(2!==e.length||2!==r.length){if(2===e.length){var u=Math.ceil(r.length/2),a=r.slice(0,u),v=r.slice(u-1),l=t.slice(0,u),c=t.slice(u-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,a,n,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,v,n,c,i))}if(2===r.length){var h=Math.ceil(e.length/2),b=e.slice(0,h),m=e.slice(h-1),g=n.slice(0,h),_=n.slice(h-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,r,g,t,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,r,_,t,i))}var h=Math.ceil(e.length/2),b=e.slice(0,h),m=e.slice(h-1),g=n.slice(0,h),_=n.slice(h-1),u=Math.ceil(r.length/2),a=r.slice(0,u),v=r.slice(u-1),l=t.slice(0,u),c=t.slice(u-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,a,g,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,v,g,c,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,a,_,l,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,v,_,c,i))}var f=verb.eval.geom.intersect_segments(e[0],e[1],r[0],r[1],i);return null!=f?(f[0][0]=f[0][0]*(n[1]-n[0])+n[0],f[1][0]=f[1][0]*(t[1]-t[0])+t[0],[[f[0][0],f[1][0]]]):[]},verb.eval.geom.intersect_segments=function(e,r,n,t,i){var s=numeric.sub(r,e),o=Math.sqrt(numeric.dot(s,s)),u=numeric.mul(1/o,s),a=numeric.sub(t,n),v=Math.sqrt(numeric.dot(a,a)),l=numeric.mul(1/v,a),c=verb.eval.geom.intersect_rays(e,u,n,l);if(null!=c){var h=Math.min(Math.max(0,c[0]/o),1),b=Math.min(Math.max(0,c[1]/v),1),m=numeric.add(numeric.mul(h,s),e),g=numeric.add(numeric.mul(b,a),n),_=numeric.norm2Squared(numeric.sub(m,g));if(i*i>_)return[[h].concat(m),[b].concat(g)]}return null},verb.eval.geom.closest_point_on_ray=function(e,r,n){var t=numeric.sub(e,r),i=numeric.dot(t,n),s=numeric.add(r,numeric.mul(i,n));return s},verb.eval.geom.dist_to_ray=function(e,r,n){var t=verb.eval.geom.closest_point_on_ray(e,r,n),i=numeric.sub(t,e);return numeric.norm2(i)},verb.eval.geom.intersect_rays=function(e,r,n,t){var i=numeric.dot(r,t),s=numeric.dot(r,n),o=numeric.dot(r,e),u=numeric.dot(t,n),a=numeric.dot(t,e),v=numeric.dot(r,r),l=numeric.dot(t,t),c=v*l-i*i;if(Math.abs(c)E)break; +var P=numeric.normalized(numeric.cross(g,x)),C=numeric.dot(P,m),R=verb.eval.geom.intersect_3_planes(g,d,x,w,P,C);if(null===R)throw Error("panic!");var I=numeric.sub(R,m),O=numeric.sub(R,y),B=numeric.cross(_,g),L=numeric.cross(f,g),j=numeric.cross(k,x),T=numeric.cross(N,x),U=numeric.dot(L,I)/numeric.dot(L,_),D=numeric.dot(B,I)/numeric.dot(B,f),V=numeric.dot(T,O)/numeric.dot(T,k),q=numeric.dot(j,O)/numeric.dot(j,N);e=numeric.add([U,D],e),r=numeric.add([V,q],r),M++}while(z>M);return{uv1:e,uv2:r,pt:m,d:E}},verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine=function(e,r,n,t,i,s,o,u,a,v,l){var c={degree_u:e,degree_v:n,knots_u:r,knots_v:t,homo_control_points:i},h=verb.eval.nurbs.tessellate_rational_surface_adaptive(c.degree_u,c.knots_u,c.degree_v,c.knots_v,c.homo_control_points),b={degree_u:s,degree_v:u,knots_u:o,knots_v:a,homo_control_points:v},m=verb.eval.nurbs.tessellate_rational_surface_adaptive(b.degree_u,b.knots_u,b.degree_v,b.knots_v,b.homo_control_points),g=verb.eval.mesh.intersect_meshes_by_aabb(h.points,h.faces,h.uvs,m.points,m.faces,m.uvs),_=g.map(function(c){return c.map(function(c){return verb.eval.nurbs.refine_rational_surface_intersect_point(c.uvtri1,c.uvtri2,e,r,n,t,i,s,o,u,a,v,l)})});return _.map(function(e){return verb.eval.nurbs.rational_interp_curve(e.map(function(e){return e.pt}),3)})},verb.eval.mesh.intersect_meshes_by_aabb=function(e,r,n,t,i,s){var o=verb.range(r.length),u=verb.range(i.length),a=verb.eval.mesh.make_mesh_aabb_tree(e,r,o),v=verb.eval.mesh.make_mesh_aabb_tree(t,i,u),l=verb.eval.geom.intersect_aabb_trees(e,r,t,i,a,v),c=l.map(function(o){var u=verb.eval.geom.intersect_tris(e,r[o[0]],n,t,i[o[1]],s);return u?(u[0].tri1id=o[0],u[1].tri1id=o[0],u[0].tri2id=o[1],u[1].tri2id=o[1],u):u}).filter(function(e){return e}).filter(function(e){var r=numeric.sub(e[0].pt,e[1].pt);return numeric.dot(r,r)>verb.EPSILON});return c=verb.unique(c,function(e,r){var n=numeric.sub(e[0].uvtri1,r[0].uvtri1),t=numeric.dot(n,n),i=numeric.sub(e[1].uvtri1,r[1].uvtri1),s=numeric.dot(i,i),o=numeric.sub(e[0].uvtri1,r[1].uvtri1),u=numeric.dot(o,o),a=numeric.sub(e[1].uvtri1,r[0].uvtri1),v=numeric.dot(a,a);return verb.EPSILON>t&&verb.EPSILON>s||verb.EPSILON>u&&verb.EPSILON>v}),0===c.length?[]:verb.eval.mesh.make_intersect_polylines(c)},verb.eval.mesh.make_intersect_polylines=function(e){e.forEach(function(e){e[1].opp=e[0],e[0].opp=e[1]});var r=verb.eval.mesh.kdtree_from_segs(e),n=e.flatten();n.forEach(function(n){if(!n.adj){var t=verb.eval.mesh.lookup_adj_segment(n,r,e.length);t&&!t.adj&&(n.adj=t,t.adj=n)}});var t=n.filter(function(e){return!e.adj});0===t.length&&(t=n);var i=[];return t.forEach(function(e){if(!e.v){for(var r=[],n=e;n;){if(n.v)throw Error("Segment end encountered twice!");if(n.v=!0,n.opp.v=!0,r.push(n),n=n.opp.adj,n===e)break}r.length>0&&(r.push(r[r.length-1].opp),i.push(r))}}),i},verb.eval.mesh.pt_dist=function(e,r){return Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2)+Math.pow(e.z-r.z,2)},verb.eval.mesh.kdtree_from_segs=function(e){var r=[];return e.forEach(function(e){r.push({x:e[0].pt[0],y:e[0].pt[1],z:e[0].pt[2],ele:e[0]}),r.push({x:e[1].pt[0],y:e[1].pt[1],z:e[1].pt[2],ele:e[1]})}),new KdTree(r,verb.eval.mesh.pt_dist,["x","y","z"])},verb.eval.mesh.lookup_adj_segment=function(e,r,n){var t=n?Math.min(n,3):3,i=r.nearest({x:e.pt[0],y:e.pt[1],z:e.pt[2]},t).filter(function(r){return e!=r[0].ele&&r[1]h;h++){var b=s[h],m=a[h],g=verb.eval.geom.intersect_rays(b,m,e,r);if(null!==g){var _=g[0],f=g[1];-verb.EPSILON>_||_>v[h]+verb.EPSILON||((null===l||l.u>f)&&(l={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[h],numeric.mul(_/v[h],o[h]))}),(null===c||f>c.u)&&(c={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[h],numeric.mul(_/v[h],o[h]))}))}}return null===c||null===l?null:{min:l,max:c}},verb.eval.geom.point_on_ray=function(e,r,n){return numeric.add(e,numeric.mul(n,r))},verb.eval.geom.merge_tri_clip_intervals=function(e,r,n,t,i,s,o,u){if(r.min.u>e.max.u+verb.EPSILON||e.min.u>r.max.u+verb.EPSILON)return null;e.min.tri=0,e.max.tri=0,r.min.tri=1,r.max.tri=1;var a=e.min.u>r.min.u?e.min:r.min,v=e.max.uo&&(s=1,o=u),a>o&&(s=2,o=a);var v,l,c,h;0===s?(v=r[1],l=r[2],c=t[1],h=t[2]):1===s?(v=r[0],l=r[2],c=t[0],h=t[2]):(v=r[0],l=r[1],c=t[0],h=t[1]);var b,m=-numeric.dot(e,r),g=-numeric.dot(n,t),_=v*h-l*c,f=(l*g-m*h)/_,d=(m*c-v*g)/_;return b=0===s?[0,f,d]:1===s?[f,0,d]:[f,d,0],{intersects:!0,origin:b,dir:numeric.normalized(i)}},verb.eval.geom.tri_uv_from_point=function(e,r,n,t){var i=e[r[0]],s=e[r[1]],o=e[r[2]],u=n[r[0]],a=n[r[1]],v=n[r[2]],l=numeric.sub(i,t),c=numeric.sub(s,t),h=numeric.sub(o,t),b=numeric.norm2(numeric.cross(numeric.sub(i,s),numeric.sub(i,o))),m=numeric.norm2(numeric.cross(c,h))/b,g=numeric.norm2(numeric.cross(h,l))/b,_=numeric.norm2(numeric.cross(l,c))/b;return numeric.add(numeric.mul(m,u),numeric.mul(g,a),numeric.mul(_,v))},verb.eval.nurbs.tessellate_rational_surface_naive=function(e,r,n,t,i,s,o){1>s&&(s=1),1>o&&(o=1);for(var u=r[r.length-1]-r[0],a=t[t.length-1]-t[0],v=u/s,l=a/o,c=[],h=[],b=[],m=0;s+1>m;m++)for(var g=0;o+1>g;g++){var _=m*v,f=g*l;h.push([_,f]);var d=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,_,f),p=d[0][0];c.push(p);var y=numeric.normalized(numeric.cross(d[0][1],d[1][0]));b.push(y)}for(var x=[],m=0;s>m;m++)for(var g=0;o>g;g++){var k=m*(o+1)+g,N=(m+1)*(o+1)+g,w=N+1,E=k+1,z=[k,N,w],M=[k,w,E];x.push(z),x.push(M)}return{points:c,faces:x,uvs:h,normals:b}},verb.eval.nurbs.rational_curve_regular_sample=function(e,r,n,t,i){return verb.eval.nurbs.rational_curve_regular_sample_range(e,r,n,0,1,t,i)},verb.eval.nurbs.rational_curve_regular_sample_range=function(e,r,n,t,i,s,o){1>s&&(s=2);for(var u=[],a=(i-t)/(s-1),v=0,l=0;s>l;l++)v=t+a*l,o?u.push([v].concat(verb.eval.nurbs.rational_curve_point(e,r,n,v))):u.push(verb.eval.nurbs.rational_curve_point(e,r,n,v));return u},verb.eval.nurbs.rational_curve_adaptive_sample=function(e,r,n,t,i){return 1===e?i?n.map(function(e,n){return[r[n+1]].concat(verb.eval.nurbs.dehomogenize(e))}):n.map(verb.eval.nurbs.dehomogenize):verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,r[0],r[r.length-1],t,i)},verb.eval.nurbs.rational_curve_adaptive_sample_range=function(e,r,n,t,i,s,o){var u=verb.eval.nurbs.rational_curve_point(e,r,n,t),a=verb.eval.nurbs.rational_curve_point(e,r,n,i),v=.5+.2*Math.random(),l=t+(i-t)*v,c=verb.eval.nurbs.rational_curve_point(e,r,n,l),h=numeric.sub(u,a),b=numeric.sub(u,c);if(s>numeric.dot(h,h)&&numeric.dot(b,b)>s||!verb.eval.nurbs.three_points_are_flat(u,c,a,s)){var m=t+.5*(i-t),g=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,t,m,s,o),_=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,m,i,s,o);return g.slice(0,-1).concat(_)}return o?[[t].concat(u),[i].concat(a)]:[u,a]},verb.eval.nurbs.three_points_are_flat=function(e,r,n,t){var i=numeric.sub(r,e),s=numeric.sub(n,e),o=crossprod(i,s),u=numeric.dot(o,o);return t>u},verb.eval.nurbs.divide_rational_surface_adaptive=function(e,r,n,t,i,s){var o,u,a,v,l={degree_u:e,knots_u:r,degree_v:n,knots_v:t,homo_control_points:i};s=s||{},s.minDivsU=s.minDivsU||1,s.minDivsV=s.minDivsV||1,s.refine=void 0!=s.refine?s.refine:!0;var c=s.minDivsU=Math.max(s.minDivsU,3*(i.length-1)),h=s.minDivsV=Math.max(s.minDivsV,3*(i.length-1)),b=verb.last(r),m=r[0],g=verb.last(t),_=t[0],f=(b-m)/c,d=(g-_)/h,p=[],y=[];for(o=0,a=h+1;a>o;o++){var x=[];for(u=0,v=c+1;v>u;u++){var k=m+f*u,N=_+d*o,w=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,k,N),E=numeric.normalized(numeric.cross(w[0][1],w[1][0]));x.push(new verb.geom.SurfacePoint(w[0][0],E,[k,N],null,verb.isZero(E)))}y.push(x)}for(o=0;h>o;o++)for(u=0;c>u;u++){var z=[y[h-o-1][u],y[h-o-1][u+1],y[h-o][u+1],y[h-o][u]];p.push(new verb.eval.nurbs.AdaptiveRefinementNode(l,z))}if(!s.refine)return p;for(o=0;h>o;o++)for(u=0;c>u;u++){var M=o*c+u,A=verb.north(M,o,u,c,h,p),S=verb.east(M,o,u,c,h,p),P=verb.south(M,o,u,c,h,p),C=verb.west(M,o,u,c,h,p);p[M].neighbors=[P,S,A,C],p[M].divide(s)}return p},verb.north=function(e,r,n,t,i,s){return 0===r?null:s[e-t]},verb.south=function(e,r,n,t,i,s){return r===i-1?null:s[e+t]},verb.east=function(e,r,n,t,i,s){return n===t-1?null:s[e+1]},verb.west=function(e,r,n,t,i,s){return 0===n?null:s[e-1]},verb.eval.nurbs.triangulate_adaptive_refinement_node_tree=function(e){var r=verb.geom.TriMesh.empty();return e.forEach(function(e){e.triangulate(r)}),r},verb.eval.nurbs.tessellate_rational_surface_adaptive=function(e,r,n,t,i,s){var o=verb.eval.nurbs.divide_rational_surface_adaptive(e,r,n,t,i,s);return verb.eval.nurbs.triangulate_adaptive_refinement_node_tree(o)},verb.eval.nurbs.dist_to_seg=function(e,r,n){var t=numeric.sub(n,e),i=numeric.norm2(t),s=numeric.sub(r,e);if(verb.TOLERANCE>i)return numeric.norm2(s);var o=numeric.mul(1/i,t),u=numeric.dot(s,o),a=numeric.add(e,numeric.mul(u,o));return numeric.norm2(numeric.sub(a,r))},verb.geom.SurfacePoint=function(e,r,n,t,i){this.uv=n,this.point=e,this.normal=r,this.id=t,this.degen=i},verb.geom.SurfacePoint.fromUv=function(e,r){return new verb.geom.SurfacePoint(null,null,[e,r],null,null)},verb.geom.TriMesh=function(e,r,n,t){this.faces=e,this.points=r,this.uvs=n,this.normals=t},verb.geom.TriMesh.empty=function(){return new verb.geom.TriMesh([],[],[],[])},verb.eval.nurbs.AdaptiveRefinementNode=function(e,r,n,t){if(this.srf=e,this.parentNode=n,this.neighbors=t||[null,null,null,null],!r){var i=e?e.knots_u[0]:null,s=e?verb.last(e.knots_u):null,o=e?e.knots_v[0]:null,u=e?verb.last(e.knots_v):null;r=[verb.geom.SurfacePoint.fromUv(i,o),verb.geom.SurfacePoint.fromUv(s,o),verb.geom.SurfacePoint.fromUv(s,u),verb.geom.SurfacePoint.fromUv(i,u)]}this.corners=r},verb.eval.nurbs.AdaptiveRefinementNode.prototype.isLeaf=function(){return void 0===this.children},verb.eval.nurbs.AdaptiveRefinementNode.prototype.center=function(){return this.centerPoint||this.evalSrf(this.u05,this.v05)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalCorners=function(){this.u05=this.u05||(this.corners[0].uv[0]+this.corners[2].uv[0])/2,this.v05=this.v05||(this.corners[0].uv[1]+this.corners[2].uv[1])/2;for(var e=0;4>e;e++)if(!this.corners[e].point){var r=this.corners[e];this.evalSrf(r.uv[0],r.uv[1],r)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalSrf=function(e,r,n){var t=verb.eval.nurbs.rational_surface_derivs(this.srf.degree_u,this.srf.knots_u,this.srf.degree_v,this.srf.knots_v,this.srf.homo_control_points,1,e,r),i=t[0][0],s=numeric.cross(t[0][1],t[1][0]),o=verb.isZero(s);return o||(s=numeric.normalized(s)),n?(n.degen=o,n.point=i,n.normal=s,n):new verb.geom.SurfacePoint(i,s,[e,r],null,o)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getEdgeCorners=function(e){if(this.isLeaf())return[this.corners[e]];if(this.horizontal)switch(e){case 0:return this.children[0].getEdgeCorners(0);case 1:return this.children[0].getEdgeCorners(1).concat(this.children[1].getEdgeCorners(1));case 2:return this.children[1].getEdgeCorners(2);case 3:return this.children[1].getEdgeCorners(3).concat(this.children[0].getEdgeCorners(3))}switch(e){case 0:return this.children[0].getEdgeCorners(0).concat(this.children[1].getEdgeCorners(0));case 1:return this.children[1].getEdgeCorners(1);case 2:return this.children[1].getEdgeCorners(2).concat(this.children[0].getEdgeCorners(2));case 3:return this.children[0].getEdgeCorners(3)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getAllCorners=function(e){var r=[this.corners[e]];if(!this.neighbors[e])return r;var n=this.neighbors[e].getEdgeCorners((e+2)%4),t=e%2,i=verb.EPSILON,s=this,o=[function(e){return e.uv[0]>s.corners[0].uv[0]+i&&e.uv[0]s.corners[0].uv[1]+i&&e.uv[1]r;r++)if(Math.abs(e[r])>verb.TOLERANCE)return!1;return!0},verb.eval.nurbs.AdaptiveRefinementNode.prototype.hasBadNormals=function(){return this.corners[0].degen||this.corners[1].degen||this.corners[2].degen||this.corners[3].degen},verb.eval.nurbs.AdaptiveRefinementNode.prototype.fixNormals=function(){for(var e=0,r=this.corners.length;r>e;e++)if(this.corners[e],this.corners[e].degen){var n=this.corners[(e+1)%r],t=this.corners[(e+3)%r];this.corners[e].normal=n.degen?t.normal:n.normal}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide=function(e,r){if(e.minDepth>r)return!0;if(r>=e.maxDepth)return!1;if(this.hasBadNormals())return this.fixNormals(),!1;if(this.splitVert=numeric.norm2Squared(numeric.sub(this.corners[0].normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[2].normal,this.corners[3].normal))>e.normTol,this.splitHoriz=numeric.norm2Squared(numeric.sub(this.corners[1].normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[3].normal,this.corners[0].normal))>e.normTol,this.splitVert||this.splitHoriz)return!0;var n=this.center();return numeric.norm2Squared(numeric.sub(n.normal,this.corners[0].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[3].normal))>e.normTol},verb.eval.nurbs.AdaptiveRefinementNode.prototype.divide=function(e){e=e||{},e.edgeTol=e.edgeTol||.1,e.normTol=e.normTol||.05,e.minDepth=void 0!=e.minDepth?e.minDepth:0,e.maxDepth=void 0!=e.maxDepth?e.maxDepth:10,this._divide(e,0,!0)},verb.eval.nurbs.AdaptiveRefinementNode.prototype._divide=function(e,r,n){if(this.evalCorners(),this.shouldDivide(e,r)){if(r++,this.splitVert&&!this.splitHoriz?n=!1:!this.splitVert&&this.splitHoriz&&(n=!0),this.horizontal=n,this.horizontal){var t=[this.corners[0],this.corners[1],this.midpoint(1),this.midpoint(3)],i=[this.midpoint(3),this.midpoint(1),this.corners[2],this.corners[3]];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,t,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,i,this)],this.children[0].neighbors=[this.neighbors[0],this.neighbors[1],this.children[1],this.neighbors[3]],this.children[1].neighbors=[this.children[0],this.neighbors[1],this.neighbors[2],this.neighbors[3]]}else{var s=[this.corners[0],this.midpoint(0),this.midpoint(2),this.corners[3]],o=[this.midpoint(0),this.corners[1],this.corners[2],this.midpoint(2)];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,s,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,o,this)],this.children[0].neighbors=[this.neighbors[0],this.children[1],this.neighbors[2],this.neighbors[3]],this.children[1].neighbors=[this.neighbors[0],this.neighbors[1],this.neighbors[2],this.children[0]]}this.children.forEach(function(t){t._divide(e,r,!n)})}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulate=function(e){return e=e||verb.geom.TriMesh.empty(),this.isLeaf()?this.triangulateLeaf(e):(this.children.forEach(function(r){r&&r.triangulate(e)}),e)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulateLeaf=function(e){var r,n,t,i,s=e.points.length,o=[],u=[],a=0;for(a=0;4>a;a++){var v=this.getAllCorners(a);for(2===v.length&&(i=a+1),t=0;v.length>t;t++)o.push(v[t])}for(a=0,n=o.length;n>a;a++)r=o[a],void 0==r.id?(e.uvs.push(r.uv),e.points.push(r.point),e.normals.push(r.normal),r.id=s,u.push(s),s++):u.push(r.id);if(4===o.length)return e.faces.push([u[0],u[3],u[1]]),e.faces.push([u[3],u[2],u[1]]),e;if(5===o.length){var l=u.length;return e.faces.push([u[i],u[(i+1)%l],u[(i+2)%l]]),e.faces.push([u[(i+4)%l],u[(i+3)%l],u[i]]),e.faces.push([u[i],u[(i+2)%l],u[(i+3)%l]]),e}var c=this.center();e.uvs.push(c.uv),e.points.push(c.point),e.normals.push(c.normal);var h=e.points.length-1;for(a=0,t=o.length-1;o.length>a;t=a++)e.faces.push([h,u[t],u[a]]);return e},verb.eval.nurbs.rational_interp_curve=function(e,r){if(r=r||3,r+1>e.length)throw Error("You need to supply at least degree + 1 points!");for(var n=[0],t=1;e.length>t;t++){var i=numeric.norm2(numeric.sub(e[t],e[t-1])),s=n[n.length-1];n.push(s+i)}for(var o=n[n.length-1],t=0;n.length>t;t++)n[t]=n[t]/o;for(var u=numeric.rep([r+1],0),a=e.length-1,t=1,v=n.length-r;v>t;t++){for(var l=0,c=0;r>c;c++)l+=n[t+c];u.push(1/r*l)}for(var h=u.concat(numeric.rep([r+1],1)),b=[],t=0;n.length>t;t++){var m=n[t],g=verb.eval.nurbs.knot_span_given_n(a,r,m,h),_=verb.eval.nurbs.basis_functions_given_knot_span_index(g,m,r,h),f=g-r,d=verb.eval.nurbs.zeros_1d(f),p=verb.eval.nurbs.zeros_1d(e.length-(r+1)-f);b.push(d.concat(_).concat(p))}for(var y=e[0].length,x=[],t=0;y>t;t++){var k=e.map(function(e){return e[t]}),N=numeric.solve(b,k);x.push(N)}var w=numeric.transpose(x),E=numeric.rep([w.length],1);return{control_points:w,knots:h,degree:r,weights:E}},verb.eval.nurbs.get_sweep1_surface=function(e,r,n,t,i,s,o,u){for(var a=verb.eval.nurbs.homogenize_1d(o,u),v=verb.eval.nurbs.rational_curve_point(s,i,a,0),l=1/o.length,c=[],h=[],b=0;o.length>b;b++){for(var m=verb.eval.nurbs.rational_curve_point(s,i,a,b*l),g=numeric.sub(m,v),_=[],f=[],d=0;n.length>d;d++)_.push(numeric.add(g,n[d])),f.push(t[d]*u[b]);c.push(_),h.push(f)}return{knots_u:i,knots_v:e,control_points:c,degree_u:s,degree_v:r,weights:h}},verb.eval.nurbs.get_ellipse_arc=function(e,r,n,t,i,s,o){s>o&&(o=2*Math.PI+s);var u=o-s,a=0;a=Math.PI/2>=u?1:Math.PI>=u?2:3*Math.PI/2>=u?3:4;var v=u/a,l=Math.cos(v/2),c=numeric.add(e,numeric.mul(t,Math.cos(s),r),numeric.mul(i,Math.sin(s),n)),h=numeric.sub(numeric.mul(Math.cos(s),n),numeric.mul(Math.sin(s),r)),b=verb.eval.nurbs.zeros_1d(2*a),m=verb.eval.nurbs.zeros_1d(2*a+3),g=0,_=s,f=verb.eval.nurbs.zeros_1d(2*a);b[0]=c,f[0]=1;for(var d=1;a>=d;d++){_+=v;var p=numeric.add(e,numeric.mul(t,Math.cos(_),r),numeric.mul(i,Math.sin(_),n));f[g+2]=1,b[g+2]=p;var y=numeric.sub(numeric.mul(Math.cos(_),n),numeric.mul(Math.sin(_),r)),x=verb.eval.geom.intersect_rays(c,numeric.mul(1/numeric.norm2(h),h),p,numeric.mul(1/numeric.norm2(y),y)),k=numeric.add(c,numeric.mul(h,x[0]));f[g+1]=l,b[g+1]=k,g+=2,a>d&&(c=p,h=y)}for(var N=2*a+1,d=0;3>d;d++)m[d]=0,m[d+N]=1;switch(a){case 1:break;case 2:m[3]=m[4]=.5;break;case 3:m[3]=m[4]=1/3,m[5]=m[6]=2/3;break;case 4:m[3]=m[4]=.25,m[5]=m[6]=.5,m[7]=m[8]=.75}return{knots:m,control_points:b,degree:2,weights:f}},verb.eval.nurbs.get_sphere_surface=function(e,r,n,t){var i=verb.eval.nurbs.get_arc(e,numeric.mul(r,-1),n,t,0,Math.PI);return verb.eval.nurbs.get_revolved_surface(e,r,2*Math.PI,i.knots,i.degree,i.control_points,i.weights)},verb.eval.nurbs.get_polyline_curve=function(e){for(var r=e.length-1,n=1/r,t=[0,0],i=1;r>i;i++)t.push(i*n);t.push(1),t.push(1);for(var s=[],i=0;e.length>i;i++)s.push(1);return{knots:t,control_points:e.slice(0),degree:1,weights:s}},verb.eval.nurbs.get_4pt_surface=function(e,r,n,t){var i=numeric.mul(.5,numeric.add(e,t)),s=numeric.mul(.5,numeric.add(r,n)),o=numeric.mul(.5,numeric.add(n,t)),u=numeric.mul(.5,numeric.add(e,r)),a=numeric.mul(.5,numeric.add(i,s));return{knots_u:[0,0,0,1,1,1],knots_v:[0,0,0,1,1,1],control_points:[[e,i,t],[u,a,o],[r,s,n]],degree_u:2,degree_v:2,weights:[[1,1,1],[1,1,1],[1,1,1]]}},verb.eval.nurbs.get_cylinder_surface=function(e,r,n,t,i){var s=crossprod(e,r),o=(2*Math.PI,verb.eval.nurbs.get_arc(n,r,s,i,0,2*Math.PI));return verb.eval.nurbs.get_extruded_surface(e,t,o.knots,o.degree,o.control_points,o.weights)},verb.eval.nurbs.get_cone_surface=function(e,r,n,t,i){var s=2*Math.PI,o=1,u=[numeric.add(n,numeric.mul(t,e)),numeric.add(n,numeric.mul(i,r))],a=[0,0,1,1],v=[1,1];return verb.eval.nurbs.get_revolved_surface(n,e,s,a,o,u,v)},verb.eval.nurbs.get_extruded_surface=function(e,r,n,t,i,s){for(var o=verb.eval.nurbs.zeros_2d(3,i.length),u=verb.eval.nurbs.zeros_2d(3,i.length),a=numeric.mul(e,r),v=numeric.mul(e,.5*r),l=0;i.length>l;l++)o[2][l]=i[l],o[1][l]=numeric.add(v,i[l]),o[0][l]=numeric.add(a,i[l]),u[0][l]=s[l],u[1][l]=s[l],u[2][l]=s[l];return{knots_u:[0,0,0,1,1,1],knots_v:n,control_points:o,degree_u:2,degree_v:t,weights:u}},verb.eval.nurbs.get_revolved_surface=function(e,r,n,t,i,s,o){var u,a,v,l;Math.PI/2>=n?(u=1,a=verb.eval.nurbs.zeros_1d(6+2*(u-1))):Math.PI>=n?(u=2,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=.5):3*Math.PI/2>=n?(u=3,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=1/3,a[5]=a[6]=2/3):(u=4,a=verb.eval.nurbs.zeros_1d(6+2*(u-1)),a[3]=a[4]=.25,a[5]=a[6]=.5,a[7]=a[8]=.75);for(var c=n/u,h=3+2*(u-1),b=0;3>b;h++,b++)a[b]=0,a[h]=1;for(var m=Math.cos(c/2),g=0,_=verb.eval.nurbs.zeros_1d(u+1),f=verb.eval.nurbs.zeros_1d(u+1),v=verb.eval.nurbs.zeros_2d(2*u+1,s.length),l=verb.eval.nurbs.zeros_2d(2*u+1,s.length),b=1;u>=b;b++)g+=c,f[b]=Math.cos(g),_[b]=Math.sin(g);for(h=0;s.length>h;h++){var d=verb.eval.geom.closest_point_on_ray(s[h],e,r),p=numeric.sub(s[h],d),y=numeric.norm2(p),x=crossprod(r,p);y>verb.EPSILON&&(p=numeric.mul(1/y,p),x=numeric.mul(1/y,x)),v[0][h]=s[h];var k=s[h];l[0][h]=o[h];for(var N=x,w=0,g=0,b=1;u>=b;b++){var E=0==y?d:numeric.add(d,numeric.mul(y,f[b],p),numeric.mul(y,_[b],x));v[w+2][h]=E,l[w+2][h]=o[h];var z=numeric.sub(numeric.mul(f[b],x),numeric.mul(_[b],p));if(0==y)v[w+1][h]=d;else{var M=verb.eval.geom.intersect_rays(k,numeric.mul(1/numeric.norm2(N),N),E,numeric.mul(1/numeric.norm2(z),z)),A=numeric.add(k,numeric.mul(N,M[0]));v[w+1][h]=A}l[w+1][h]=m*o[h],w+=2,u>b&&(k=E,N=z)}}return{knots_u:a,knots_v:t,control_points:v,degree_u:2,degree_v:i,weights:l}},verb.eval.nurbs.get_arc=function(e,r,n,t,i,s){return verb.eval.nurbs.get_ellipse_arc(e,r,n,t,t,i,s)},verb.eval.nurbs.curve_bezier_decompose=function(e,r,n){for(var t=verb.eval.nurbs.knot_multiplicities(r),i=e+1,s=verb.eval.nurbs.curve_knot_refine,o=0;t.length>o;o++)if(i>t[o][1]){var u=numeric.rep([i-t[o][1]],t[o][0]),a=s(e,r,n,u);r=a.knots,n=a.control_points}r.length/i-1;for(var v=2*i,l=[],o=0;n.length>o;o+=i){var c=r.slice(o,o+v),h=n.slice(o,o+i);l.push({degree:e,knots:c,control_points:h})}return l},verb.eval.nurbs.knot_multiplicities=function(e){for(var r=[[e[0],0]],n=r[0],t=0;e.length>t;t++)Math.abs(e[t]-n[0])>verb.EPSILON&&(n=[e[t],0],r.push(n)),n[1]++;return r},verb.eval.nurbs.curve_split=function(e,r,n,t){for(var i=[],s=0;e+1>s;s++)i.push(t);var o=verb.eval.nurbs.curve_knot_refine(e,r,n,i),u=verb.eval.nurbs.knot_span(e,t,r),a=o.knots.slice(0,u+e+2),v=o.knots.slice(u+1),l=o.control_points.slice(0,u+1),c=o.control_points.slice(u+1);return[{degree:e,knots:a,control_points:l},{degree:e,knots:v,control_points:c}]},verb.eval.nurbs.curve_knot_refine=function(e,r,n,t){var i=n.length-1,s=i+e+1,o=t.length-1,u=verb.eval.nurbs.knot_span(e,t[0],r),a=verb.eval.nurbs.knot_span(e,t[o],r),v=Array(n.length+o+1),l=Array(r.length+o+1),c=0,h=0;for(c=0;u-e>=c;c++)v[c]=n[c];for(c=a-1;i>=c;c++)v[c+o+1]=n[c];for(c=0;u>=c;c++)l[c]=r[c];for(c=a+e;s>=c;c++)l[c+o+1]=r[c];c=a+e-1;var b=a+e+o;for(h=o;h>=0;h--){for(;t[h]<=r[c]&&c>u;)v[b-e-1]=n[c-e-1],l[b]=r[c],b-=1,c-=1;v[b-e-1]=v[b-e];for(var m=1;e>=m;m++){var g=b-e+m,_=l[b+m]-t[h];Math.abs(_)=h;h++)l[h]=r[h];for(h=1;i>=h;h++)l[u+h]=t;for(h=u+1;r.length>h;h++)l[h+i]=r[h];for(h=0;u-e>=h;h++)c[h]=n[h];for(h=u-s;o>h;h++)c[h+i]=n[h];for(h=0;e-s>=h;h++)v[h]=n[u-e+h];for(var b=0,m=0,g=1;i>=g;g++){for(b=u-e+g,h=0;e-g-s>=h;h++)m=(t-r[b+h])/(r[h+u+1]-r[b+h]),v[h]=numeric.add(numeric.mul(m,v[h+1]),numeric.mul(1-m,v[h]));c[b]=v[0],c[u+i-g-s]=v[e-g-s]}for(h=b+1;u-s>h;h++)c[h]=v[h-b];return{knots:l,control_points:c}},verb.eval.nurbs.rational_surface_curvature=function(e,r,n,t,i,s,o){var u=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,2,s,o),a=u[0][1],v=u[1][0],l=u[0][2],c=u[2][0],h=u[1][1],b=numeric.cross(a,v),m=numeric.dot(l,b),g=numeric.dot(h,b),_=numeric.dot(c,b),f=[[m,g],[g,_]],d=numeric.eig(f),p=d.lambda.x[0],y=d.lambda.x[1],x=.5*(p+y),k=p*y,N=numeric.add(numeric.mul(d.E.x[0][0],a),numeric.mul(d.E.x[0][1],v)),w=numeric.add(numeric.mul(d.E.x[1][0],a),numeric.mul(d.E.x[1][1],v));return{point:u[0][0],normal:b,mean:x,gaussian:k,shapeOperator:f,k1:p,k2:y,p1:N,p2:w,p1p:d.E.x[0],p2p:d.E.x[1]}},verb.eval.nurbs.rational_surface_derivs=function(e,r,n,t,i,s,o,u){var a=verb.eval.nurbs.surface_derivs(e,r,n,t,i,s,o,u),v=verb.eval.nurbs.separate_homo_derivs_2d(a),l=v[0],c=v[1],h=0,b=0,m=0,g=0,_=[],f=l[0][0].length;for(h=0;s>=h;h++)for(_.push([]),g=0;s-h>=g;g++){var u=l[h][g];for(m=1;g>=m;m++)u=numeric.sub(u,numeric.mul(numeric.mul(binomial.get(g,m),c[0][m]),_[h][g-m]));for(b=1;h>=b;b++){u=numeric.sub(u,numeric.mul(numeric.mul(binomial.get(h,b),c[b][0]),_[h-b][g]));var d=verb.eval.nurbs.zeros_1d(f);for(m=1;g>=m;m++)d=numeric.add(d,numeric.mul(numeric.mul(binomial.get(g,m),c[b][m]),_[h-b][g-m]));u=numeric.sub(u,numeric.mul(binomial.get(h,b),d))}_[h].push(numeric.mul(1/c[0][0],u))}return _},verb.eval.nurbs.rational_surface_point=function(e,r,n,t,i,s,o){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.surface_point(e,r,n,t,i,s,o))},verb.eval.nurbs.rational_curve_derivs=function(e,r,n,t,i){var s=verb.eval.nurbs.separate_homo_derivs_1d(verb.eval.nurbs.curve_derivs(e,r,n,t,i)),o=s[0],u=s[1],a=0,v=0,l=[];for(a=0;i>=a;a++){var c=o[a];for(v=1;a>=v;v++)c=numeric.sub(c,numeric.mul(numeric.mul(binomial.get(a,v),u[v]),l[a-v]));l.push(numeric.mul(1/u[0],c))}return l},verb.eval.nurbs.separate_homo_derivs_1d=function(e){for(var r=e[0].length,n=r-1,t=[],i=[],s=0,o=e.length;o>s;s++)t.push(e[s].slice(0,n)),i.push(e[s][n]);return[t,i]},verb.eval.nurbs.separate_homo_derivs_2d=function(e){for(var r=[],n=[],t=0,i=e.length;i>t;t++){var s=verb.eval.nurbs.separate_homo_derivs_1d(e[t]);r.push(s[0]),n.push(s[1])}return[r,n]},verb.eval.nurbs.rational_curve_point=function(e,r,n,t){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.curve_point(e,r,n,t))},verb.eval.nurbs.dehomogenize=function(e){for(var r=e.length,n=[],t=e[r-1],i=0;e.length-1>i;i++)n.push(e[i]/t);return n},verb.eval.nurbs.weight_1d=function(e){var r=e[0].length-1;return e.map(function(e){return e[r]})},verb.eval.nurbs.dehomogenize_1d=function(e){return e.map(function(e){return verb.eval.nurbs.dehomogenize(e)})},verb.eval.nurbs.homogenize_1d=function(e,r){for(var n=e.length,t=e[0].length,i=0,s=[],o=0,u=[],a=0;n>a;a++){var v=[];for(u=e[a],o=r[a],i=0;t>i;i++)v.push(u[i]*o);v.push(o),s.push(v)}return s},verb.eval.nurbs.homogenize_2d=function(e,r){for(var n=e.length,t=(e[0].length,e[0][0].length,[]),i=0;n>i;i++)t.push(verb.eval.nurbs.homogenize_1d(e[i],r[i]));return t},verb.eval.nurbs.surface_derivs=function(e,r,n,t,i,s,o,u){var a=r.length-e-2,v=t.length-n-2;return verb.eval.nurbs.surface_derivs_given_n_m(a,e,r,v,n,t,i,s,o,u)},verb.eval.nurbs.surface_derivs_given_n_m=function(e,r,n,t,i,s,o,u,a,v){if(verb.eval.nurbs.are_valid_relations(r,o.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,o[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var l=o[0][0].length,c=Math.min(u,r),h=Math.min(u,i),b=verb.eval.nurbs.zeros_3d(c+1,h+1,l),m=verb.eval.nurbs.knot_span_given_n(e,r,a,n),g=verb.eval.nurbs.knot_span_given_n(t,i,v,s),_=verb.eval.nurbs.deriv_basis_functions_given_n_i(m,a,r,e,n),f=verb.eval.nurbs.deriv_basis_functions_given_n_i(g,v,i,t,s),d=verb.eval.nurbs.zeros_2d(i+1,l),p=0,y=0,x=0,k=0,N=0;for(p=0;c>=p;p++){for(y=0;i>=y;y++)for(d[y]=verb.eval.nurbs.zeros_1d(l),x=0;r>=x;x++)d[y]=numeric.add(d[y],numeric.mul(_[p][x],o[m-r+x][g-i+y]));for(N=Math.min(u-p,h),k=0;N>=k;k++)for(b[p][k]=verb.eval.nurbs.zeros_1d(l),y=0;i>=y;y++)b[p][k]=numeric.add(b[p][k],numeric.mul(f[k][y],d[y]))}return b},verb.eval.nurbs.surface_point=function(e,r,n,t,i,s,o){var u=r.length-e-2,a=t.length-n-2;return verb.eval.nurbs.surface_point_given_n_m(u,e,r,a,n,t,i,s,o)},verb.eval.nurbs.volume_point=function(e,r,n,t,i,s,o,u,a,v){var l=r.length-e-2,c=t.length-n-2,h=s.length-i-2;return verb.eval.nurbs.volume_point_given_n_m_l(l,e,r,c,n,t,h,i,s,o,u,a,v)},verb.eval.nurbs.volume_point_given_n_m_l=function(e,r,n,t,i,s,o,u,a,v,l,c,h){if(!verb.eval.nurbs.are_valid_relations(r,v.length,n.length)||!verb.eval.nurbs.are_valid_relations(i,v[0].length,s.length)||!verb.eval.nurbs.are_valid_relations(u,v[0][0].length,a.length))return console.error("Invalid relations between control points and knot vector"),null;for(var b=v[0][0][0].length,m=verb.eval.nurbs.knot_span_given_n(e,r,l,n),g=verb.eval.nurbs.knot_span_given_n(t,i,c,s),_=verb.eval.nurbs.knot_span_given_n(o,u,h,a),f=verb.eval.nurbs.basis_functions_given_knot_span_index(m,l,r,n),d=verb.eval.nurbs.basis_functions_given_knot_span_index(g,c,i,s),p=verb.eval.nurbs.basis_functions_given_knot_span_index(_,h,u,a),y=m-r,x=g,k=_,N=verb.eval.nurbs.zeros_1d(b),w=verb.eval.nurbs.zeros_1d(b),E=verb.eval.nurbs.zeros_1d(b),z=0,M=0,A=0;u>=A;A++){for(E=verb.eval.nurbs.zeros_1d(b),k=_-u+A,z=0;i>=z;z++){for(w=verb.eval.nurbs.zeros_1d(b),x=g-i+z,M=0;r>=M;M++)w=numeric.add(w,numeric.mul(f[M],v[y+M][x][k]));E=numeric.add(E,numeric.mul(d[z],w))}N=numeric.add(N,numeric.mul(p[A],E))}return N},verb.eval.nurbs.surface_point_given_n_m=function(e,r,n,t,i,s,o,u,a){if(verb.eval.nurbs.are_valid_relations(r,o.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,o[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var v=o[0][0].length,l=verb.eval.nurbs.knot_span_given_n(e,r,u,n),c=verb.eval.nurbs.knot_span_given_n(t,i,a,s),h=verb.eval.nurbs.basis_functions_given_knot_span_index(l,u,r,n),b=verb.eval.nurbs.basis_functions_given_knot_span_index(c,a,i,s),m=l-r,g=c,_=verb.eval.nurbs.zeros_1d(v),f=verb.eval.nurbs.zeros_1d(v),d=0,p=0;for(d=0;i>=d;d++){for(f=verb.eval.nurbs.zeros_1d(v),g=c-i+d,p=0;r>=p;p++)f=numeric.add(f,numeric.mul(h[p],o[m+p][g]));_=numeric.add(_,numeric.mul(b[d],f))}return _},verb.eval.nurbs.curve_derivs=function(e,r,n,t,i){var s=r.length-e-2;return verb.eval.nurbs.curve_derivs_given_n(s,e,r,n,t,i)},verb.eval.nurbs.curve_derivs_given_n=function(e,r,n,t,i,s){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null; var o=t[0].length,u=Math.min(s,r),a=verb.eval.nurbs.zeros_2d(u+1,o),v=verb.eval.nurbs.knot_span_given_n(e,r,i,n),l=verb.eval.nurbs.deriv_basis_functions_given_n_i(v,i,r,u,n),c=0,h=0;for(c=0;u>=c;c++)for(h=0;r>=h;h++)a[c]=numeric.add(a[c],numeric.mul(l[c][h],t[v-r+h]));return a},verb.eval.nurbs.are_valid_relations=function(e,r,n){return 0===r+e+1-n?!0:!1},verb.eval.nurbs.curve_point=function(e,r,n,t){var i=r.length-e-2;return verb.eval.nurbs.curve_point_given_n(i,e,r,n,t)},verb.eval.nurbs.curve_point_given_n=function(e,r,n,t,i){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;for(var s=verb.eval.nurbs.knot_span_given_n(e,r,i,n),o=verb.eval.nurbs.basis_functions_given_knot_span_index(s,i,r,n),u=verb.eval.nurbs.zeros_1d(t[0].length),a=0;r>=a;a++)u=numeric.add(u,numeric.mul(o[a],t[s-r+a]));return u},verb.eval.nurbs.zeros_1d=function(e){return numeric.rep([e],0)},verb.eval.nurbs.zeros_2d=function(e,r){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r],0)},verb.eval.nurbs.zeros_3d=function(e,r,n){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r,n],0)},verb.eval.nurbs.deriv_basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(r,e,n),i=n.length-1,s=i-r-1;return verb.eval.nurbs.deriv_basis_functions_given_n_i(t,e,r,s,n)},verb.eval.nurbs.deriv_basis_functions_given_n_i=function(e,r,n,t,i){var s=verb.eval.nurbs.zeros_2d(n+1,n+1),o=Array(n+1),u=Array(n+1),a=0,v=0,l=1,c=0;for(s[0][0]=1,l=1;n>=l;l++){for(o[l]=r-i[e+1-l],u[l]=i[e+l]-r,a=0,c=0;l>c;c++)s[l][c]=u[c+1]+o[l-c],v=s[c][l-1]/s[l][c],s[c][l]=a+u[c+1]*v,a=o[l-c]*v;s[l][l]=a}var h=verb.eval.nurbs.zeros_2d(t+1,n+1),b=verb.eval.nurbs.zeros_2d(2,n+1),m=1,g=0,_=1,f=0,d=0,p=0,y=0,x=0;for(l=0;n>=l;l++)h[0][l]=s[l][n];for(c=0;n>=c;c++)for(g=0,_=1,b[0][0]=1,m=1;t>=m;m++){for(f=0,d=c-m,p=n-m,c>=m&&(b[_][0]=b[g][0]/s[p+1][d],f=b[_][0]*s[d][p]),y=d>=-1?1:-d,x=p>=c-1?m-1:n-c,l=y;x>=l;l++)b[_][l]=(b[g][l]-b[g][l-1])/s[p+1][d+l],f+=b[_][l]*s[d+l][p];p>=c&&(b[_][m]=-b[g][m-1]/s[p+1][c],f+=b[_][m]*s[c][p]),h[m][c]=f,l=g,g=_,_=l}for(c=n,m=1;t>=m;m++){for(l=0;n>=l;l++)h[m][l]*=c;c*=n-m}return h},verb.eval.nurbs.basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(e,r,n);return verb.eval.nurbs.basis_functions_given_knot_span_index(t,e,r,n)},verb.eval.nurbs.basis_functions_given_knot_span_index=function(e,r,n,t){var i=Array(n+1),s=Array(n+1),o=Array(n+1),u=0,a=0;i[0]=1;for(var v=1;n>=v;v++){s[v]=r-t[e+1-v],o[v]=t[e+v]-r,u=0;for(var l=0;v>l;l++)a=i[l]/(o[l+1]+s[v-l]),i[l]=u+o[l+1]*a,u=s[v-l]*a;i[v]=u}return i},verb.eval.nurbs.knot_span=function(e,r,n){var t=n.length-1,i=t-e-1;return verb.eval.nurbs.knot_span_given_n(i,e,r,n)},verb.eval.nurbs.knot_span_given_n=function(e,r,n,t){if(n>=t[e+1])return e;if(t[r]>n)return r;for(var i=r,s=e+1,o=Math.floor((i+s)/2);t[o]>n||n>=t[o+1];)t[o]>n?s=o:i=o,o=Math.floor((i+s)/2);return o}; \ No newline at end of file diff --git a/build/verbEval.js b/build/verbEval.js index 38b1177b..1161e572 100644 --- a/build/verbEval.js +++ b/build/verbEval.js @@ -1155,14 +1155,12 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de }; // todo: need to be able to predict the number of divisions - var tessOptions = { minDivsU: 20, minDivsV: 20, tol: 5e-2 }; var tess1 = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj1.degree_u, srfObj1.knots_u, srfObj1.degree_v, srfObj1.knots_v, - srfObj1.homo_control_points, - tessOptions ); + srfObj1.homo_control_points); var srfObj2 = { degree_u : degree_u2, @@ -1176,8 +1174,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de srfObj2.knots_u, srfObj2.degree_v, srfObj2.knots_v, - srfObj2.homo_control_points, - tessOptions ); + srfObj2.homo_control_points); var resApprox = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, tess1.uvs, tess2.points, tess2.faces, tess2.uvs ); @@ -1191,7 +1188,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de // 3) perform cubic interpolation return exactPls.map(function(x){ - return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 2 ); + return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 3 ); }); // TODO: represent this in uv space @@ -1221,11 +1218,10 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points res[1].tri2id = ids[1]; return res; - }) - .filter(function(x){ return x; }) + }).filter(function(x){ return x; }) .filter(function(x){ var dif = numeric.sub( x[0].pt, x[1].pt ); - return numeric.dot( dif, dif ) > verb.TOLERANCE + return numeric.dot( dif, dif ) > verb.EPSILON }); // TODO: this is too expensive and this only occurs when the intersection @@ -1245,8 +1241,8 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points var s4 = numeric.sub( a[1].uvtri1, b[0].uvtri1 ); var d4 = numeric.dot( s4, s4 ); - return ( d1 < verb.TOLERANCE && d2 < verb.TOLERANCE ) || - ( d3 < verb.TOLERANCE && d4 < verb.TOLERANCE ); + return ( d1 < verb.EPSILON && d2 < verb.EPSILON ) || + ( d3 < verb.EPSILON && d4 < verb.EPSILON ); }); @@ -1366,7 +1362,7 @@ verb.eval.mesh.lookup_adj_segment = function( segEnd, tree, numSegments ) { // we expect one result to be self, one to be neighbor and no more var adj = tree.nearest({ x: segEnd.pt[0], y: segEnd.pt[1], z: segEnd.pt[2] }, numResults) .filter(function(r){ - return segEnd != r[0].ele && r[1] < verb.TOLERANCE; + return segEnd != r[0].ele && r[1] < verb.EPSILON; }) .map(function(r){ return r[0].ele; }); @@ -2321,14 +2317,6 @@ verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide = function( option this.splitHoriz = numeric.norm2Squared( numeric.sub( this.corners[1].normal, this.corners[2].normal ) ) > options.normTol || numeric.norm2Squared( numeric.sub( this.corners[3].normal, this.corners[0].normal ) ) > options.normTol; - // is curved in u direction? - // this.splitVert = verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[0].point, this.corners[1].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[2].point, this.midpoints[2].point, this.corners[3].point ) > options.edgeTol; - - // // is curved in v direction? - // this.splitHoriz = verb.eval.nurbs.dist_to_seg( this.corners[1].point, this.midpoints[1].point, this.corners[2].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[3].point, this.corners[3].point ) > options.edgeTol; - if ( this.splitVert || this.splitHoriz ) return true; var center = this.center(); diff --git a/build/verbEval.min.js b/build/verbEval.min.js index 99cbc722..dcab6be5 100644 --- a/build/verbEval.min.js +++ b/build/verbEval.min.js @@ -1,3 +1,3 @@ /*! verb 2014-11-29 */ -function crossprod(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]}if("object"!=typeof exports||void 0===exports)importScripts("labor.js"),importScripts("binomial.js"),importScripts("numeric-1.2.6.min.js");else var labor=require("labor");var verb=verb||{};verb.eval=verb.eval||{},verb.eval.nurbs=verb.eval.nurbs||{},verb.eval.mesh=verb.eval.mesh||{},verb.eval.geom=verb.eval.geom||{},verb.geom=verb.geom||{},verb.EPSILON=1e-8,verb.TOLERANCE=.001;var router=new labor.Router(verb.eval.nurbs);numeric.normalized=function(e){return numeric.div(e,numeric.norm2(e))},numeric.cross=function(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]},verb.left=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(0,r)},verb.right=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r)},verb.rightWithPivot=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r-1)},verb.unique=function(e,r){if(0===e.length)return[];for(var n=[e.pop()],t=0;e.length>t;t++){for(var i=e.pop(),s=!0,u=0;n.length>u;u++)if(r(i,n[t])){s=!1;break}s&&n.push(i)}return n},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb_refine=function(e,r,n,t,i,s,u,o,a,v,l,c){var b=verb.eval.nurbs.intersect_rational_curve_surface_by_aabb(e,r,n,t,i,s,u,o,a,v,l,c);return b.map(function(a){var v=[a.p,a.uv[0],a.uv[1]],l=verb.eval.nurbs.refine_rational_curve_surface_intersection(e,r,n,t,i,s,u,o,v);return a.p=l[0],a.uv[0]=l[1],a.uv[1]=l[2],a.distance=l[3],delete a.face,a})},verb.eval.nurbs.refine_rational_curve_surface_intersection=function(e,r,n,t,i,s,u,o,a){var v=function(a){var v=verb.eval.nurbs.rational_curve_point(s,u,o,a[0]),l=verb.eval.nurbs.rational_surface_point(e,r,n,t,i,a[1],a[2]),c=numeric.sub(v,l);return numeric.dot(c,c)},l=numeric.uncmin(v,a);return l.solution.concat(l.f)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb=function(e,r,n,t,i,s,u,o,a,v,l,c){var b=verb.eval.nurbs.rational_curve_adaptive_sample(s,u,o,a,!0),h=verb.eval.nurbs.tessellate_rational_surface_naive(e,r,n,t,i,l,c),m=b.map(function(e){return e[0]}),_=b.map(function(e){return e.slice(1)}),g=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb(_,m,h,verb.range(h.faces.length),v);return verb.unique(g,function(e,r){return v>numeric.norm2(numeric.sub(e.point,r.point))&&v>Math.abs(e.p-r.p)&&v>numeric.norm2(numeric.sub(e.uv,r.uv))})},verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),u=verb.eval.mesh.make_mesh_aabb(n.points,n.faces,t),o=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb;if(!s.intersects(u,i))return[];if(2!==e.length||1!==t.length){if(1===t.length){var a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return o(a,l,n,t,i).concat(o(v,c,n,t,i))}if(2===e.length){var b=verb.eval.mesh.sort_tris_on_longest_axis(u,n.points,n.faces,t),h=verb.left(b),m=verb.right(b);return o(e,r,n,h,i).concat(o(e,r,n,m,i))}var b=verb.eval.mesh.sort_tris_on_longest_axis(u,n.points,n.faces,t),h=verb.left(b),m=verb.right(b),a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return o(a,l,n,h,i).concat(o(a,l,n,m,i)).concat(o(v,c,n,h,i)).concat(o(v,c,n,m,i))}var _=verb.eval.geom.intersect_segment_with_tri(e[0],e[1],n.points,n.faces[t[0]]);if(null!=_){var g=_.p*(r[1]-r[0])+r[0],f=n.faces[t][0],d=n.faces[t][1],p=n.faces[t][2],y=n.uvs[f],k=n.uvs[d],x=n.uvs[p],E=numeric.sub(k,y),N=numeric.sub(x,y),z=numeric.add(y,numeric.mul(_.s,E),numeric.mul(_.t,N));return[{point:_.point,p:g,uv:z,face:t[0]}]}return[]},verb.eval.geom.intersect_segment_with_tri=function(e,r,n,t){var i=n[t[0]],s=n[t[1]],u=n[t[2]],o=numeric.sub(s,i),a=numeric.sub(u,i),v=numeric.cross(o,a),l=numeric.sub(r,e),c=numeric.sub(e,i),b=-numeric.dot(v,c),h=numeric.dot(v,l);if(Math.abs(h)m||m>1)return null;var _=numeric.add(e,numeric.mul(m,l)),g=numeric.dot(o,a),f=numeric.dot(o,o),d=numeric.dot(a,a),p=numeric.sub(_,i),y=numeric.dot(p,o),k=numeric.dot(p,a),x=g*g-f*d,E=(g*k-d*y)/x,N=(g*y-f*k)/x;return E>1+verb.EPSILON||N>1+verb.EPSILON||-verb.EPSILON>N||-verb.EPSILON>E||E+N>1+verb.EPSILON?null:{point:_,s:E,t:N,p:m}},verb.eval.geom.intersect_segment_with_plane=function(e,r,n,t){var i=numeric.dot(t,numeric.sub(e,r));if(EPSILON>abs(i))return null;var s=numeric.dot(t,numeric.sub(n,e));return{p:s/i}},verb.eval.geom.intersect_aabb_trees=function(e,r,n,t,i,s){var u=i.bounding_box.intersects(s.bounding_box),o=verb.eval.geom.intersect_aabb_trees;return u?0===i.children.length&&0===s.children.length?[[i.triangle,s.triangle]]:0===i.children.length&&0!=s.children.length?o(e,r,n,t,i,s.children[0]).concat(o(e,r,n,t,i,s.children[1])):0!=i.children.length&&0===s.children.length?o(e,r,n,t,i.children[0],s).concat(o(e,r,n,t,i.children[1],s)):0!=i.children.length&&0!=s.children.length?o(e,r,n,t,i.children[0],s.children[0]).concat(o(e,r,n,t,i.children[0],s.children[1])).concat(o(e,r,n,t,i.children[1],s.children[0])).concat(o(e,r,n,t,i.children[1],s.children[1])):void 0:[]},verb.eval.mesh.make_mesh_aabb_tree=function(e,r,n){var t={bounding_box:verb.eval.mesh.make_mesh_aabb(e,r,n),children:[]};if(1===n.length)return t.triangle=n[0],t;var i=verb.eval.mesh.sort_tris_on_longest_axis(t.bounding_box,e,r,n),s=i.slice(0,Math.floor(i.length/2)),u=i.slice(Math.floor(i.length/2),i.length);return t.children=[verb.eval.mesh.make_mesh_aabb_tree(e,r,s),verb.eval.mesh.make_mesh_aabb_tree(e,r,u)],t},verb.eval.mesh.make_mesh_aabb=function(e,r,n){var t=new verb.geom.BoundingBox;return n.forEach(function(n){t.add(e[r[n][0]]),t.add(e[r[n][1]]),t.add(e[r[n][2]])}),t},verb.eval.mesh.sort_tris_on_longest_axis=function(e,r,n,t){for(var i=e.get_longest_axis(),s=[],u=t.length-1;u>=0;u--){var o=t[u],a=verb.eval.mesh.get_min_coordinate_on_axis(r,n[o],i);s.push([a,o])}s.sort(function(e,r){return e[0]>r[0]});for(var v=[],u=0,l=s.length;l>u;u++)v.push(s[u][1]);return v},verb.eval.mesh.get_min_coordinate_on_axis=function(e,r,n){for(var t=[],i=0;3>i;i++)t.push(e[r[i]][n]);return Math.min.apply(Math,t)},verb.eval.geom.get_tri_centroid=function(e,r){for(var n=[0,0,0],t=0;3>t;t++)for(var i=0;3>i;i++)n[i]+=e[r[t]][i];for(var t=0;3>t;t++)n[t]/=3;return n},verb.eval.geom.get_tri_norm=function(e,r){var n=e[r[0]],t=e[r[1]],i=e[r[2]],s=numeric.sub(t,n),u=numeric.sub(i,n),o=numeric.cross(s,u);return numeric.mul(1/numeric.norm2(o),o)},verb.eval.nurbs.intersect_rational_curves_by_aabb_refine=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.intersect_rational_curves_by_aabb(e,r,n,t,i,s,u,o);return a.map(function(u){return verb.eval.nurbs.refine_rational_curve_intersection(e,r,n,t,i,s,u)})},verb.eval.nurbs.refine_rational_curve_intersection=function(e,r,n,t,i,s,u){var o=function(u){var o=verb.eval.nurbs.rational_curve_point(e,r,n,u[0]),a=verb.eval.nurbs.rational_curve_point(t,i,s,u[1]),v=numeric.sub(o,a);return numeric.dot(v,v)},a=numeric.uncmin(o,u);return a.solution.concat(a.f)},verb.eval.nurbs.intersect_rational_curves_by_aabb=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.rational_curve_adaptive_sample(e,r,n,u,!0),v=verb.eval.nurbs.rational_curve_adaptive_sample(t,i,s,u,!0),l=a.map(function(e){return e[0]}),c=v.map(function(e){return e[0]}),b=a.map(function(e){return e.slice(1)}),h=v.map(function(e){return e.slice(1)});return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,h,l,c,o)},verb.eval.nurbs.intersect_parametric_polylines_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),u=new verb.geom.BoundingBox(r);if(!s.intersects(u,i))return[];if(2!==e.length||2!==r.length){if(2===e.length){var o=Math.ceil(r.length/2),a=r.slice(0,o),v=r.slice(o-1),l=t.slice(0,o),c=t.slice(o-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,a,n,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,v,n,c,i))}if(2===r.length){var b=Math.ceil(e.length/2),h=e.slice(0,b),m=e.slice(b-1),_=n.slice(0,b),g=n.slice(b-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,r,_,t,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,r,g,t,i))}var b=Math.ceil(e.length/2),h=e.slice(0,b),m=e.slice(b-1),_=n.slice(0,b),g=n.slice(b-1),o=Math.ceil(r.length/2),a=r.slice(0,o),v=r.slice(o-1),l=t.slice(0,o),c=t.slice(o-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,a,_,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,v,_,c,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,a,g,l,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,v,g,c,i))}var f=verb.eval.geom.intersect_segments(e[0],e[1],r[0],r[1],i);return null!=f?(f[0][0]=f[0][0]*(n[1]-n[0])+n[0],f[1][0]=f[1][0]*(t[1]-t[0])+t[0],[[f[0][0],f[1][0]]]):[]},verb.eval.geom.intersect_segments=function(e,r,n,t,i){var s=numeric.sub(r,e),u=Math.sqrt(numeric.dot(s,s)),o=numeric.mul(1/u,s),a=numeric.sub(t,n),v=Math.sqrt(numeric.dot(a,a)),l=numeric.mul(1/v,a),c=verb.eval.geom.intersect_rays(e,o,n,l);if(null!=c){var b=Math.min(Math.max(0,c[0]/u),1),h=Math.min(Math.max(0,c[1]/v),1),m=numeric.add(numeric.mul(b,s),e),_=numeric.add(numeric.mul(h,a),n),g=numeric.norm2Squared(numeric.sub(m,_));if(i*i>g)return[[b].concat(m),[h].concat(_)]}return null},verb.eval.geom.closest_point_on_ray=function(e,r,n){var t=numeric.sub(e,r),i=numeric.dot(t,n),s=numeric.add(r,numeric.mul(i,n));return s},verb.eval.geom.dist_to_ray=function(e,r,n){var t=verb.eval.geom.closest_point_on_ray(e,r,n),i=numeric.sub(t,e);return numeric.norm2(i)},verb.eval.geom.intersect_rays=function(e,r,n,t){var i=numeric.dot(r,t),s=numeric.dot(r,n),u=numeric.dot(r,e),o=numeric.dot(t,n),a=numeric.dot(t,e),v=numeric.dot(r,r),l=numeric.dot(t,t),c=v*l-i*i;if(Math.abs(c)z)break;var P=numeric.normalized(numeric.cross(_,k)),C=numeric.dot(P,m),R=verb.eval.geom.intersect_3_planes(_,d,k,N,P,C);if(null===R)throw Error("panic!");var I=numeric.sub(R,m),L=numeric.sub(R,y),O=numeric.cross(g,_),T=numeric.cross(f,_),B=numeric.cross(x,k),j=numeric.cross(E,k),D=numeric.dot(T,I)/numeric.dot(T,g),U=numeric.dot(O,I)/numeric.dot(O,f),V=numeric.dot(j,L)/numeric.dot(j,x),q=numeric.dot(B,L)/numeric.dot(B,E);e=numeric.add([D,U],e),r=numeric.add([V,q],r),M++}while(w>M);return{uv1:e,uv2:r,pt:m,d:z}},verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine=function(e,r,n,t,i,s,u,o,a,v,l){var c={degree_u:e,degree_v:n,knots_u:r,knots_v:t,homo_control_points:i},b={minDivsU:20,minDivsV:20,tol:.05},h=verb.eval.nurbs.tessellate_rational_surface_adaptive(c.degree_u,c.knots_u,c.degree_v,c.knots_v,c.homo_control_points,b),m={degree_u:s,degree_v:o,knots_u:u,knots_v:a,homo_control_points:v},_=verb.eval.nurbs.tessellate_rational_surface_adaptive(m.degree_u,m.knots_u,m.degree_v,m.knots_v,m.homo_control_points,b),g=verb.eval.mesh.intersect_meshes_by_aabb(h.points,h.faces,h.uvs,_.points,_.faces,_.uvs),f=g.map(function(c){return c.map(function(c){return verb.eval.nurbs.refine_rational_surface_intersect_point(c.uvtri1,c.uvtri2,e,r,n,t,i,s,u,o,a,v,l)})});return f.map(function(e){return verb.eval.nurbs.rational_interp_curve(e.map(function(e){return e.pt}),2)})},verb.eval.mesh.intersect_meshes_by_aabb=function(e,r,n,t,i,s){var u=verb.range(r.length),o=verb.range(i.length),a=verb.eval.mesh.make_mesh_aabb_tree(e,r,u),v=verb.eval.mesh.make_mesh_aabb_tree(t,i,o),l=verb.eval.geom.intersect_aabb_trees(e,r,t,i,a,v),c=l.map(function(u){var o=verb.eval.geom.intersect_tris(e,r[u[0]],n,t,i[u[1]],s);return o?(o[0].tri1id=u[0],o[1].tri1id=u[0],o[0].tri2id=u[1],o[1].tri2id=u[1],o):o}).filter(function(e){return e}).filter(function(e){var r=numeric.sub(e[0].pt,e[1].pt);return numeric.dot(r,r)>verb.TOLERANCE});return c=verb.unique(c,function(e,r){var n=numeric.sub(e[0].uvtri1,r[0].uvtri1),t=numeric.dot(n,n),i=numeric.sub(e[1].uvtri1,r[1].uvtri1),s=numeric.dot(i,i),u=numeric.sub(e[0].uvtri1,r[1].uvtri1),o=numeric.dot(u,u),a=numeric.sub(e[1].uvtri1,r[0].uvtri1),v=numeric.dot(a,a);return verb.TOLERANCE>t&&verb.TOLERANCE>s||verb.TOLERANCE>o&&verb.TOLERANCE>v}),0===c.length?[]:verb.eval.mesh.make_intersect_polylines(c)},verb.eval.mesh.make_intersect_polylines=function(e){e.forEach(function(e){e[1].opp=e[0],e[0].opp=e[1]});var r=verb.eval.mesh.kdtree_from_segs(e),n=e.flatten();n.forEach(function(n){if(!n.adj){var t=verb.eval.mesh.lookup_adj_segment(n,r,e.length);t&&!t.adj&&(n.adj=t,t.adj=n)}});var t=n.filter(function(e){return!e.adj});0===t.length&&(t=n);var i=[];return t.forEach(function(e){if(!e.v){for(var r=[],n=e;n;){if(n.v)throw Error("Segment end encountered twice!");if(n.v=!0,n.opp.v=!0,r.push(n),n=n.opp.adj,n===e)break}r.length>0&&(r.push(r[r.length-1].opp),i.push(r))}}),i},verb.eval.mesh.pt_dist=function(e,r){return Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2)+Math.pow(e.z-r.z,2)},verb.eval.mesh.kdtree_from_segs=function(e){var r=[];return e.forEach(function(e){r.push({x:e[0].pt[0],y:e[0].pt[1],z:e[0].pt[2],ele:e[0]}),r.push({x:e[1].pt[0],y:e[1].pt[1],z:e[1].pt[2],ele:e[1]})}),new KdTree(r,verb.eval.mesh.pt_dist,["x","y","z"])},verb.eval.mesh.lookup_adj_segment=function(e,r,n){var t=n?Math.min(n,3):3,i=r.nearest({x:e.pt[0],y:e.pt[1],z:e.pt[2]},t).filter(function(r){return e!=r[0].ele&&r[1]b;b++){var h=s[b],m=a[b],_=verb.eval.geom.intersect_rays(h,m,e,r);if(null!==_){var g=_[0],f=_[1];-verb.EPSILON>g||g>v[b]+verb.EPSILON||((null===l||l.u>f)&&(l={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[b],numeric.mul(g/v[b],u[b]))}),(null===c||f>c.u)&&(c={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[b],numeric.mul(g/v[b],u[b]))}))}}return null===c||null===l?null:{min:l,max:c}},verb.eval.geom.point_on_ray=function(e,r,n){return numeric.add(e,numeric.mul(n,r))},verb.eval.geom.merge_tri_clip_intervals=function(e,r,n,t,i,s,u,o){if(r.min.u>e.max.u+verb.EPSILON||e.min.u>r.max.u+verb.EPSILON)return null;e.min.tri=0,e.max.tri=0,r.min.tri=1,r.max.tri=1;var a=e.min.u>r.min.u?e.min:r.min,v=e.max.uu&&(s=1,u=o),a>u&&(s=2,u=a);var v,l,c,b;0===s?(v=r[1],l=r[2],c=t[1],b=t[2]):1===s?(v=r[0],l=r[2],c=t[0],b=t[2]):(v=r[0],l=r[1],c=t[0],b=t[1]);var h,m=-numeric.dot(e,r),_=-numeric.dot(n,t),g=v*b-l*c,f=(l*_-m*b)/g,d=(m*c-v*_)/g;return h=0===s?[0,f,d]:1===s?[f,0,d]:[f,d,0],{intersects:!0,origin:h,dir:numeric.normalized(i)}},verb.eval.geom.tri_uv_from_point=function(e,r,n,t){var i=e[r[0]],s=e[r[1]],u=e[r[2]],o=n[r[0]],a=n[r[1]],v=n[r[2]],l=numeric.sub(i,t),c=numeric.sub(s,t),b=numeric.sub(u,t),h=numeric.norm2(numeric.cross(numeric.sub(i,s),numeric.sub(i,u))),m=numeric.norm2(numeric.cross(c,b))/h,_=numeric.norm2(numeric.cross(b,l))/h,g=numeric.norm2(numeric.cross(l,c))/h;return numeric.add(numeric.mul(m,o),numeric.mul(_,a),numeric.mul(g,v))},verb.eval.nurbs.tessellate_rational_surface_naive=function(e,r,n,t,i,s,u){1>s&&(s=1),1>u&&(u=1);for(var o=r[r.length-1]-r[0],a=t[t.length-1]-t[0],v=o/s,l=a/u,c=[],b=[],h=[],m=0;s+1>m;m++)for(var _=0;u+1>_;_++){var g=m*v,f=_*l;b.push([g,f]);var d=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,g,f),p=d[0][0];c.push(p);var y=numeric.normalized(numeric.cross(d[0][1],d[1][0]));h.push(y)}for(var k=[],m=0;s>m;m++)for(var _=0;u>_;_++){var x=m*(u+1)+_,E=(m+1)*(u+1)+_,N=E+1,z=x+1,w=[x,E,N],M=[x,N,z];k.push(w),k.push(M)}return{points:c,faces:k,uvs:b,normals:h}},verb.eval.nurbs.rational_curve_regular_sample=function(e,r,n,t,i){return verb.eval.nurbs.rational_curve_regular_sample_range(e,r,n,0,1,t,i)},verb.eval.nurbs.rational_curve_regular_sample_range=function(e,r,n,t,i,s,u){1>s&&(s=2);for(var o=[],a=(i-t)/(s-1),v=0,l=0;s>l;l++)v=t+a*l,u?o.push([v].concat(verb.eval.nurbs.rational_curve_point(e,r,n,v))):o.push(verb.eval.nurbs.rational_curve_point(e,r,n,v));return o},verb.eval.nurbs.rational_curve_adaptive_sample=function(e,r,n,t,i){return 1===e?i?n.map(function(e,n){return[r[n+1]].concat(verb.eval.nurbs.dehomogenize(e))}):n.map(verb.eval.nurbs.dehomogenize):verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,r[0],r[r.length-1],t,i)},verb.eval.nurbs.rational_curve_adaptive_sample_range=function(e,r,n,t,i,s,u){var o=verb.eval.nurbs.rational_curve_point(e,r,n,t),a=verb.eval.nurbs.rational_curve_point(e,r,n,i),v=.5+.2*Math.random(),l=t+(i-t)*v,c=verb.eval.nurbs.rational_curve_point(e,r,n,l),b=numeric.sub(o,a),h=numeric.sub(o,c);if(s>numeric.dot(b,b)&&numeric.dot(h,h)>s||!verb.eval.nurbs.three_points_are_flat(o,c,a,s)){var m=t+.5*(i-t),_=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,t,m,s,u),g=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,m,i,s,u);return _.slice(0,-1).concat(g)}return u?[[t].concat(o),[i].concat(a)]:[o,a]},verb.eval.nurbs.three_points_are_flat=function(e,r,n,t){var i=numeric.sub(r,e),s=numeric.sub(n,e),u=crossprod(i,s),o=numeric.dot(u,u);return t>o},verb.eval.nurbs.divide_rational_surface_adaptive=function(e,r,n,t,i,s){var u,o,a,v,l={degree_u:e,knots_u:r,degree_v:n,knots_v:t,homo_control_points:i};s=s||{},s.minDivsU=s.minDivsU||1,s.minDivsV=s.minDivsV||1,s.refine=void 0!=s.refine?s.refine:!0;var c=s.minDivsU=Math.max(s.minDivsU,3*(i.length-1)),b=s.minDivsV=Math.max(s.minDivsV,3*(i.length-1)),h=verb.last(r),m=r[0],_=verb.last(t),g=t[0],f=(h-m)/c,d=(_-g)/b,p=[],y=[];for(u=0,a=b+1;a>u;u++){var k=[];for(o=0,v=c+1;v>o;o++){var x=m+f*o,E=g+d*u,N=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,x,E),z=numeric.normalized(numeric.cross(N[0][1],N[1][0]));k.push(new verb.geom.SurfacePoint(N[0][0],z,[x,E],null,verb.isZero(z)))}y.push(k)}for(u=0;b>u;u++)for(o=0;c>o;o++){var w=[y[b-u-1][o],y[b-u-1][o+1],y[b-u][o+1],y[b-u][o]];p.push(new verb.eval.nurbs.AdaptiveRefinementNode(l,w))}if(!s.refine)return p;for(u=0;b>u;u++)for(o=0;c>o;o++){var M=u*c+o,A=verb.north(M,u,o,c,b,p),S=verb.east(M,u,o,c,b,p),P=verb.south(M,u,o,c,b,p),C=verb.west(M,u,o,c,b,p);p[M].neighbors=[P,S,A,C],p[M].divide(s)}return p},verb.north=function(e,r,n,t,i,s){return 0===r?null:s[e-t]},verb.south=function(e,r,n,t,i,s){return r===i-1?null:s[e+t]},verb.east=function(e,r,n,t,i,s){return n===t-1?null:s[e+1]},verb.west=function(e,r,n,t,i,s){return 0===n?null:s[e-1]},verb.eval.nurbs.triangulate_adaptive_refinement_node_tree=function(e){var r=verb.geom.TriMesh.empty();return e.forEach(function(e){e.triangulate(r)}),r},verb.eval.nurbs.tessellate_rational_surface_adaptive=function(e,r,n,t,i,s){var u=verb.eval.nurbs.divide_rational_surface_adaptive(e,r,n,t,i,s);return verb.eval.nurbs.triangulate_adaptive_refinement_node_tree(u)},verb.eval.nurbs.dist_to_seg=function(e,r,n){var t=numeric.sub(n,e),i=numeric.norm2(t),s=numeric.sub(r,e);if(verb.TOLERANCE>i)return numeric.norm2(s);var u=numeric.mul(1/i,t),o=numeric.dot(s,u),a=numeric.add(e,numeric.mul(o,u));return numeric.norm2(numeric.sub(a,r))},verb.geom.SurfacePoint=function(e,r,n,t,i){this.uv=n,this.point=e,this.normal=r,this.id=t,this.degen=i},verb.geom.SurfacePoint.fromUv=function(e,r){return new verb.geom.SurfacePoint(null,null,[e,r],null,null)},verb.geom.TriMesh=function(e,r,n,t){this.faces=e,this.points=r,this.uvs=n,this.normals=t},verb.geom.TriMesh.empty=function(){return new verb.geom.TriMesh([],[],[],[])},verb.eval.nurbs.AdaptiveRefinementNode=function(e,r,n,t){if(this.srf=e,this.parentNode=n,this.neighbors=t||[null,null,null,null],!r){var i=e?e.knots_u[0]:null,s=e?verb.last(e.knots_u):null,u=e?e.knots_v[0]:null,o=e?verb.last(e.knots_v):null;r=[verb.geom.SurfacePoint.fromUv(i,u),verb.geom.SurfacePoint.fromUv(s,u),verb.geom.SurfacePoint.fromUv(s,o),verb.geom.SurfacePoint.fromUv(i,o)]}this.corners=r},verb.eval.nurbs.AdaptiveRefinementNode.prototype.isLeaf=function(){return void 0===this.children},verb.eval.nurbs.AdaptiveRefinementNode.prototype.center=function(){return this.centerPoint||this.evalSrf(this.u05,this.v05)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalCorners=function(){this.u05=this.u05||(this.corners[0].uv[0]+this.corners[2].uv[0])/2,this.v05=this.v05||(this.corners[0].uv[1]+this.corners[2].uv[1])/2;for(var e=0;4>e;e++)if(!this.corners[e].point){var r=this.corners[e];this.evalSrf(r.uv[0],r.uv[1],r)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalSrf=function(e,r,n){var t=verb.eval.nurbs.rational_surface_derivs(this.srf.degree_u,this.srf.knots_u,this.srf.degree_v,this.srf.knots_v,this.srf.homo_control_points,1,e,r),i=t[0][0],s=numeric.cross(t[0][1],t[1][0]),u=verb.isZero(s);return u||(s=numeric.normalized(s)),n?(n.degen=u,n.point=i,n.normal=s,n):new verb.geom.SurfacePoint(i,s,[e,r],null,u)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getEdgeCorners=function(e){if(this.isLeaf())return[this.corners[e]];if(this.horizontal)switch(e){case 0:return this.children[0].getEdgeCorners(0);case 1:return this.children[0].getEdgeCorners(1).concat(this.children[1].getEdgeCorners(1));case 2:return this.children[1].getEdgeCorners(2);case 3:return this.children[1].getEdgeCorners(3).concat(this.children[0].getEdgeCorners(3))}switch(e){case 0:return this.children[0].getEdgeCorners(0).concat(this.children[1].getEdgeCorners(0));case 1:return this.children[1].getEdgeCorners(1);case 2:return this.children[1].getEdgeCorners(2).concat(this.children[0].getEdgeCorners(2));case 3:return this.children[0].getEdgeCorners(3)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getAllCorners=function(e){var r=[this.corners[e]];if(!this.neighbors[e])return r;var n=this.neighbors[e].getEdgeCorners((e+2)%4),t=e%2,i=verb.EPSILON,s=this,u=[function(e){return e.uv[0]>s.corners[0].uv[0]+i&&e.uv[0]s.corners[0].uv[1]+i&&e.uv[1]r;r++)if(Math.abs(e[r])>verb.TOLERANCE)return!1;return!0},verb.eval.nurbs.AdaptiveRefinementNode.prototype.hasBadNormals=function(){return this.corners[0].degen||this.corners[1].degen||this.corners[2].degen||this.corners[3].degen},verb.eval.nurbs.AdaptiveRefinementNode.prototype.fixNormals=function(){for(var e=0,r=this.corners.length;r>e;e++)if(this.corners[e],this.corners[e].degen){var n=this.corners[(e+1)%r],t=this.corners[(e+3)%r];this.corners[e].normal=n.degen?t.normal:n.normal}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide=function(e,r){if(e.minDepth>r)return!0;if(r>=e.maxDepth)return!1;if(this.hasBadNormals())return this.fixNormals(),!1;if(this.splitVert=numeric.norm2Squared(numeric.sub(this.corners[0].normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[2].normal,this.corners[3].normal))>e.normTol,this.splitHoriz=numeric.norm2Squared(numeric.sub(this.corners[1].normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[3].normal,this.corners[0].normal))>e.normTol,this.splitVert||this.splitHoriz)return!0;var n=this.center();return numeric.norm2Squared(numeric.sub(n.normal,this.corners[0].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[3].normal))>e.normTol},verb.eval.nurbs.AdaptiveRefinementNode.prototype.divide=function(e){e=e||{},e.edgeTol=e.edgeTol||.1,e.normTol=e.normTol||.05,e.minDepth=void 0!=e.minDepth?e.minDepth:0,e.maxDepth=void 0!=e.maxDepth?e.maxDepth:10,this._divide(e,0,!0)},verb.eval.nurbs.AdaptiveRefinementNode.prototype._divide=function(e,r,n){if(this.evalCorners(),this.shouldDivide(e,r)){if(r++,this.splitVert&&!this.splitHoriz?n=!1:!this.splitVert&&this.splitHoriz&&(n=!0),this.horizontal=n,this.horizontal){var t=[this.corners[0],this.corners[1],this.midpoint(1),this.midpoint(3)],i=[this.midpoint(3),this.midpoint(1),this.corners[2],this.corners[3]];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,t,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,i,this)],this.children[0].neighbors=[this.neighbors[0],this.neighbors[1],this.children[1],this.neighbors[3]],this.children[1].neighbors=[this.children[0],this.neighbors[1],this.neighbors[2],this.neighbors[3]]}else{var s=[this.corners[0],this.midpoint(0),this.midpoint(2),this.corners[3]],u=[this.midpoint(0),this.corners[1],this.corners[2],this.midpoint(2)];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,s,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,u,this)],this.children[0].neighbors=[this.neighbors[0],this.children[1],this.neighbors[2],this.neighbors[3]],this.children[1].neighbors=[this.neighbors[0],this.neighbors[1],this.neighbors[2],this.children[0]]}this.children.forEach(function(t){t._divide(e,r,!n)})}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulate=function(e){return e=e||verb.geom.TriMesh.empty(),this.isLeaf()?this.triangulateLeaf(e):(this.children.forEach(function(r){r&&r.triangulate(e)}),e)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulateLeaf=function(e){var r,n,t,i,s=e.points.length,u=[],o=[],a=0;for(a=0;4>a;a++){var v=this.getAllCorners(a);for(2===v.length&&(i=a+1),t=0;v.length>t;t++)u.push(v[t])}for(a=0,n=u.length;n>a;a++)r=u[a],void 0==r.id?(e.uvs.push(r.uv),e.points.push(r.point),e.normals.push(r.normal),r.id=s,o.push(s),s++):o.push(r.id);if(4===u.length)return e.faces.push([o[0],o[3],o[1]]),e.faces.push([o[3],o[2],o[1]]),e;if(5===u.length){var l=o.length;return e.faces.push([o[i],o[(i+1)%l],o[(i+2)%l]]),e.faces.push([o[(i+4)%l],o[(i+3)%l],o[i]]),e.faces.push([o[i],o[(i+2)%l],o[(i+3)%l]]),e}var c=this.center();e.uvs.push(c.uv),e.points.push(c.point),e.normals.push(c.normal);var b=e.points.length-1;for(a=0,t=u.length-1;u.length>a;t=a++)e.faces.push([b,o[t],o[a]]);return e},verb.eval.nurbs.rational_interp_curve=function(e,r){if(r=r||3,r+1>e.length)throw Error("You need to supply at least degree + 1 points!");for(var n=[0],t=1;e.length>t;t++){var i=numeric.norm2(numeric.sub(e[t],e[t-1])),s=n[n.length-1];n.push(s+i)}for(var u=n[n.length-1],t=0;n.length>t;t++)n[t]=n[t]/u;for(var o=numeric.rep([r+1],0),a=e.length-1,t=1,v=n.length-r;v>t;t++){for(var l=0,c=0;r>c;c++)l+=n[t+c];o.push(1/r*l)}for(var b=o.concat(numeric.rep([r+1],1)),h=[],t=0;n.length>t;t++){var m=n[t],_=verb.eval.nurbs.knot_span_given_n(a,r,m,b),g=verb.eval.nurbs.basis_functions_given_knot_span_index(_,m,r,b),f=_-r,d=verb.eval.nurbs.zeros_1d(f),p=verb.eval.nurbs.zeros_1d(e.length-(r+1)-f);h.push(d.concat(g).concat(p))}for(var y=e[0].length,k=[],t=0;y>t;t++){var x=e.map(function(e){return e[t]}),E=numeric.solve(h,x);k.push(E)}var N=numeric.transpose(k),z=numeric.rep([N.length],1);return{control_points:N,knots:b,degree:r,weights:z}},verb.eval.nurbs.get_sweep1_surface=function(e,r,n,t,i,s,u,o){for(var a=verb.eval.nurbs.homogenize_1d(u,o),v=verb.eval.nurbs.rational_curve_point(s,i,a,0),l=1/u.length,c=[],b=[],h=0;u.length>h;h++){for(var m=verb.eval.nurbs.rational_curve_point(s,i,a,h*l),_=numeric.sub(m,v),g=[],f=[],d=0;n.length>d;d++)g.push(numeric.add(_,n[d])),f.push(t[d]*o[h]);c.push(g),b.push(f)}return{knots_u:i,knots_v:e,control_points:c,degree_u:s,degree_v:r,weights:b}},verb.eval.nurbs.get_ellipse_arc=function(e,r,n,t,i,s,u){s>u&&(u=2*Math.PI+s);var o=u-s,a=0;a=Math.PI/2>=o?1:Math.PI>=o?2:3*Math.PI/2>=o?3:4;var v=o/a,l=Math.cos(v/2),c=numeric.add(e,numeric.mul(t,Math.cos(s),r),numeric.mul(i,Math.sin(s),n)),b=numeric.sub(numeric.mul(Math.cos(s),n),numeric.mul(Math.sin(s),r)),h=verb.eval.nurbs.zeros_1d(2*a),m=verb.eval.nurbs.zeros_1d(2*a+3),_=0,g=s,f=verb.eval.nurbs.zeros_1d(2*a);h[0]=c,f[0]=1;for(var d=1;a>=d;d++){g+=v;var p=numeric.add(e,numeric.mul(t,Math.cos(g),r),numeric.mul(i,Math.sin(g),n));f[_+2]=1,h[_+2]=p;var y=numeric.sub(numeric.mul(Math.cos(g),n),numeric.mul(Math.sin(g),r)),k=verb.eval.geom.intersect_rays(c,numeric.mul(1/numeric.norm2(b),b),p,numeric.mul(1/numeric.norm2(y),y)),x=numeric.add(c,numeric.mul(b,k[0]));f[_+1]=l,h[_+1]=x,_+=2,a>d&&(c=p,b=y)}for(var E=2*a+1,d=0;3>d;d++)m[d]=0,m[d+E]=1;switch(a){case 1:break;case 2:m[3]=m[4]=.5;break;case 3:m[3]=m[4]=1/3,m[5]=m[6]=2/3;break;case 4:m[3]=m[4]=.25,m[5]=m[6]=.5,m[7]=m[8]=.75}return{knots:m,control_points:h,degree:2,weights:f}},verb.eval.nurbs.get_sphere_surface=function(e,r,n,t){var i=verb.eval.nurbs.get_arc(e,numeric.mul(r,-1),n,t,0,Math.PI);return verb.eval.nurbs.get_revolved_surface(e,r,2*Math.PI,i.knots,i.degree,i.control_points,i.weights)},verb.eval.nurbs.get_polyline_curve=function(e){for(var r=e.length-1,n=1/r,t=[0,0],i=1;r>i;i++)t.push(i*n);t.push(1),t.push(1);for(var s=[],i=0;e.length>i;i++)s.push(1);return{knots:t,control_points:e.slice(0),degree:1,weights:s}},verb.eval.nurbs.get_4pt_surface=function(e,r,n,t){var i=numeric.mul(.5,numeric.add(e,t)),s=numeric.mul(.5,numeric.add(r,n)),u=numeric.mul(.5,numeric.add(n,t)),o=numeric.mul(.5,numeric.add(e,r)),a=numeric.mul(.5,numeric.add(i,s));return{knots_u:[0,0,0,1,1,1],knots_v:[0,0,0,1,1,1],control_points:[[e,i,t],[o,a,u],[r,s,n]],degree_u:2,degree_v:2,weights:[[1,1,1],[1,1,1],[1,1,1]]}},verb.eval.nurbs.get_cylinder_surface=function(e,r,n,t,i){var s=crossprod(e,r),u=(2*Math.PI,verb.eval.nurbs.get_arc(n,r,s,i,0,2*Math.PI));return verb.eval.nurbs.get_extruded_surface(e,t,u.knots,u.degree,u.control_points,u.weights)},verb.eval.nurbs.get_cone_surface=function(e,r,n,t,i){var s=2*Math.PI,u=1,o=[numeric.add(n,numeric.mul(t,e)),numeric.add(n,numeric.mul(i,r))],a=[0,0,1,1],v=[1,1]; -return verb.eval.nurbs.get_revolved_surface(n,e,s,a,u,o,v)},verb.eval.nurbs.get_extruded_surface=function(e,r,n,t,i,s){for(var u=verb.eval.nurbs.zeros_2d(3,i.length),o=verb.eval.nurbs.zeros_2d(3,i.length),a=numeric.mul(e,r),v=numeric.mul(e,.5*r),l=0;i.length>l;l++)u[2][l]=i[l],u[1][l]=numeric.add(v,i[l]),u[0][l]=numeric.add(a,i[l]),o[0][l]=s[l],o[1][l]=s[l],o[2][l]=s[l];return{knots_u:[0,0,0,1,1,1],knots_v:n,control_points:u,degree_u:2,degree_v:t,weights:o}},verb.eval.nurbs.get_revolved_surface=function(e,r,n,t,i,s,u){var o,a,v,l;Math.PI/2>=n?(o=1,a=verb.eval.nurbs.zeros_1d(6+2*(o-1))):Math.PI>=n?(o=2,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=.5):3*Math.PI/2>=n?(o=3,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=1/3,a[5]=a[6]=2/3):(o=4,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=.25,a[5]=a[6]=.5,a[7]=a[8]=.75);for(var c=n/o,b=3+2*(o-1),h=0;3>h;b++,h++)a[h]=0,a[b]=1;for(var m=Math.cos(c/2),_=0,g=verb.eval.nurbs.zeros_1d(o+1),f=verb.eval.nurbs.zeros_1d(o+1),v=verb.eval.nurbs.zeros_2d(2*o+1,s.length),l=verb.eval.nurbs.zeros_2d(2*o+1,s.length),h=1;o>=h;h++)_+=c,f[h]=Math.cos(_),g[h]=Math.sin(_);for(b=0;s.length>b;b++){var d=verb.eval.geom.closest_point_on_ray(s[b],e,r),p=numeric.sub(s[b],d),y=numeric.norm2(p),k=crossprod(r,p);y>verb.EPSILON&&(p=numeric.mul(1/y,p),k=numeric.mul(1/y,k)),v[0][b]=s[b];var x=s[b];l[0][b]=u[b];for(var E=k,N=0,_=0,h=1;o>=h;h++){var z=0==y?d:numeric.add(d,numeric.mul(y,f[h],p),numeric.mul(y,g[h],k));v[N+2][b]=z,l[N+2][b]=u[b];var w=numeric.sub(numeric.mul(f[h],k),numeric.mul(g[h],p));if(0==y)v[N+1][b]=d;else{var M=verb.eval.geom.intersect_rays(x,numeric.mul(1/numeric.norm2(E),E),z,numeric.mul(1/numeric.norm2(w),w)),A=numeric.add(x,numeric.mul(E,M[0]));v[N+1][b]=A}l[N+1][b]=m*u[b],N+=2,o>h&&(x=z,E=w)}}return{knots_u:a,knots_v:t,control_points:v,degree_u:2,degree_v:i,weights:l}},verb.eval.nurbs.get_arc=function(e,r,n,t,i,s){return verb.eval.nurbs.get_ellipse_arc(e,r,n,t,t,i,s)},verb.eval.nurbs.curve_bezier_decompose=function(e,r,n){for(var t=verb.eval.nurbs.knot_multiplicities(r),i=e+1,s=verb.eval.nurbs.curve_knot_refine,u=0;t.length>u;u++)if(i>t[u][1]){var o=numeric.rep([i-t[u][1]],t[u][0]),a=s(e,r,n,o);r=a.knots,n=a.control_points}r.length/i-1;for(var v=2*i,l=[],u=0;n.length>u;u+=i){var c=r.slice(u,u+v),b=n.slice(u,u+i);l.push({degree:e,knots:c,control_points:b})}return l},verb.eval.nurbs.knot_multiplicities=function(e){for(var r=[[e[0],0]],n=r[0],t=0;e.length>t;t++)Math.abs(e[t]-n[0])>verb.EPSILON&&(n=[e[t],0],r.push(n)),n[1]++;return r},verb.eval.nurbs.curve_split=function(e,r,n,t){for(var i=[],s=0;e+1>s;s++)i.push(t);var u=verb.eval.nurbs.curve_knot_refine(e,r,n,i),o=verb.eval.nurbs.knot_span(e,t,r),a=u.knots.slice(0,o+e+2),v=u.knots.slice(o+1),l=u.control_points.slice(0,o+1),c=u.control_points.slice(o+1);return[{degree:e,knots:a,control_points:l},{degree:e,knots:v,control_points:c}]},verb.eval.nurbs.curve_knot_refine=function(e,r,n,t){var i=n.length-1,s=i+e+1,u=t.length-1,o=verb.eval.nurbs.knot_span(e,t[0],r),a=verb.eval.nurbs.knot_span(e,t[u],r),v=Array(n.length+u+1),l=Array(r.length+u+1),c=0,b=0;for(c=0;o-e>=c;c++)v[c]=n[c];for(c=a-1;i>=c;c++)v[c+u+1]=n[c];for(c=0;o>=c;c++)l[c]=r[c];for(c=a+e;s>=c;c++)l[c+u+1]=r[c];c=a+e-1;var h=a+e+u;for(b=u;b>=0;b--){for(;t[b]<=r[c]&&c>o;)v[h-e-1]=n[c-e-1],l[h]=r[c],h-=1,c-=1;v[h-e-1]=v[h-e];for(var m=1;e>=m;m++){var _=h-e+m,g=l[h+m]-t[b];Math.abs(g)=b;b++)l[b]=r[b];for(b=1;i>=b;b++)l[o+b]=t;for(b=o+1;r.length>b;b++)l[b+i]=r[b];for(b=0;o-e>=b;b++)c[b]=n[b];for(b=o-s;u>b;b++)c[b+i]=n[b];for(b=0;e-s>=b;b++)v[b]=n[o-e+b];for(var h=0,m=0,_=1;i>=_;_++){for(h=o-e+_,b=0;e-_-s>=b;b++)m=(t-r[h+b])/(r[b+o+1]-r[h+b]),v[b]=numeric.add(numeric.mul(m,v[b+1]),numeric.mul(1-m,v[b]));c[h]=v[0],c[o+i-_-s]=v[e-_-s]}for(b=h+1;o-s>b;b++)c[b]=v[b-h];return{knots:l,control_points:c}},verb.eval.nurbs.rational_surface_curvature=function(e,r,n,t,i,s,u){var o=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,2,s,u),a=o[0][1],v=o[1][0],l=o[0][2],c=o[2][0],b=o[1][1],h=numeric.cross(a,v),m=numeric.dot(l,h),_=numeric.dot(b,h),g=numeric.dot(c,h),f=[[m,_],[_,g]],d=numeric.eig(f),p=d.lambda.x[0],y=d.lambda.x[1],k=.5*(p+y),x=p*y,E=numeric.add(numeric.mul(d.E.x[0][0],a),numeric.mul(d.E.x[0][1],v)),N=numeric.add(numeric.mul(d.E.x[1][0],a),numeric.mul(d.E.x[1][1],v));return{point:o[0][0],normal:h,mean:k,gaussian:x,shapeOperator:f,k1:p,k2:y,p1:E,p2:N,p1p:d.E.x[0],p2p:d.E.x[1]}},verb.eval.nurbs.rational_surface_derivs=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.surface_derivs(e,r,n,t,i,s,u,o),v=verb.eval.nurbs.separate_homo_derivs_2d(a),l=v[0],c=v[1],b=0,h=0,m=0,_=0,g=[],f=l[0][0].length;for(b=0;s>=b;b++)for(g.push([]),_=0;s-b>=_;_++){var o=l[b][_];for(m=1;_>=m;m++)o=numeric.sub(o,numeric.mul(numeric.mul(binomial.get(_,m),c[0][m]),g[b][_-m]));for(h=1;b>=h;h++){o=numeric.sub(o,numeric.mul(numeric.mul(binomial.get(b,h),c[h][0]),g[b-h][_]));var d=verb.eval.nurbs.zeros_1d(f);for(m=1;_>=m;m++)d=numeric.add(d,numeric.mul(numeric.mul(binomial.get(_,m),c[h][m]),g[b-h][_-m]));o=numeric.sub(o,numeric.mul(binomial.get(b,h),d))}g[b].push(numeric.mul(1/c[0][0],o))}return g},verb.eval.nurbs.rational_surface_point=function(e,r,n,t,i,s,u){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.surface_point(e,r,n,t,i,s,u))},verb.eval.nurbs.rational_curve_derivs=function(e,r,n,t,i){var s=verb.eval.nurbs.separate_homo_derivs_1d(verb.eval.nurbs.curve_derivs(e,r,n,t,i)),u=s[0],o=s[1],a=0,v=0,l=[];for(a=0;i>=a;a++){var c=u[a];for(v=1;a>=v;v++)c=numeric.sub(c,numeric.mul(numeric.mul(binomial.get(a,v),o[v]),l[a-v]));l.push(numeric.mul(1/o[0],c))}return l},verb.eval.nurbs.separate_homo_derivs_1d=function(e){for(var r=e[0].length,n=r-1,t=[],i=[],s=0,u=e.length;u>s;s++)t.push(e[s].slice(0,n)),i.push(e[s][n]);return[t,i]},verb.eval.nurbs.separate_homo_derivs_2d=function(e){for(var r=[],n=[],t=0,i=e.length;i>t;t++){var s=verb.eval.nurbs.separate_homo_derivs_1d(e[t]);r.push(s[0]),n.push(s[1])}return[r,n]},verb.eval.nurbs.rational_curve_point=function(e,r,n,t){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.curve_point(e,r,n,t))},verb.eval.nurbs.dehomogenize=function(e){for(var r=e.length,n=[],t=e[r-1],i=0;e.length-1>i;i++)n.push(e[i]/t);return n},verb.eval.nurbs.weight_1d=function(e){var r=e[0].length-1;return e.map(function(e){return e[r]})},verb.eval.nurbs.dehomogenize_1d=function(e){return e.map(function(e){return verb.eval.nurbs.dehomogenize(e)})},verb.eval.nurbs.homogenize_1d=function(e,r){for(var n=e.length,t=e[0].length,i=0,s=[],u=0,o=[],a=0;n>a;a++){var v=[];for(o=e[a],u=r[a],i=0;t>i;i++)v.push(o[i]*u);v.push(u),s.push(v)}return s},verb.eval.nurbs.homogenize_2d=function(e,r){for(var n=e.length,t=(e[0].length,e[0][0].length,[]),i=0;n>i;i++)t.push(verb.eval.nurbs.homogenize_1d(e[i],r[i]));return t},verb.eval.nurbs.surface_derivs=function(e,r,n,t,i,s,u,o){var a=r.length-e-2,v=t.length-n-2;return verb.eval.nurbs.surface_derivs_given_n_m(a,e,r,v,n,t,i,s,u,o)},verb.eval.nurbs.surface_derivs_given_n_m=function(e,r,n,t,i,s,u,o,a,v){if(verb.eval.nurbs.are_valid_relations(r,u.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,u[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var l=u[0][0].length,c=Math.min(o,r),b=Math.min(o,i),h=verb.eval.nurbs.zeros_3d(c+1,b+1,l),m=verb.eval.nurbs.knot_span_given_n(e,r,a,n),_=verb.eval.nurbs.knot_span_given_n(t,i,v,s),g=verb.eval.nurbs.deriv_basis_functions_given_n_i(m,a,r,e,n),f=verb.eval.nurbs.deriv_basis_functions_given_n_i(_,v,i,t,s),d=verb.eval.nurbs.zeros_2d(i+1,l),p=0,y=0,k=0,x=0,E=0;for(p=0;c>=p;p++){for(y=0;i>=y;y++)for(d[y]=verb.eval.nurbs.zeros_1d(l),k=0;r>=k;k++)d[y]=numeric.add(d[y],numeric.mul(g[p][k],u[m-r+k][_-i+y]));for(E=Math.min(o-p,b),x=0;E>=x;x++)for(h[p][x]=verb.eval.nurbs.zeros_1d(l),y=0;i>=y;y++)h[p][x]=numeric.add(h[p][x],numeric.mul(f[x][y],d[y]))}return h},verb.eval.nurbs.surface_point=function(e,r,n,t,i,s,u){var o=r.length-e-2,a=t.length-n-2;return verb.eval.nurbs.surface_point_given_n_m(o,e,r,a,n,t,i,s,u)},verb.eval.nurbs.volume_point=function(e,r,n,t,i,s,u,o,a,v){var l=r.length-e-2,c=t.length-n-2,b=s.length-i-2;return verb.eval.nurbs.volume_point_given_n_m_l(l,e,r,c,n,t,b,i,s,u,o,a,v)},verb.eval.nurbs.volume_point_given_n_m_l=function(e,r,n,t,i,s,u,o,a,v,l,c,b){if(!verb.eval.nurbs.are_valid_relations(r,v.length,n.length)||!verb.eval.nurbs.are_valid_relations(i,v[0].length,s.length)||!verb.eval.nurbs.are_valid_relations(o,v[0][0].length,a.length))return console.error("Invalid relations between control points and knot vector"),null;for(var h=v[0][0][0].length,m=verb.eval.nurbs.knot_span_given_n(e,r,l,n),_=verb.eval.nurbs.knot_span_given_n(t,i,c,s),g=verb.eval.nurbs.knot_span_given_n(u,o,b,a),f=verb.eval.nurbs.basis_functions_given_knot_span_index(m,l,r,n),d=verb.eval.nurbs.basis_functions_given_knot_span_index(_,c,i,s),p=verb.eval.nurbs.basis_functions_given_knot_span_index(g,b,o,a),y=m-r,k=_,x=g,E=verb.eval.nurbs.zeros_1d(h),N=verb.eval.nurbs.zeros_1d(h),z=verb.eval.nurbs.zeros_1d(h),w=0,M=0,A=0;o>=A;A++){for(z=verb.eval.nurbs.zeros_1d(h),x=g-o+A,w=0;i>=w;w++){for(N=verb.eval.nurbs.zeros_1d(h),k=_-i+w,M=0;r>=M;M++)N=numeric.add(N,numeric.mul(f[M],v[y+M][k][x]));z=numeric.add(z,numeric.mul(d[w],N))}E=numeric.add(E,numeric.mul(p[A],z))}return E},verb.eval.nurbs.surface_point_given_n_m=function(e,r,n,t,i,s,u,o,a){if(verb.eval.nurbs.are_valid_relations(r,u.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,u[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var v=u[0][0].length,l=verb.eval.nurbs.knot_span_given_n(e,r,o,n),c=verb.eval.nurbs.knot_span_given_n(t,i,a,s),b=verb.eval.nurbs.basis_functions_given_knot_span_index(l,o,r,n),h=verb.eval.nurbs.basis_functions_given_knot_span_index(c,a,i,s),m=l-r,_=c,g=verb.eval.nurbs.zeros_1d(v),f=verb.eval.nurbs.zeros_1d(v),d=0,p=0;for(d=0;i>=d;d++){for(f=verb.eval.nurbs.zeros_1d(v),_=c-i+d,p=0;r>=p;p++)f=numeric.add(f,numeric.mul(b[p],u[m+p][_]));g=numeric.add(g,numeric.mul(h[d],f))}return g},verb.eval.nurbs.curve_derivs=function(e,r,n,t,i){var s=r.length-e-2;return verb.eval.nurbs.curve_derivs_given_n(s,e,r,n,t,i)},verb.eval.nurbs.curve_derivs_given_n=function(e,r,n,t,i,s){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var u=t[0].length,o=Math.min(s,r),a=verb.eval.nurbs.zeros_2d(o+1,u),v=verb.eval.nurbs.knot_span_given_n(e,r,i,n),l=verb.eval.nurbs.deriv_basis_functions_given_n_i(v,i,r,o,n),c=0,b=0;for(c=0;o>=c;c++)for(b=0;r>=b;b++)a[c]=numeric.add(a[c],numeric.mul(l[c][b],t[v-r+b]));return a},verb.eval.nurbs.are_valid_relations=function(e,r,n){return 0===r+e+1-n?!0:!1},verb.eval.nurbs.curve_point=function(e,r,n,t){var i=r.length-e-2;return verb.eval.nurbs.curve_point_given_n(i,e,r,n,t)},verb.eval.nurbs.curve_point_given_n=function(e,r,n,t,i){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;for(var s=verb.eval.nurbs.knot_span_given_n(e,r,i,n),u=verb.eval.nurbs.basis_functions_given_knot_span_index(s,i,r,n),o=verb.eval.nurbs.zeros_1d(t[0].length),a=0;r>=a;a++)o=numeric.add(o,numeric.mul(u[a],t[s-r+a]));return o},verb.eval.nurbs.zeros_1d=function(e){return numeric.rep([e],0)},verb.eval.nurbs.zeros_2d=function(e,r){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r],0)},verb.eval.nurbs.zeros_3d=function(e,r,n){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r,n],0)},verb.eval.nurbs.deriv_basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(r,e,n),i=n.length-1,s=i-r-1;return verb.eval.nurbs.deriv_basis_functions_given_n_i(t,e,r,s,n)},verb.eval.nurbs.deriv_basis_functions_given_n_i=function(e,r,n,t,i){var s=verb.eval.nurbs.zeros_2d(n+1,n+1),u=Array(n+1),o=Array(n+1),a=0,v=0,l=1,c=0;for(s[0][0]=1,l=1;n>=l;l++){for(u[l]=r-i[e+1-l],o[l]=i[e+l]-r,a=0,c=0;l>c;c++)s[l][c]=o[c+1]+u[l-c],v=s[c][l-1]/s[l][c],s[c][l]=a+o[c+1]*v,a=u[l-c]*v;s[l][l]=a}var b=verb.eval.nurbs.zeros_2d(t+1,n+1),h=verb.eval.nurbs.zeros_2d(2,n+1),m=1,_=0,g=1,f=0,d=0,p=0,y=0,k=0;for(l=0;n>=l;l++)b[0][l]=s[l][n];for(c=0;n>=c;c++)for(_=0,g=1,h[0][0]=1,m=1;t>=m;m++){for(f=0,d=c-m,p=n-m,c>=m&&(h[g][0]=h[_][0]/s[p+1][d],f=h[g][0]*s[d][p]),y=d>=-1?1:-d,k=p>=c-1?m-1:n-c,l=y;k>=l;l++)h[g][l]=(h[_][l]-h[_][l-1])/s[p+1][d+l],f+=h[g][l]*s[d+l][p];p>=c&&(h[g][m]=-h[_][m-1]/s[p+1][c],f+=h[g][m]*s[c][p]),b[m][c]=f,l=_,_=g,g=l}for(c=n,m=1;t>=m;m++){for(l=0;n>=l;l++)b[m][l]*=c;c*=n-m}return b},verb.eval.nurbs.basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(e,r,n);return verb.eval.nurbs.basis_functions_given_knot_span_index(t,e,r,n)},verb.eval.nurbs.basis_functions_given_knot_span_index=function(e,r,n,t){var i=Array(n+1),s=Array(n+1),u=Array(n+1),o=0,a=0;i[0]=1;for(var v=1;n>=v;v++){s[v]=r-t[e+1-v],u[v]=t[e+v]-r,o=0;for(var l=0;v>l;l++)a=i[l]/(u[l+1]+s[v-l]),i[l]=o+u[l+1]*a,o=s[v-l]*a;i[v]=o}return i},verb.eval.nurbs.knot_span=function(e,r,n){var t=n.length-1,i=t-e-1;return verb.eval.nurbs.knot_span_given_n(i,e,r,n)},verb.eval.nurbs.knot_span_given_n=function(e,r,n,t){if(n>=t[e+1])return e;if(t[r]>n)return r;for(var i=r,s=e+1,u=Math.floor((i+s)/2);t[u]>n||n>=t[u+1];)t[u]>n?s=u:i=u,u=Math.floor((i+s)/2);return u}; \ No newline at end of file +function crossprod(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]}if("object"!=typeof exports||void 0===exports)importScripts("labor.js"),importScripts("binomial.js"),importScripts("numeric-1.2.6.min.js");else var labor=require("labor");var verb=verb||{};verb.eval=verb.eval||{},verb.eval.nurbs=verb.eval.nurbs||{},verb.eval.mesh=verb.eval.mesh||{},verb.eval.geom=verb.eval.geom||{},verb.geom=verb.geom||{},verb.EPSILON=1e-8,verb.TOLERANCE=.001;var router=new labor.Router(verb.eval.nurbs);numeric.normalized=function(e){return numeric.div(e,numeric.norm2(e))},numeric.cross=function(e,r){return[e[1]*r[2]-e[2]*r[1],e[2]*r[0]-e[0]*r[2],e[0]*r[1]-e[1]*r[0]]},verb.left=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(0,r)},verb.right=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r)},verb.rightWithPivot=function(e){if(0===e.length)return[];var r=Math.ceil(e.length/2);return e.slice(r-1)},verb.unique=function(e,r){if(0===e.length)return[];for(var n=[e.pop()],t=0;e.length>t;t++){for(var i=e.pop(),s=!0,u=0;n.length>u;u++)if(r(i,n[t])){s=!1;break}s&&n.push(i)}return n},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb_refine=function(e,r,n,t,i,s,u,o,a,v,l,c){var b=verb.eval.nurbs.intersect_rational_curve_surface_by_aabb(e,r,n,t,i,s,u,o,a,v,l,c);return b.map(function(a){var v=[a.p,a.uv[0],a.uv[1]],l=verb.eval.nurbs.refine_rational_curve_surface_intersection(e,r,n,t,i,s,u,o,v);return a.p=l[0],a.uv[0]=l[1],a.uv[1]=l[2],a.distance=l[3],delete a.face,a})},verb.eval.nurbs.refine_rational_curve_surface_intersection=function(e,r,n,t,i,s,u,o,a){var v=function(a){var v=verb.eval.nurbs.rational_curve_point(s,u,o,a[0]),l=verb.eval.nurbs.rational_surface_point(e,r,n,t,i,a[1],a[2]),c=numeric.sub(v,l);return numeric.dot(c,c)},l=numeric.uncmin(v,a);return l.solution.concat(l.f)},verb.eval.nurbs.intersect_rational_curve_surface_by_aabb=function(e,r,n,t,i,s,u,o,a,v,l,c){var b=verb.eval.nurbs.rational_curve_adaptive_sample(s,u,o,a,!0),h=verb.eval.nurbs.tessellate_rational_surface_naive(e,r,n,t,i,l,c),m=b.map(function(e){return e[0]}),_=b.map(function(e){return e.slice(1)}),g=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb(_,m,h,verb.range(h.faces.length),v);return verb.unique(g,function(e,r){return v>numeric.norm2(numeric.sub(e.point,r.point))&&v>Math.abs(e.p-r.p)&&v>numeric.norm2(numeric.sub(e.uv,r.uv))})},verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),u=verb.eval.mesh.make_mesh_aabb(n.points,n.faces,t),o=verb.eval.nurbs.intersect_parametric_polyline_mesh_by_aabb;if(!s.intersects(u,i))return[];if(2!==e.length||1!==t.length){if(1===t.length){var a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return o(a,l,n,t,i).concat(o(v,c,n,t,i))}if(2===e.length){var b=verb.eval.mesh.sort_tris_on_longest_axis(u,n.points,n.faces,t),h=verb.left(b),m=verb.right(b);return o(e,r,n,h,i).concat(o(e,r,n,m,i))}var b=verb.eval.mesh.sort_tris_on_longest_axis(u,n.points,n.faces,t),h=verb.left(b),m=verb.right(b),a=verb.left(e),v=verb.rightWithPivot(e),l=verb.left(r),c=verb.rightWithPivot(r);return o(a,l,n,h,i).concat(o(a,l,n,m,i)).concat(o(v,c,n,h,i)).concat(o(v,c,n,m,i))}var _=verb.eval.geom.intersect_segment_with_tri(e[0],e[1],n.points,n.faces[t[0]]);if(null!=_){var g=_.p*(r[1]-r[0])+r[0],f=n.faces[t][0],d=n.faces[t][1],p=n.faces[t][2],y=n.uvs[f],k=n.uvs[d],x=n.uvs[p],N=numeric.sub(k,y),E=numeric.sub(x,y),z=numeric.add(y,numeric.mul(_.s,N),numeric.mul(_.t,E));return[{point:_.point,p:g,uv:z,face:t[0]}]}return[]},verb.eval.geom.intersect_segment_with_tri=function(e,r,n,t){var i=n[t[0]],s=n[t[1]],u=n[t[2]],o=numeric.sub(s,i),a=numeric.sub(u,i),v=numeric.cross(o,a),l=numeric.sub(r,e),c=numeric.sub(e,i),b=-numeric.dot(v,c),h=numeric.dot(v,l);if(Math.abs(h)m||m>1)return null;var _=numeric.add(e,numeric.mul(m,l)),g=numeric.dot(o,a),f=numeric.dot(o,o),d=numeric.dot(a,a),p=numeric.sub(_,i),y=numeric.dot(p,o),k=numeric.dot(p,a),x=g*g-f*d,N=(g*k-d*y)/x,E=(g*y-f*k)/x;return N>1+verb.EPSILON||E>1+verb.EPSILON||-verb.EPSILON>E||-verb.EPSILON>N||N+E>1+verb.EPSILON?null:{point:_,s:N,t:E,p:m}},verb.eval.geom.intersect_segment_with_plane=function(e,r,n,t){var i=numeric.dot(t,numeric.sub(e,r));if(EPSILON>abs(i))return null;var s=numeric.dot(t,numeric.sub(n,e));return{p:s/i}},verb.eval.geom.intersect_aabb_trees=function(e,r,n,t,i,s){var u=i.bounding_box.intersects(s.bounding_box),o=verb.eval.geom.intersect_aabb_trees;return u?0===i.children.length&&0===s.children.length?[[i.triangle,s.triangle]]:0===i.children.length&&0!=s.children.length?o(e,r,n,t,i,s.children[0]).concat(o(e,r,n,t,i,s.children[1])):0!=i.children.length&&0===s.children.length?o(e,r,n,t,i.children[0],s).concat(o(e,r,n,t,i.children[1],s)):0!=i.children.length&&0!=s.children.length?o(e,r,n,t,i.children[0],s.children[0]).concat(o(e,r,n,t,i.children[0],s.children[1])).concat(o(e,r,n,t,i.children[1],s.children[0])).concat(o(e,r,n,t,i.children[1],s.children[1])):void 0:[]},verb.eval.mesh.make_mesh_aabb_tree=function(e,r,n){var t={bounding_box:verb.eval.mesh.make_mesh_aabb(e,r,n),children:[]};if(1===n.length)return t.triangle=n[0],t;var i=verb.eval.mesh.sort_tris_on_longest_axis(t.bounding_box,e,r,n),s=i.slice(0,Math.floor(i.length/2)),u=i.slice(Math.floor(i.length/2),i.length);return t.children=[verb.eval.mesh.make_mesh_aabb_tree(e,r,s),verb.eval.mesh.make_mesh_aabb_tree(e,r,u)],t},verb.eval.mesh.make_mesh_aabb=function(e,r,n){var t=new verb.geom.BoundingBox;return n.forEach(function(n){t.add(e[r[n][0]]),t.add(e[r[n][1]]),t.add(e[r[n][2]])}),t},verb.eval.mesh.sort_tris_on_longest_axis=function(e,r,n,t){for(var i=e.get_longest_axis(),s=[],u=t.length-1;u>=0;u--){var o=t[u],a=verb.eval.mesh.get_min_coordinate_on_axis(r,n[o],i);s.push([a,o])}s.sort(function(e,r){return e[0]>r[0]});for(var v=[],u=0,l=s.length;l>u;u++)v.push(s[u][1]);return v},verb.eval.mesh.get_min_coordinate_on_axis=function(e,r,n){for(var t=[],i=0;3>i;i++)t.push(e[r[i]][n]);return Math.min.apply(Math,t)},verb.eval.geom.get_tri_centroid=function(e,r){for(var n=[0,0,0],t=0;3>t;t++)for(var i=0;3>i;i++)n[i]+=e[r[t]][i];for(var t=0;3>t;t++)n[t]/=3;return n},verb.eval.geom.get_tri_norm=function(e,r){var n=e[r[0]],t=e[r[1]],i=e[r[2]],s=numeric.sub(t,n),u=numeric.sub(i,n),o=numeric.cross(s,u);return numeric.mul(1/numeric.norm2(o),o)},verb.eval.nurbs.intersect_rational_curves_by_aabb_refine=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.intersect_rational_curves_by_aabb(e,r,n,t,i,s,u,o);return a.map(function(u){return verb.eval.nurbs.refine_rational_curve_intersection(e,r,n,t,i,s,u)})},verb.eval.nurbs.refine_rational_curve_intersection=function(e,r,n,t,i,s,u){var o=function(u){var o=verb.eval.nurbs.rational_curve_point(e,r,n,u[0]),a=verb.eval.nurbs.rational_curve_point(t,i,s,u[1]),v=numeric.sub(o,a);return numeric.dot(v,v)},a=numeric.uncmin(o,u);return a.solution.concat(a.f)},verb.eval.nurbs.intersect_rational_curves_by_aabb=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.rational_curve_adaptive_sample(e,r,n,u,!0),v=verb.eval.nurbs.rational_curve_adaptive_sample(t,i,s,u,!0),l=a.map(function(e){return e[0]}),c=v.map(function(e){return e[0]}),b=a.map(function(e){return e.slice(1)}),h=v.map(function(e){return e.slice(1)});return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(b,h,l,c,o)},verb.eval.nurbs.intersect_parametric_polylines_by_aabb=function(e,r,n,t,i){var s=new verb.geom.BoundingBox(e),u=new verb.geom.BoundingBox(r);if(!s.intersects(u,i))return[];if(2!==e.length||2!==r.length){if(2===e.length){var o=Math.ceil(r.length/2),a=r.slice(0,o),v=r.slice(o-1),l=t.slice(0,o),c=t.slice(o-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,a,n,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(e,v,n,c,i))}if(2===r.length){var b=Math.ceil(e.length/2),h=e.slice(0,b),m=e.slice(b-1),_=n.slice(0,b),g=n.slice(b-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,r,_,t,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,r,g,t,i))}var b=Math.ceil(e.length/2),h=e.slice(0,b),m=e.slice(b-1),_=n.slice(0,b),g=n.slice(b-1),o=Math.ceil(r.length/2),a=r.slice(0,o),v=r.slice(o-1),l=t.slice(0,o),c=t.slice(o-1);return verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,a,_,l,i).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(h,v,_,c,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,a,g,l,i)).concat(verb.eval.nurbs.intersect_parametric_polylines_by_aabb(m,v,g,c,i))}var f=verb.eval.geom.intersect_segments(e[0],e[1],r[0],r[1],i);return null!=f?(f[0][0]=f[0][0]*(n[1]-n[0])+n[0],f[1][0]=f[1][0]*(t[1]-t[0])+t[0],[[f[0][0],f[1][0]]]):[]},verb.eval.geom.intersect_segments=function(e,r,n,t,i){var s=numeric.sub(r,e),u=Math.sqrt(numeric.dot(s,s)),o=numeric.mul(1/u,s),a=numeric.sub(t,n),v=Math.sqrt(numeric.dot(a,a)),l=numeric.mul(1/v,a),c=verb.eval.geom.intersect_rays(e,o,n,l);if(null!=c){var b=Math.min(Math.max(0,c[0]/u),1),h=Math.min(Math.max(0,c[1]/v),1),m=numeric.add(numeric.mul(b,s),e),_=numeric.add(numeric.mul(h,a),n),g=numeric.norm2Squared(numeric.sub(m,_));if(i*i>g)return[[b].concat(m),[h].concat(_)]}return null},verb.eval.geom.closest_point_on_ray=function(e,r,n){var t=numeric.sub(e,r),i=numeric.dot(t,n),s=numeric.add(r,numeric.mul(i,n));return s},verb.eval.geom.dist_to_ray=function(e,r,n){var t=verb.eval.geom.closest_point_on_ray(e,r,n),i=numeric.sub(t,e);return numeric.norm2(i)},verb.eval.geom.intersect_rays=function(e,r,n,t){var i=numeric.dot(r,t),s=numeric.dot(r,n),u=numeric.dot(r,e),o=numeric.dot(t,n),a=numeric.dot(t,e),v=numeric.dot(r,r),l=numeric.dot(t,t),c=v*l-i*i;if(Math.abs(c)z)break;var A=numeric.normalized(numeric.cross(_,k)),I=numeric.dot(A,m),C=verb.eval.geom.intersect_3_planes(_,d,k,E,A,I);if(null===C)throw Error("panic!");var R=numeric.sub(C,m),L=numeric.sub(C,y),O=numeric.cross(g,_),B=numeric.cross(f,_),T=numeric.cross(x,k),j=numeric.cross(N,k),D=numeric.dot(B,R)/numeric.dot(B,g),U=numeric.dot(O,R)/numeric.dot(O,f),q=numeric.dot(j,L)/numeric.dot(j,x),V=numeric.dot(T,L)/numeric.dot(T,N);e=numeric.add([D,U],e),r=numeric.add([q,V],r),M++}while(w>M);return{uv1:e,uv2:r,pt:m,d:z}},verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine=function(e,r,n,t,i,s,u,o,a,v,l){var c={degree_u:e,degree_v:n,knots_u:r,knots_v:t,homo_control_points:i},b=verb.eval.nurbs.tessellate_rational_surface_adaptive(c.degree_u,c.knots_u,c.degree_v,c.knots_v,c.homo_control_points),h={degree_u:s,degree_v:o,knots_u:u,knots_v:a,homo_control_points:v},m=verb.eval.nurbs.tessellate_rational_surface_adaptive(h.degree_u,h.knots_u,h.degree_v,h.knots_v,h.homo_control_points),_=verb.eval.mesh.intersect_meshes_by_aabb(b.points,b.faces,b.uvs,m.points,m.faces,m.uvs),g=_.map(function(c){return c.map(function(c){return verb.eval.nurbs.refine_rational_surface_intersect_point(c.uvtri1,c.uvtri2,e,r,n,t,i,s,u,o,a,v,l)})});return g.map(function(e){return verb.eval.nurbs.rational_interp_curve(e.map(function(e){return e.pt}),3)})},verb.eval.mesh.intersect_meshes_by_aabb=function(e,r,n,t,i,s){var u=verb.range(r.length),o=verb.range(i.length),a=verb.eval.mesh.make_mesh_aabb_tree(e,r,u),v=verb.eval.mesh.make_mesh_aabb_tree(t,i,o),l=verb.eval.geom.intersect_aabb_trees(e,r,t,i,a,v),c=l.map(function(u){var o=verb.eval.geom.intersect_tris(e,r[u[0]],n,t,i[u[1]],s);return o?(o[0].tri1id=u[0],o[1].tri1id=u[0],o[0].tri2id=u[1],o[1].tri2id=u[1],o):o}).filter(function(e){return e}).filter(function(e){var r=numeric.sub(e[0].pt,e[1].pt);return numeric.dot(r,r)>verb.EPSILON});return c=verb.unique(c,function(e,r){var n=numeric.sub(e[0].uvtri1,r[0].uvtri1),t=numeric.dot(n,n),i=numeric.sub(e[1].uvtri1,r[1].uvtri1),s=numeric.dot(i,i),u=numeric.sub(e[0].uvtri1,r[1].uvtri1),o=numeric.dot(u,u),a=numeric.sub(e[1].uvtri1,r[0].uvtri1),v=numeric.dot(a,a);return verb.EPSILON>t&&verb.EPSILON>s||verb.EPSILON>o&&verb.EPSILON>v}),0===c.length?[]:verb.eval.mesh.make_intersect_polylines(c)},verb.eval.mesh.make_intersect_polylines=function(e){e.forEach(function(e){e[1].opp=e[0],e[0].opp=e[1]});var r=verb.eval.mesh.kdtree_from_segs(e),n=e.flatten();n.forEach(function(n){if(!n.adj){var t=verb.eval.mesh.lookup_adj_segment(n,r,e.length);t&&!t.adj&&(n.adj=t,t.adj=n)}});var t=n.filter(function(e){return!e.adj});0===t.length&&(t=n);var i=[];return t.forEach(function(e){if(!e.v){for(var r=[],n=e;n;){if(n.v)throw Error("Segment end encountered twice!");if(n.v=!0,n.opp.v=!0,r.push(n),n=n.opp.adj,n===e)break}r.length>0&&(r.push(r[r.length-1].opp),i.push(r))}}),i},verb.eval.mesh.pt_dist=function(e,r){return Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2)+Math.pow(e.z-r.z,2)},verb.eval.mesh.kdtree_from_segs=function(e){var r=[];return e.forEach(function(e){r.push({x:e[0].pt[0],y:e[0].pt[1],z:e[0].pt[2],ele:e[0]}),r.push({x:e[1].pt[0],y:e[1].pt[1],z:e[1].pt[2],ele:e[1]})}),new KdTree(r,verb.eval.mesh.pt_dist,["x","y","z"])},verb.eval.mesh.lookup_adj_segment=function(e,r,n){var t=n?Math.min(n,3):3,i=r.nearest({x:e.pt[0],y:e.pt[1],z:e.pt[2]},t).filter(function(r){return e!=r[0].ele&&r[1]b;b++){var h=s[b],m=a[b],_=verb.eval.geom.intersect_rays(h,m,e,r);if(null!==_){var g=_[0],f=_[1];-verb.EPSILON>g||g>v[b]+verb.EPSILON||((null===l||l.u>f)&&(l={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[b],numeric.mul(g/v[b],u[b]))}),(null===c||f>c.u)&&(c={u:f,pt:verb.eval.geom.point_on_ray(e,r,f),uv:numeric.add(i[b],numeric.mul(g/v[b],u[b]))}))}}return null===c||null===l?null:{min:l,max:c}},verb.eval.geom.point_on_ray=function(e,r,n){return numeric.add(e,numeric.mul(n,r))},verb.eval.geom.merge_tri_clip_intervals=function(e,r,n,t,i,s,u,o){if(r.min.u>e.max.u+verb.EPSILON||e.min.u>r.max.u+verb.EPSILON)return null;e.min.tri=0,e.max.tri=0,r.min.tri=1,r.max.tri=1;var a=e.min.u>r.min.u?e.min:r.min,v=e.max.uu&&(s=1,u=o),a>u&&(s=2,u=a);var v,l,c,b;0===s?(v=r[1],l=r[2],c=t[1],b=t[2]):1===s?(v=r[0],l=r[2],c=t[0],b=t[2]):(v=r[0],l=r[1],c=t[0],b=t[1]);var h,m=-numeric.dot(e,r),_=-numeric.dot(n,t),g=v*b-l*c,f=(l*_-m*b)/g,d=(m*c-v*_)/g;return h=0===s?[0,f,d]:1===s?[f,0,d]:[f,d,0],{intersects:!0,origin:h,dir:numeric.normalized(i)}},verb.eval.geom.tri_uv_from_point=function(e,r,n,t){var i=e[r[0]],s=e[r[1]],u=e[r[2]],o=n[r[0]],a=n[r[1]],v=n[r[2]],l=numeric.sub(i,t),c=numeric.sub(s,t),b=numeric.sub(u,t),h=numeric.norm2(numeric.cross(numeric.sub(i,s),numeric.sub(i,u))),m=numeric.norm2(numeric.cross(c,b))/h,_=numeric.norm2(numeric.cross(b,l))/h,g=numeric.norm2(numeric.cross(l,c))/h;return numeric.add(numeric.mul(m,o),numeric.mul(_,a),numeric.mul(g,v))},verb.eval.nurbs.tessellate_rational_surface_naive=function(e,r,n,t,i,s,u){1>s&&(s=1),1>u&&(u=1);for(var o=r[r.length-1]-r[0],a=t[t.length-1]-t[0],v=o/s,l=a/u,c=[],b=[],h=[],m=0;s+1>m;m++)for(var _=0;u+1>_;_++){var g=m*v,f=_*l;b.push([g,f]);var d=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,g,f),p=d[0][0];c.push(p);var y=numeric.normalized(numeric.cross(d[0][1],d[1][0]));h.push(y)}for(var k=[],m=0;s>m;m++)for(var _=0;u>_;_++){var x=m*(u+1)+_,N=(m+1)*(u+1)+_,E=N+1,z=x+1,w=[x,N,E],M=[x,E,z];k.push(w),k.push(M)}return{points:c,faces:k,uvs:b,normals:h}},verb.eval.nurbs.rational_curve_regular_sample=function(e,r,n,t,i){return verb.eval.nurbs.rational_curve_regular_sample_range(e,r,n,0,1,t,i)},verb.eval.nurbs.rational_curve_regular_sample_range=function(e,r,n,t,i,s,u){1>s&&(s=2);for(var o=[],a=(i-t)/(s-1),v=0,l=0;s>l;l++)v=t+a*l,u?o.push([v].concat(verb.eval.nurbs.rational_curve_point(e,r,n,v))):o.push(verb.eval.nurbs.rational_curve_point(e,r,n,v));return o},verb.eval.nurbs.rational_curve_adaptive_sample=function(e,r,n,t,i){return 1===e?i?n.map(function(e,n){return[r[n+1]].concat(verb.eval.nurbs.dehomogenize(e))}):n.map(verb.eval.nurbs.dehomogenize):verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,r[0],r[r.length-1],t,i)},verb.eval.nurbs.rational_curve_adaptive_sample_range=function(e,r,n,t,i,s,u){var o=verb.eval.nurbs.rational_curve_point(e,r,n,t),a=verb.eval.nurbs.rational_curve_point(e,r,n,i),v=.5+.2*Math.random(),l=t+(i-t)*v,c=verb.eval.nurbs.rational_curve_point(e,r,n,l),b=numeric.sub(o,a),h=numeric.sub(o,c);if(s>numeric.dot(b,b)&&numeric.dot(h,h)>s||!verb.eval.nurbs.three_points_are_flat(o,c,a,s)){var m=t+.5*(i-t),_=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,t,m,s,u),g=verb.eval.nurbs.rational_curve_adaptive_sample_range(e,r,n,m,i,s,u);return _.slice(0,-1).concat(g)}return u?[[t].concat(o),[i].concat(a)]:[o,a]},verb.eval.nurbs.three_points_are_flat=function(e,r,n,t){var i=numeric.sub(r,e),s=numeric.sub(n,e),u=crossprod(i,s),o=numeric.dot(u,u);return t>o},verb.eval.nurbs.divide_rational_surface_adaptive=function(e,r,n,t,i,s){var u,o,a,v,l={degree_u:e,knots_u:r,degree_v:n,knots_v:t,homo_control_points:i};s=s||{},s.minDivsU=s.minDivsU||1,s.minDivsV=s.minDivsV||1,s.refine=void 0!=s.refine?s.refine:!0;var c=s.minDivsU=Math.max(s.minDivsU,3*(i.length-1)),b=s.minDivsV=Math.max(s.minDivsV,3*(i.length-1)),h=verb.last(r),m=r[0],_=verb.last(t),g=t[0],f=(h-m)/c,d=(_-g)/b,p=[],y=[];for(u=0,a=b+1;a>u;u++){var k=[];for(o=0,v=c+1;v>o;o++){var x=m+f*o,N=g+d*u,E=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,1,x,N),z=numeric.normalized(numeric.cross(E[0][1],E[1][0]));k.push(new verb.geom.SurfacePoint(E[0][0],z,[x,N],null,verb.isZero(z)))}y.push(k)}for(u=0;b>u;u++)for(o=0;c>o;o++){var w=[y[b-u-1][o],y[b-u-1][o+1],y[b-u][o+1],y[b-u][o]];p.push(new verb.eval.nurbs.AdaptiveRefinementNode(l,w))}if(!s.refine)return p;for(u=0;b>u;u++)for(o=0;c>o;o++){var M=u*c+o,S=verb.north(M,u,o,c,b,p),P=verb.east(M,u,o,c,b,p),A=verb.south(M,u,o,c,b,p),I=verb.west(M,u,o,c,b,p);p[M].neighbors=[A,P,S,I],p[M].divide(s)}return p},verb.north=function(e,r,n,t,i,s){return 0===r?null:s[e-t]},verb.south=function(e,r,n,t,i,s){return r===i-1?null:s[e+t]},verb.east=function(e,r,n,t,i,s){return n===t-1?null:s[e+1]},verb.west=function(e,r,n,t,i,s){return 0===n?null:s[e-1]},verb.eval.nurbs.triangulate_adaptive_refinement_node_tree=function(e){var r=verb.geom.TriMesh.empty();return e.forEach(function(e){e.triangulate(r)}),r},verb.eval.nurbs.tessellate_rational_surface_adaptive=function(e,r,n,t,i,s){var u=verb.eval.nurbs.divide_rational_surface_adaptive(e,r,n,t,i,s);return verb.eval.nurbs.triangulate_adaptive_refinement_node_tree(u)},verb.eval.nurbs.dist_to_seg=function(e,r,n){var t=numeric.sub(n,e),i=numeric.norm2(t),s=numeric.sub(r,e);if(verb.TOLERANCE>i)return numeric.norm2(s);var u=numeric.mul(1/i,t),o=numeric.dot(s,u),a=numeric.add(e,numeric.mul(o,u));return numeric.norm2(numeric.sub(a,r))},verb.geom.SurfacePoint=function(e,r,n,t,i){this.uv=n,this.point=e,this.normal=r,this.id=t,this.degen=i},verb.geom.SurfacePoint.fromUv=function(e,r){return new verb.geom.SurfacePoint(null,null,[e,r],null,null)},verb.geom.TriMesh=function(e,r,n,t){this.faces=e,this.points=r,this.uvs=n,this.normals=t},verb.geom.TriMesh.empty=function(){return new verb.geom.TriMesh([],[],[],[])},verb.eval.nurbs.AdaptiveRefinementNode=function(e,r,n,t){if(this.srf=e,this.parentNode=n,this.neighbors=t||[null,null,null,null],!r){var i=e?e.knots_u[0]:null,s=e?verb.last(e.knots_u):null,u=e?e.knots_v[0]:null,o=e?verb.last(e.knots_v):null;r=[verb.geom.SurfacePoint.fromUv(i,u),verb.geom.SurfacePoint.fromUv(s,u),verb.geom.SurfacePoint.fromUv(s,o),verb.geom.SurfacePoint.fromUv(i,o)]}this.corners=r},verb.eval.nurbs.AdaptiveRefinementNode.prototype.isLeaf=function(){return void 0===this.children},verb.eval.nurbs.AdaptiveRefinementNode.prototype.center=function(){return this.centerPoint||this.evalSrf(this.u05,this.v05)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalCorners=function(){this.u05=this.u05||(this.corners[0].uv[0]+this.corners[2].uv[0])/2,this.v05=this.v05||(this.corners[0].uv[1]+this.corners[2].uv[1])/2;for(var e=0;4>e;e++)if(!this.corners[e].point){var r=this.corners[e];this.evalSrf(r.uv[0],r.uv[1],r)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.evalSrf=function(e,r,n){var t=verb.eval.nurbs.rational_surface_derivs(this.srf.degree_u,this.srf.knots_u,this.srf.degree_v,this.srf.knots_v,this.srf.homo_control_points,1,e,r),i=t[0][0],s=numeric.cross(t[0][1],t[1][0]),u=verb.isZero(s);return u||(s=numeric.normalized(s)),n?(n.degen=u,n.point=i,n.normal=s,n):new verb.geom.SurfacePoint(i,s,[e,r],null,u)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getEdgeCorners=function(e){if(this.isLeaf())return[this.corners[e]];if(this.horizontal)switch(e){case 0:return this.children[0].getEdgeCorners(0);case 1:return this.children[0].getEdgeCorners(1).concat(this.children[1].getEdgeCorners(1));case 2:return this.children[1].getEdgeCorners(2);case 3:return this.children[1].getEdgeCorners(3).concat(this.children[0].getEdgeCorners(3))}switch(e){case 0:return this.children[0].getEdgeCorners(0).concat(this.children[1].getEdgeCorners(0));case 1:return this.children[1].getEdgeCorners(1);case 2:return this.children[1].getEdgeCorners(2).concat(this.children[0].getEdgeCorners(2));case 3:return this.children[0].getEdgeCorners(3)}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.getAllCorners=function(e){var r=[this.corners[e]];if(!this.neighbors[e])return r;var n=this.neighbors[e].getEdgeCorners((e+2)%4),t=e%2,i=verb.EPSILON,s=this,u=[function(e){return e.uv[0]>s.corners[0].uv[0]+i&&e.uv[0]s.corners[0].uv[1]+i&&e.uv[1]r;r++)if(Math.abs(e[r])>verb.TOLERANCE)return!1;return!0},verb.eval.nurbs.AdaptiveRefinementNode.prototype.hasBadNormals=function(){return this.corners[0].degen||this.corners[1].degen||this.corners[2].degen||this.corners[3].degen},verb.eval.nurbs.AdaptiveRefinementNode.prototype.fixNormals=function(){for(var e=0,r=this.corners.length;r>e;e++)if(this.corners[e],this.corners[e].degen){var n=this.corners[(e+1)%r],t=this.corners[(e+3)%r];this.corners[e].normal=n.degen?t.normal:n.normal}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide=function(e,r){if(e.minDepth>r)return!0;if(r>=e.maxDepth)return!1;if(this.hasBadNormals())return this.fixNormals(),!1;if(this.splitVert=numeric.norm2Squared(numeric.sub(this.corners[0].normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[2].normal,this.corners[3].normal))>e.normTol,this.splitHoriz=numeric.norm2Squared(numeric.sub(this.corners[1].normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(this.corners[3].normal,this.corners[0].normal))>e.normTol,this.splitVert||this.splitHoriz)return!0;var n=this.center();return numeric.norm2Squared(numeric.sub(n.normal,this.corners[0].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[1].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[2].normal))>e.normTol||numeric.norm2Squared(numeric.sub(n.normal,this.corners[3].normal))>e.normTol},verb.eval.nurbs.AdaptiveRefinementNode.prototype.divide=function(e){e=e||{},e.edgeTol=e.edgeTol||.1,e.normTol=e.normTol||.05,e.minDepth=void 0!=e.minDepth?e.minDepth:0,e.maxDepth=void 0!=e.maxDepth?e.maxDepth:10,this._divide(e,0,!0)},verb.eval.nurbs.AdaptiveRefinementNode.prototype._divide=function(e,r,n){if(this.evalCorners(),this.shouldDivide(e,r)){if(r++,this.splitVert&&!this.splitHoriz?n=!1:!this.splitVert&&this.splitHoriz&&(n=!0),this.horizontal=n,this.horizontal){var t=[this.corners[0],this.corners[1],this.midpoint(1),this.midpoint(3)],i=[this.midpoint(3),this.midpoint(1),this.corners[2],this.corners[3]];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,t,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,i,this)],this.children[0].neighbors=[this.neighbors[0],this.neighbors[1],this.children[1],this.neighbors[3]],this.children[1].neighbors=[this.children[0],this.neighbors[1],this.neighbors[2],this.neighbors[3]]}else{var s=[this.corners[0],this.midpoint(0),this.midpoint(2),this.corners[3]],u=[this.midpoint(0),this.corners[1],this.corners[2],this.midpoint(2)];this.children=[new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,s,this),new verb.eval.nurbs.AdaptiveRefinementNode(this.srf,u,this)],this.children[0].neighbors=[this.neighbors[0],this.children[1],this.neighbors[2],this.neighbors[3]],this.children[1].neighbors=[this.neighbors[0],this.neighbors[1],this.neighbors[2],this.children[0]]}this.children.forEach(function(t){t._divide(e,r,!n)})}},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulate=function(e){return e=e||verb.geom.TriMesh.empty(),this.isLeaf()?this.triangulateLeaf(e):(this.children.forEach(function(r){r&&r.triangulate(e)}),e)},verb.eval.nurbs.AdaptiveRefinementNode.prototype.triangulateLeaf=function(e){var r,n,t,i,s=e.points.length,u=[],o=[],a=0;for(a=0;4>a;a++){var v=this.getAllCorners(a);for(2===v.length&&(i=a+1),t=0;v.length>t;t++)u.push(v[t])}for(a=0,n=u.length;n>a;a++)r=u[a],void 0==r.id?(e.uvs.push(r.uv),e.points.push(r.point),e.normals.push(r.normal),r.id=s,o.push(s),s++):o.push(r.id);if(4===u.length)return e.faces.push([o[0],o[3],o[1]]),e.faces.push([o[3],o[2],o[1]]),e;if(5===u.length){var l=o.length;return e.faces.push([o[i],o[(i+1)%l],o[(i+2)%l]]),e.faces.push([o[(i+4)%l],o[(i+3)%l],o[i]]),e.faces.push([o[i],o[(i+2)%l],o[(i+3)%l]]),e}var c=this.center();e.uvs.push(c.uv),e.points.push(c.point),e.normals.push(c.normal);var b=e.points.length-1;for(a=0,t=u.length-1;u.length>a;t=a++)e.faces.push([b,o[t],o[a]]);return e},verb.eval.nurbs.rational_interp_curve=function(e,r){if(r=r||3,r+1>e.length)throw Error("You need to supply at least degree + 1 points!");for(var n=[0],t=1;e.length>t;t++){var i=numeric.norm2(numeric.sub(e[t],e[t-1])),s=n[n.length-1];n.push(s+i)}for(var u=n[n.length-1],t=0;n.length>t;t++)n[t]=n[t]/u;for(var o=numeric.rep([r+1],0),a=e.length-1,t=1,v=n.length-r;v>t;t++){for(var l=0,c=0;r>c;c++)l+=n[t+c];o.push(1/r*l)}for(var b=o.concat(numeric.rep([r+1],1)),h=[],t=0;n.length>t;t++){var m=n[t],_=verb.eval.nurbs.knot_span_given_n(a,r,m,b),g=verb.eval.nurbs.basis_functions_given_knot_span_index(_,m,r,b),f=_-r,d=verb.eval.nurbs.zeros_1d(f),p=verb.eval.nurbs.zeros_1d(e.length-(r+1)-f);h.push(d.concat(g).concat(p))}for(var y=e[0].length,k=[],t=0;y>t;t++){var x=e.map(function(e){return e[t]}),N=numeric.solve(h,x);k.push(N)}var E=numeric.transpose(k),z=numeric.rep([E.length],1);return{control_points:E,knots:b,degree:r,weights:z}},verb.eval.nurbs.get_sweep1_surface=function(e,r,n,t,i,s,u,o){for(var a=verb.eval.nurbs.homogenize_1d(u,o),v=verb.eval.nurbs.rational_curve_point(s,i,a,0),l=1/u.length,c=[],b=[],h=0;u.length>h;h++){for(var m=verb.eval.nurbs.rational_curve_point(s,i,a,h*l),_=numeric.sub(m,v),g=[],f=[],d=0;n.length>d;d++)g.push(numeric.add(_,n[d])),f.push(t[d]*o[h]);c.push(g),b.push(f)}return{knots_u:i,knots_v:e,control_points:c,degree_u:s,degree_v:r,weights:b}},verb.eval.nurbs.get_ellipse_arc=function(e,r,n,t,i,s,u){s>u&&(u=2*Math.PI+s);var o=u-s,a=0;a=Math.PI/2>=o?1:Math.PI>=o?2:3*Math.PI/2>=o?3:4;var v=o/a,l=Math.cos(v/2),c=numeric.add(e,numeric.mul(t,Math.cos(s),r),numeric.mul(i,Math.sin(s),n)),b=numeric.sub(numeric.mul(Math.cos(s),n),numeric.mul(Math.sin(s),r)),h=verb.eval.nurbs.zeros_1d(2*a),m=verb.eval.nurbs.zeros_1d(2*a+3),_=0,g=s,f=verb.eval.nurbs.zeros_1d(2*a);h[0]=c,f[0]=1;for(var d=1;a>=d;d++){g+=v;var p=numeric.add(e,numeric.mul(t,Math.cos(g),r),numeric.mul(i,Math.sin(g),n));f[_+2]=1,h[_+2]=p;var y=numeric.sub(numeric.mul(Math.cos(g),n),numeric.mul(Math.sin(g),r)),k=verb.eval.geom.intersect_rays(c,numeric.mul(1/numeric.norm2(b),b),p,numeric.mul(1/numeric.norm2(y),y)),x=numeric.add(c,numeric.mul(b,k[0]));f[_+1]=l,h[_+1]=x,_+=2,a>d&&(c=p,b=y)}for(var N=2*a+1,d=0;3>d;d++)m[d]=0,m[d+N]=1;switch(a){case 1:break;case 2:m[3]=m[4]=.5;break;case 3:m[3]=m[4]=1/3,m[5]=m[6]=2/3;break;case 4:m[3]=m[4]=.25,m[5]=m[6]=.5,m[7]=m[8]=.75}return{knots:m,control_points:h,degree:2,weights:f}},verb.eval.nurbs.get_sphere_surface=function(e,r,n,t){var i=verb.eval.nurbs.get_arc(e,numeric.mul(r,-1),n,t,0,Math.PI);return verb.eval.nurbs.get_revolved_surface(e,r,2*Math.PI,i.knots,i.degree,i.control_points,i.weights)},verb.eval.nurbs.get_polyline_curve=function(e){for(var r=e.length-1,n=1/r,t=[0,0],i=1;r>i;i++)t.push(i*n);t.push(1),t.push(1);for(var s=[],i=0;e.length>i;i++)s.push(1);return{knots:t,control_points:e.slice(0),degree:1,weights:s}},verb.eval.nurbs.get_4pt_surface=function(e,r,n,t){var i=numeric.mul(.5,numeric.add(e,t)),s=numeric.mul(.5,numeric.add(r,n)),u=numeric.mul(.5,numeric.add(n,t)),o=numeric.mul(.5,numeric.add(e,r)),a=numeric.mul(.5,numeric.add(i,s));return{knots_u:[0,0,0,1,1,1],knots_v:[0,0,0,1,1,1],control_points:[[e,i,t],[o,a,u],[r,s,n]],degree_u:2,degree_v:2,weights:[[1,1,1],[1,1,1],[1,1,1]]}},verb.eval.nurbs.get_cylinder_surface=function(e,r,n,t,i){var s=crossprod(e,r),u=(2*Math.PI,verb.eval.nurbs.get_arc(n,r,s,i,0,2*Math.PI));return verb.eval.nurbs.get_extruded_surface(e,t,u.knots,u.degree,u.control_points,u.weights)},verb.eval.nurbs.get_cone_surface=function(e,r,n,t,i){var s=2*Math.PI,u=1,o=[numeric.add(n,numeric.mul(t,e)),numeric.add(n,numeric.mul(i,r))],a=[0,0,1,1],v=[1,1];return verb.eval.nurbs.get_revolved_surface(n,e,s,a,u,o,v) +},verb.eval.nurbs.get_extruded_surface=function(e,r,n,t,i,s){for(var u=verb.eval.nurbs.zeros_2d(3,i.length),o=verb.eval.nurbs.zeros_2d(3,i.length),a=numeric.mul(e,r),v=numeric.mul(e,.5*r),l=0;i.length>l;l++)u[2][l]=i[l],u[1][l]=numeric.add(v,i[l]),u[0][l]=numeric.add(a,i[l]),o[0][l]=s[l],o[1][l]=s[l],o[2][l]=s[l];return{knots_u:[0,0,0,1,1,1],knots_v:n,control_points:u,degree_u:2,degree_v:t,weights:o}},verb.eval.nurbs.get_revolved_surface=function(e,r,n,t,i,s,u){var o,a,v,l;Math.PI/2>=n?(o=1,a=verb.eval.nurbs.zeros_1d(6+2*(o-1))):Math.PI>=n?(o=2,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=.5):3*Math.PI/2>=n?(o=3,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=1/3,a[5]=a[6]=2/3):(o=4,a=verb.eval.nurbs.zeros_1d(6+2*(o-1)),a[3]=a[4]=.25,a[5]=a[6]=.5,a[7]=a[8]=.75);for(var c=n/o,b=3+2*(o-1),h=0;3>h;b++,h++)a[h]=0,a[b]=1;for(var m=Math.cos(c/2),_=0,g=verb.eval.nurbs.zeros_1d(o+1),f=verb.eval.nurbs.zeros_1d(o+1),v=verb.eval.nurbs.zeros_2d(2*o+1,s.length),l=verb.eval.nurbs.zeros_2d(2*o+1,s.length),h=1;o>=h;h++)_+=c,f[h]=Math.cos(_),g[h]=Math.sin(_);for(b=0;s.length>b;b++){var d=verb.eval.geom.closest_point_on_ray(s[b],e,r),p=numeric.sub(s[b],d),y=numeric.norm2(p),k=crossprod(r,p);y>verb.EPSILON&&(p=numeric.mul(1/y,p),k=numeric.mul(1/y,k)),v[0][b]=s[b];var x=s[b];l[0][b]=u[b];for(var N=k,E=0,_=0,h=1;o>=h;h++){var z=0==y?d:numeric.add(d,numeric.mul(y,f[h],p),numeric.mul(y,g[h],k));v[E+2][b]=z,l[E+2][b]=u[b];var w=numeric.sub(numeric.mul(f[h],k),numeric.mul(g[h],p));if(0==y)v[E+1][b]=d;else{var M=verb.eval.geom.intersect_rays(x,numeric.mul(1/numeric.norm2(N),N),z,numeric.mul(1/numeric.norm2(w),w)),S=numeric.add(x,numeric.mul(N,M[0]));v[E+1][b]=S}l[E+1][b]=m*u[b],E+=2,o>h&&(x=z,N=w)}}return{knots_u:a,knots_v:t,control_points:v,degree_u:2,degree_v:i,weights:l}},verb.eval.nurbs.get_arc=function(e,r,n,t,i,s){return verb.eval.nurbs.get_ellipse_arc(e,r,n,t,t,i,s)},verb.eval.nurbs.curve_bezier_decompose=function(e,r,n){for(var t=verb.eval.nurbs.knot_multiplicities(r),i=e+1,s=verb.eval.nurbs.curve_knot_refine,u=0;t.length>u;u++)if(i>t[u][1]){var o=numeric.rep([i-t[u][1]],t[u][0]),a=s(e,r,n,o);r=a.knots,n=a.control_points}r.length/i-1;for(var v=2*i,l=[],u=0;n.length>u;u+=i){var c=r.slice(u,u+v),b=n.slice(u,u+i);l.push({degree:e,knots:c,control_points:b})}return l},verb.eval.nurbs.knot_multiplicities=function(e){for(var r=[[e[0],0]],n=r[0],t=0;e.length>t;t++)Math.abs(e[t]-n[0])>verb.EPSILON&&(n=[e[t],0],r.push(n)),n[1]++;return r},verb.eval.nurbs.curve_split=function(e,r,n,t){for(var i=[],s=0;e+1>s;s++)i.push(t);var u=verb.eval.nurbs.curve_knot_refine(e,r,n,i),o=verb.eval.nurbs.knot_span(e,t,r),a=u.knots.slice(0,o+e+2),v=u.knots.slice(o+1),l=u.control_points.slice(0,o+1),c=u.control_points.slice(o+1);return[{degree:e,knots:a,control_points:l},{degree:e,knots:v,control_points:c}]},verb.eval.nurbs.curve_knot_refine=function(e,r,n,t){var i=n.length-1,s=i+e+1,u=t.length-1,o=verb.eval.nurbs.knot_span(e,t[0],r),a=verb.eval.nurbs.knot_span(e,t[u],r),v=Array(n.length+u+1),l=Array(r.length+u+1),c=0,b=0;for(c=0;o-e>=c;c++)v[c]=n[c];for(c=a-1;i>=c;c++)v[c+u+1]=n[c];for(c=0;o>=c;c++)l[c]=r[c];for(c=a+e;s>=c;c++)l[c+u+1]=r[c];c=a+e-1;var h=a+e+u;for(b=u;b>=0;b--){for(;t[b]<=r[c]&&c>o;)v[h-e-1]=n[c-e-1],l[h]=r[c],h-=1,c-=1;v[h-e-1]=v[h-e];for(var m=1;e>=m;m++){var _=h-e+m,g=l[h+m]-t[b];Math.abs(g)=b;b++)l[b]=r[b];for(b=1;i>=b;b++)l[o+b]=t;for(b=o+1;r.length>b;b++)l[b+i]=r[b];for(b=0;o-e>=b;b++)c[b]=n[b];for(b=o-s;u>b;b++)c[b+i]=n[b];for(b=0;e-s>=b;b++)v[b]=n[o-e+b];for(var h=0,m=0,_=1;i>=_;_++){for(h=o-e+_,b=0;e-_-s>=b;b++)m=(t-r[h+b])/(r[b+o+1]-r[h+b]),v[b]=numeric.add(numeric.mul(m,v[b+1]),numeric.mul(1-m,v[b]));c[h]=v[0],c[o+i-_-s]=v[e-_-s]}for(b=h+1;o-s>b;b++)c[b]=v[b-h];return{knots:l,control_points:c}},verb.eval.nurbs.rational_surface_curvature=function(e,r,n,t,i,s,u){var o=verb.eval.nurbs.rational_surface_derivs(e,r,n,t,i,2,s,u),a=o[0][1],v=o[1][0],l=o[0][2],c=o[2][0],b=o[1][1],h=numeric.cross(a,v),m=numeric.dot(l,h),_=numeric.dot(b,h),g=numeric.dot(c,h),f=[[m,_],[_,g]],d=numeric.eig(f),p=d.lambda.x[0],y=d.lambda.x[1],k=.5*(p+y),x=p*y,N=numeric.add(numeric.mul(d.E.x[0][0],a),numeric.mul(d.E.x[0][1],v)),E=numeric.add(numeric.mul(d.E.x[1][0],a),numeric.mul(d.E.x[1][1],v));return{point:o[0][0],normal:h,mean:k,gaussian:x,shapeOperator:f,k1:p,k2:y,p1:N,p2:E,p1p:d.E.x[0],p2p:d.E.x[1]}},verb.eval.nurbs.rational_surface_derivs=function(e,r,n,t,i,s,u,o){var a=verb.eval.nurbs.surface_derivs(e,r,n,t,i,s,u,o),v=verb.eval.nurbs.separate_homo_derivs_2d(a),l=v[0],c=v[1],b=0,h=0,m=0,_=0,g=[],f=l[0][0].length;for(b=0;s>=b;b++)for(g.push([]),_=0;s-b>=_;_++){var o=l[b][_];for(m=1;_>=m;m++)o=numeric.sub(o,numeric.mul(numeric.mul(binomial.get(_,m),c[0][m]),g[b][_-m]));for(h=1;b>=h;h++){o=numeric.sub(o,numeric.mul(numeric.mul(binomial.get(b,h),c[h][0]),g[b-h][_]));var d=verb.eval.nurbs.zeros_1d(f);for(m=1;_>=m;m++)d=numeric.add(d,numeric.mul(numeric.mul(binomial.get(_,m),c[h][m]),g[b-h][_-m]));o=numeric.sub(o,numeric.mul(binomial.get(b,h),d))}g[b].push(numeric.mul(1/c[0][0],o))}return g},verb.eval.nurbs.rational_surface_point=function(e,r,n,t,i,s,u){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.surface_point(e,r,n,t,i,s,u))},verb.eval.nurbs.rational_curve_derivs=function(e,r,n,t,i){var s=verb.eval.nurbs.separate_homo_derivs_1d(verb.eval.nurbs.curve_derivs(e,r,n,t,i)),u=s[0],o=s[1],a=0,v=0,l=[];for(a=0;i>=a;a++){var c=u[a];for(v=1;a>=v;v++)c=numeric.sub(c,numeric.mul(numeric.mul(binomial.get(a,v),o[v]),l[a-v]));l.push(numeric.mul(1/o[0],c))}return l},verb.eval.nurbs.separate_homo_derivs_1d=function(e){for(var r=e[0].length,n=r-1,t=[],i=[],s=0,u=e.length;u>s;s++)t.push(e[s].slice(0,n)),i.push(e[s][n]);return[t,i]},verb.eval.nurbs.separate_homo_derivs_2d=function(e){for(var r=[],n=[],t=0,i=e.length;i>t;t++){var s=verb.eval.nurbs.separate_homo_derivs_1d(e[t]);r.push(s[0]),n.push(s[1])}return[r,n]},verb.eval.nurbs.rational_curve_point=function(e,r,n,t){return verb.eval.nurbs.dehomogenize(verb.eval.nurbs.curve_point(e,r,n,t))},verb.eval.nurbs.dehomogenize=function(e){for(var r=e.length,n=[],t=e[r-1],i=0;e.length-1>i;i++)n.push(e[i]/t);return n},verb.eval.nurbs.weight_1d=function(e){var r=e[0].length-1;return e.map(function(e){return e[r]})},verb.eval.nurbs.dehomogenize_1d=function(e){return e.map(function(e){return verb.eval.nurbs.dehomogenize(e)})},verb.eval.nurbs.homogenize_1d=function(e,r){for(var n=e.length,t=e[0].length,i=0,s=[],u=0,o=[],a=0;n>a;a++){var v=[];for(o=e[a],u=r[a],i=0;t>i;i++)v.push(o[i]*u);v.push(u),s.push(v)}return s},verb.eval.nurbs.homogenize_2d=function(e,r){for(var n=e.length,t=(e[0].length,e[0][0].length,[]),i=0;n>i;i++)t.push(verb.eval.nurbs.homogenize_1d(e[i],r[i]));return t},verb.eval.nurbs.surface_derivs=function(e,r,n,t,i,s,u,o){var a=r.length-e-2,v=t.length-n-2;return verb.eval.nurbs.surface_derivs_given_n_m(a,e,r,v,n,t,i,s,u,o)},verb.eval.nurbs.surface_derivs_given_n_m=function(e,r,n,t,i,s,u,o,a,v){if(verb.eval.nurbs.are_valid_relations(r,u.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,u[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var l=u[0][0].length,c=Math.min(o,r),b=Math.min(o,i),h=verb.eval.nurbs.zeros_3d(c+1,b+1,l),m=verb.eval.nurbs.knot_span_given_n(e,r,a,n),_=verb.eval.nurbs.knot_span_given_n(t,i,v,s),g=verb.eval.nurbs.deriv_basis_functions_given_n_i(m,a,r,e,n),f=verb.eval.nurbs.deriv_basis_functions_given_n_i(_,v,i,t,s),d=verb.eval.nurbs.zeros_2d(i+1,l),p=0,y=0,k=0,x=0,N=0;for(p=0;c>=p;p++){for(y=0;i>=y;y++)for(d[y]=verb.eval.nurbs.zeros_1d(l),k=0;r>=k;k++)d[y]=numeric.add(d[y],numeric.mul(g[p][k],u[m-r+k][_-i+y]));for(N=Math.min(o-p,b),x=0;N>=x;x++)for(h[p][x]=verb.eval.nurbs.zeros_1d(l),y=0;i>=y;y++)h[p][x]=numeric.add(h[p][x],numeric.mul(f[x][y],d[y]))}return h},verb.eval.nurbs.surface_point=function(e,r,n,t,i,s,u){var o=r.length-e-2,a=t.length-n-2;return verb.eval.nurbs.surface_point_given_n_m(o,e,r,a,n,t,i,s,u)},verb.eval.nurbs.volume_point=function(e,r,n,t,i,s,u,o,a,v){var l=r.length-e-2,c=t.length-n-2,b=s.length-i-2;return verb.eval.nurbs.volume_point_given_n_m_l(l,e,r,c,n,t,b,i,s,u,o,a,v)},verb.eval.nurbs.volume_point_given_n_m_l=function(e,r,n,t,i,s,u,o,a,v,l,c,b){if(!verb.eval.nurbs.are_valid_relations(r,v.length,n.length)||!verb.eval.nurbs.are_valid_relations(i,v[0].length,s.length)||!verb.eval.nurbs.are_valid_relations(o,v[0][0].length,a.length))return console.error("Invalid relations between control points and knot vector"),null;for(var h=v[0][0][0].length,m=verb.eval.nurbs.knot_span_given_n(e,r,l,n),_=verb.eval.nurbs.knot_span_given_n(t,i,c,s),g=verb.eval.nurbs.knot_span_given_n(u,o,b,a),f=verb.eval.nurbs.basis_functions_given_knot_span_index(m,l,r,n),d=verb.eval.nurbs.basis_functions_given_knot_span_index(_,c,i,s),p=verb.eval.nurbs.basis_functions_given_knot_span_index(g,b,o,a),y=m-r,k=_,x=g,N=verb.eval.nurbs.zeros_1d(h),E=verb.eval.nurbs.zeros_1d(h),z=verb.eval.nurbs.zeros_1d(h),w=0,M=0,S=0;o>=S;S++){for(z=verb.eval.nurbs.zeros_1d(h),x=g-o+S,w=0;i>=w;w++){for(E=verb.eval.nurbs.zeros_1d(h),k=_-i+w,M=0;r>=M;M++)E=numeric.add(E,numeric.mul(f[M],v[y+M][k][x]));z=numeric.add(z,numeric.mul(d[w],E))}N=numeric.add(N,numeric.mul(p[S],z))}return N},verb.eval.nurbs.surface_point_given_n_m=function(e,r,n,t,i,s,u,o,a){if(verb.eval.nurbs.are_valid_relations(r,u.length,n.length)===!1||verb.eval.nurbs.are_valid_relations(i,u[0].length,s.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var v=u[0][0].length,l=verb.eval.nurbs.knot_span_given_n(e,r,o,n),c=verb.eval.nurbs.knot_span_given_n(t,i,a,s),b=verb.eval.nurbs.basis_functions_given_knot_span_index(l,o,r,n),h=verb.eval.nurbs.basis_functions_given_knot_span_index(c,a,i,s),m=l-r,_=c,g=verb.eval.nurbs.zeros_1d(v),f=verb.eval.nurbs.zeros_1d(v),d=0,p=0;for(d=0;i>=d;d++){for(f=verb.eval.nurbs.zeros_1d(v),_=c-i+d,p=0;r>=p;p++)f=numeric.add(f,numeric.mul(b[p],u[m+p][_]));g=numeric.add(g,numeric.mul(h[d],f))}return g},verb.eval.nurbs.curve_derivs=function(e,r,n,t,i){var s=r.length-e-2;return verb.eval.nurbs.curve_derivs_given_n(s,e,r,n,t,i)},verb.eval.nurbs.curve_derivs_given_n=function(e,r,n,t,i,s){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;var u=t[0].length,o=Math.min(s,r),a=verb.eval.nurbs.zeros_2d(o+1,u),v=verb.eval.nurbs.knot_span_given_n(e,r,i,n),l=verb.eval.nurbs.deriv_basis_functions_given_n_i(v,i,r,o,n),c=0,b=0;for(c=0;o>=c;c++)for(b=0;r>=b;b++)a[c]=numeric.add(a[c],numeric.mul(l[c][b],t[v-r+b]));return a},verb.eval.nurbs.are_valid_relations=function(e,r,n){return 0===r+e+1-n?!0:!1},verb.eval.nurbs.curve_point=function(e,r,n,t){var i=r.length-e-2;return verb.eval.nurbs.curve_point_given_n(i,e,r,n,t)},verb.eval.nurbs.curve_point_given_n=function(e,r,n,t,i){if(verb.eval.nurbs.are_valid_relations(r,t.length,n.length)===!1)return console.error("Invalid relations between control points, knot vector, and n"),null;for(var s=verb.eval.nurbs.knot_span_given_n(e,r,i,n),u=verb.eval.nurbs.basis_functions_given_knot_span_index(s,i,r,n),o=verb.eval.nurbs.zeros_1d(t[0].length),a=0;r>=a;a++)o=numeric.add(o,numeric.mul(u[a],t[s-r+a]));return o},verb.eval.nurbs.zeros_1d=function(e){return numeric.rep([e],0)},verb.eval.nurbs.zeros_2d=function(e,r){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r],0)},verb.eval.nurbs.zeros_3d=function(e,r,n){return r=r>0?r:0,e=e>0?e:0,numeric.rep([e,r,n],0)},verb.eval.nurbs.deriv_basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(r,e,n),i=n.length-1,s=i-r-1;return verb.eval.nurbs.deriv_basis_functions_given_n_i(t,e,r,s,n)},verb.eval.nurbs.deriv_basis_functions_given_n_i=function(e,r,n,t,i){var s=verb.eval.nurbs.zeros_2d(n+1,n+1),u=Array(n+1),o=Array(n+1),a=0,v=0,l=1,c=0;for(s[0][0]=1,l=1;n>=l;l++){for(u[l]=r-i[e+1-l],o[l]=i[e+l]-r,a=0,c=0;l>c;c++)s[l][c]=o[c+1]+u[l-c],v=s[c][l-1]/s[l][c],s[c][l]=a+o[c+1]*v,a=u[l-c]*v;s[l][l]=a}var b=verb.eval.nurbs.zeros_2d(t+1,n+1),h=verb.eval.nurbs.zeros_2d(2,n+1),m=1,_=0,g=1,f=0,d=0,p=0,y=0,k=0;for(l=0;n>=l;l++)b[0][l]=s[l][n];for(c=0;n>=c;c++)for(_=0,g=1,h[0][0]=1,m=1;t>=m;m++){for(f=0,d=c-m,p=n-m,c>=m&&(h[g][0]=h[_][0]/s[p+1][d],f=h[g][0]*s[d][p]),y=d>=-1?1:-d,k=p>=c-1?m-1:n-c,l=y;k>=l;l++)h[g][l]=(h[_][l]-h[_][l-1])/s[p+1][d+l],f+=h[g][l]*s[d+l][p];p>=c&&(h[g][m]=-h[_][m-1]/s[p+1][c],f+=h[g][m]*s[c][p]),b[m][c]=f,l=_,_=g,g=l}for(c=n,m=1;t>=m;m++){for(l=0;n>=l;l++)b[m][l]*=c;c*=n-m}return b},verb.eval.nurbs.basis_functions=function(e,r,n){var t=verb.eval.nurbs.knot_span(e,r,n);return verb.eval.nurbs.basis_functions_given_knot_span_index(t,e,r,n)},verb.eval.nurbs.basis_functions_given_knot_span_index=function(e,r,n,t){var i=Array(n+1),s=Array(n+1),u=Array(n+1),o=0,a=0;i[0]=1;for(var v=1;n>=v;v++){s[v]=r-t[e+1-v],u[v]=t[e+v]-r,o=0;for(var l=0;v>l;l++)a=i[l]/(u[l+1]+s[v-l]),i[l]=o+u[l+1]*a,o=s[v-l]*a;i[v]=o}return i},verb.eval.nurbs.knot_span=function(e,r,n){var t=n.length-1,i=t-e-1;return verb.eval.nurbs.knot_span_given_n(i,e,r,n)},verb.eval.nurbs.knot_span_given_n=function(e,r,n,t){if(n>=t[e+1])return e;if(t[r]>n)return r;for(var i=r,s=e+1,u=Math.floor((i+s)/2);t[u]>n||n>=t[u+1];)t[u]>n?s=u:i=u,u=Math.floor((i+s)/2);return u}; \ No newline at end of file diff --git a/docs/verb.html b/docs/verb.html index 84d02ac5..97b5d033 100644 --- a/docs/verb.html +++ b/docs/verb.html @@ -93,7 +93,7 @@

verb.EPSILON

-
verb.EPSILON = 1e-8;
+
verb.EPSILON = 1e-10;
@@ -5990,14 +5990,12 @@

intersect_rays( a0, a, b0, b )

-
	var tessOptions = { minDivsU: 20, minDivsV: 20, tol: 5e-2 };
-
+            
 	var tess1 = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj1.degree_u,
 		srfObj1.knots_u,
 		srfObj1.degree_v,
 		srfObj1.knots_v, 
-		srfObj1.homo_control_points, 
-		tessOptions );
+		srfObj1.homo_control_points);
 
 	var srfObj2 = {
 		degree_u : degree_u2,
@@ -6011,8 +6009,7 @@ 

intersect_rays( a0, a, b0, b )

srfObj2.knots_u, srfObj2.degree_v, srfObj2.knots_v, - srfObj2.homo_control_points, - tessOptions ); + srfObj2.homo_control_points); var resApprox = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, tess1.uvs, tess2.points, tess2.faces, tess2.uvs );
@@ -6050,7 +6047,7 @@

intersect_rays( a0, a, b0, b )

	return exactPls.map(function(x){
-		return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 2 ); 
+		return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 3 ); 
 	});
@@ -6128,11 +6125,10 @@

intersect_rays( a0, a, b0, b )

res[1].tri2id = ids[1]; return res; - }) - .filter(function(x){ return x; }) + }).filter(function(x){ return x; }) .filter(function(x){ var dif = numeric.sub( x[0].pt, x[1].pt ); - return numeric.dot( dif, dif ) > verb.TOLERANCE + return numeric.dot( dif, dif ) > verb.EPSILON });
@@ -6164,8 +6160,8 @@

intersect_rays( a0, a, b0, b )

var s4 = numeric.sub( a[1].uvtri1, b[0].uvtri1 ); var d4 = numeric.dot( s4, s4 ); - return ( d1 < verb.TOLERANCE && d2 < verb.TOLERANCE ) || - ( d3 < verb.TOLERANCE && d4 < verb.TOLERANCE ); + return ( d1 < verb.EPSILON && d2 < verb.EPSILON ) || + ( d3 < verb.EPSILON && d4 < verb.EPSILON ); }); @@ -6452,7 +6448,7 @@

intersect_rays( a0, a, b0, b )

	var adj = tree.nearest({ x: segEnd.pt[0], y: segEnd.pt[1], z: segEnd.pt[2] }, numResults)
 								.filter(function(r){ 
-									return segEnd != r[0].ele && r[1] < verb.TOLERANCE;
+									return segEnd != r[0].ele && r[1] < verb.EPSILON;
 								})
 								.map(function(r){ return r[0].ele; });
@@ -8199,39 +8195,8 @@

three_points_are_flat( p1, p2, p3, numeric.norm2Squared( numeric.sub( this.corners[2].normal, this.corners[3].normal ) ) > options.normTol; this.splitHoriz = numeric.norm2Squared( numeric.sub( this.corners[1].normal, this.corners[2].normal ) ) > options.normTol || - numeric.norm2Squared( numeric.sub( this.corners[3].normal, this.corners[0].normal ) ) > options.normTol; - - - - -
  • -
    - -
    - -
    -

    is curved in u direction? -this.splitVert = verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[0].point, this.corners[1].point ) > options.edgeTol || - verb.eval.nurbs.dist_to_seg( this.corners[2].point, this.midpoints[2].point, this.corners[3].point ) > options.edgeTol;

    - -
    - -
  • - - -
  • -
    - -
    - -
    -

    // is curved in v direction? -this.splitHoriz = verb.eval.nurbs.dist_to_seg( this.corners[1].point, this.midpoints[1].point, this.corners[2].point ) > options.edgeTol || - verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[3].point, this.corners[3].point ) > options.edgeTol;

    + numeric.norm2Squared( numeric.sub( this.corners[3].normal, this.corners[0].normal ) ) > options.normTol; -
    - -
     	if ( this.splitVert || this.splitHoriz ) return true;
     
     	var center = this.center();
    @@ -8265,11 +8230,11 @@ 

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    is the quad flat in one dir and curved in the other?

    @@ -8294,11 +8259,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    assign neighbors to bottom node

    @@ -8309,11 +8274,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    assign neighbors to top node

    @@ -8337,11 +8302,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    divide all children recursively

    @@ -8360,11 +8325,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    recurse on the children

    @@ -8393,11 +8358,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    enumerate all uvs in counter clockwise direction

    @@ -8410,11 +8375,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    this is the vertex that is split

    @@ -8432,11 +8397,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    if the id is defined, we can just push it and continue

    @@ -8462,11 +8427,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    if the number of points is 4, we’re just doing a rectangle - just build the basic triangulated square

    @@ -8479,11 +8444,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    all done

    @@ -8496,11 +8461,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    use the splitcorner to triangulate

    @@ -8511,11 +8476,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    there will be 3 triangles

    @@ -8540,11 +8505,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    make point at center of face

    @@ -8559,11 +8524,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    get index

    @@ -8574,11 +8539,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    build triangle fan from center

    @@ -8595,11 +8560,11 @@

    three_points_are_flat( p1, p2, p3,

  • -
  • +
  • - +

    verb.eval

    This defines verb’s core geometry library which is called by the current Engine.

    @@ -8612,11 +8577,11 @@

    verb.eval

  • -
  • +
  • - +

    0) build knot vector for curve by normalized chord length 1) construct effective basis function in square matrix (W) @@ -8628,11 +8593,11 @@

    verb.eval

  • -
  • +
  • - +

    Wc = p

    @@ -8641,11 +8606,11 @@

    verb.eval

  • -
  • +
  • - +

    4) solve for c in all 3 dimensions

    @@ -8670,11 +8635,11 @@

    verb.eval

  • -
  • +
  • - +

    normalize

    @@ -8706,11 +8671,11 @@

    verb.eval

  • -
  • +
  • - +

    build matrix of basis function coeffs (TODO: use sparse rep)

    @@ -8735,11 +8700,11 @@

    verb.eval

  • -
  • +
  • - +

    for each dimension, solve

    @@ -8765,11 +8730,11 @@

    verb.eval

  • -
  • +
  • - +

    get_sweep1_surface( profile_knots, profile_degree, profile_control_points, profile_weights, rail_knots, rail_degree, rail_control_points, rail_weights )

    Generate the control points, weights, and knots of an elliptical arc

    @@ -8795,11 +8760,11 @@

    +
  • - +

    for each point on rail, move all of the points

    @@ -8816,11 +8781,11 @@

    +
  • - +

    evaluate the point on the curve, subtracting it from the first point

    @@ -8854,11 +8819,11 @@

    +
  • - +

    get_ellipse_arc( center, xaxis, yaxis, xradius, yradius, start_angle, end_angle )

    Generate the control points, weights, and knots of an elliptical arc

    @@ -8885,11 +8850,11 @@

    +
  • - +

    if the end angle is less than the start angle, do a circle

    @@ -8903,11 +8868,11 @@

    +
  • - +

    how many arcs?

    @@ -8987,11 +8952,11 @@

    +
  • - +

    get_sphere_surface( center, axis, xaxis, radius )

    Generate the control points, weights, and knots of a sphere

    @@ -9021,11 +8986,11 @@

    get_sphere_surface( center

  • -
  • +
  • - +

    get_polyline_curve( pts )

    Generate the control points, weights, and knots of a polyline curve

    @@ -9072,11 +9037,11 @@

    get_polyline_curve( pts )

  • -
  • +
  • - +

    get_4pt_surface( p1, p2, p3, p4 )

    Generate the control points, weights, and knots of a surface define by 3 points

    @@ -9119,11 +9084,11 @@

    get_4pt_surface( p1, p2, p3, p4 )

  • -
  • +
  • - +

    get_cylinder_surface( axis, xaxis, base, height, radius )

    Generate the control points, weights, and knots of a cylinder

    @@ -9156,11 +9121,11 @@

    get_cylinder_surfac

  • -
  • +
  • - +

    get_cone_surface( axis, xaxis, base, height, radius )

    Generate the control points, weights, and knots of a cone

    @@ -9194,11 +9159,11 @@

    get_cone_surface( axis,

  • -
  • +
  • - +

    get_extruded_surface( axis, length, prof_knots, prof_degree, prof_control_points, prof_weights)

    Generate the control points, weights, and knots of an extruded surface

    @@ -9229,11 +9194,11 @@

    +
  • - +

    original control points

    @@ -9252,11 +9217,11 @@

    +
  • - +

    return all parameters

    @@ -9273,11 +9238,11 @@

    +
  • - +

    get_revolved_surface( center, axis, theta, prof_knots, prof_degree, prof_control_points, prof_weights)

    Generate the control points, weights, and knots of a revolved surface @@ -9301,11 +9266,11 @@

    +
  • - +

    helper method

    @@ -9348,11 +9313,11 @@

    +
  • - +

    initialize the start and end knots keep in mind that we only return the knot vector for the

    @@ -9368,11 +9333,11 @@

    +
  • - +

    do some initialization

    @@ -9389,11 +9354,11 @@

    +
  • - +

    initialize the sines and cosines

    @@ -9408,11 +9373,11 @@

    +
  • - +

    for each pt in the generatrix i.e. for each row of the 2d knot vectors

    @@ -9424,11 +9389,11 @@

    +
  • - +

    get the closest point of the generatrix point on the axis

    @@ -9439,11 +9404,11 @@

    +
  • - +

    X is the vector from the axis to generatrix control pt

    @@ -9454,11 +9419,11 @@

    +
  • - +

    radius at that height

    @@ -9469,11 +9434,11 @@

    +
  • - +

    Y is perpendicular to X and axis, and complete the coordinate system

    @@ -9489,11 +9454,11 @@

    +
  • - +

    the first row of control_points and weights is just the generatrix

    @@ -9506,11 +9471,11 @@

    +
  • - +

    store T0 as the Y vector

    @@ -9523,11 +9488,11 @@

    +
  • - +

    proceed around the circle

    @@ -9538,11 +9503,11 @@

    +
  • - +

    O + r cos(theta) X + r sin(theta) Y rotated generatrix pt

    @@ -9557,11 +9522,11 @@

    +
  • - +

    construct the vector tangent to the rotation

    @@ -9572,11 +9537,11 @@

    +
  • - +

    construct the next control pt

    @@ -9607,11 +9572,11 @@

    +
  • - +

    store all of the parameters

    @@ -9629,11 +9594,11 @@

    +
  • - +

    get_arc( center, xaxis, yaxis, radius, start_angle, end_angle )

    Generate the control points, weights, and knots of an arbitrary arc @@ -9664,11 +9629,11 @@

    get_arc( cente

  • -
  • +
  • - +

    curve_bezier_decompose( degree, knots, control_points )

    Decompose a NURBS curve into a collection of bezier’s. Useful @@ -9692,11 +9657,11 @@

    curve_bezier_decomp

  • -
  • +
  • - +

    find all of the unique knot values and their multiplicity for each, increase their multiplicity to degree + 1

    @@ -9711,11 +9676,11 @@

    curve_bezier_decomp

  • -
  • +
  • - +

    insert the knots

    @@ -9754,11 +9719,11 @@

    curve_bezier_decomp

  • -
  • +
  • - +

    knot_multiplicities( knots )

    Determine the multiplicities of the values in a knot vector

    @@ -9778,11 +9743,11 @@

    knot_multiplicities( knots )

  • -
  • +
  • - +

    initialize

    @@ -9811,11 +9776,11 @@

    knot_multiplicities( knots )

  • -
  • +
  • - +

    curve_split( degree, knots, control_points, u )

    Split a curve into two parts

    @@ -9857,11 +9822,11 @@

    curve_split( degree, knots,

  • -
  • +
  • - +

    curve_knot_refine( degree, knots, control_points, knots_to_insert )

    Insert a collection of knots on a curve

    @@ -9896,11 +9861,11 @@

    curve_kn

  • -
  • +
  • - +

    new control pts

    @@ -9917,11 +9882,11 @@

    curve_kn

  • -
  • +
  • - +

    new knot vector

    @@ -9981,11 +9946,11 @@

    curve_kn

  • -
  • +
  • - +

    curve_knot_insert( degree, knots, control_points, u, r )

    Insert a knot along a rational curve. Note that this algorithm only works @@ -10013,11 +9978,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    num_pts is num control points for the initial curve k is the span on which the knots are inserted @@ -10041,11 +10006,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    new knot vector

    @@ -10054,11 +10019,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    insert the k knots that will not be affected

    @@ -10071,11 +10036,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    insert the new repeat knots

    @@ -10088,11 +10053,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    insert the rest of the knots

    @@ -10105,11 +10070,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    control point generation

    @@ -10118,11 +10083,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    copy the original control points before the insertion span

    @@ -10135,11 +10100,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    copy the original controls after the insertion span

    @@ -10152,11 +10117,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    collect the affected control points in this temporary array

    @@ -10172,11 +10137,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    insert knot r times

    @@ -10207,11 +10172,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    not so confident about this part

    @@ -10228,11 +10193,11 @@

    curve_knot_insert( d

  • -
  • +
  • - +

    surface_curvature( degree_u, knots_u, degree_v, knots_v, control_points, u, v, options )

    Compute the gaussian curvature on a non-uniform, non-rational B spline surface

    @@ -10260,11 +10225,11 @@

    +
  • - +

    compute the first fundamental form

    @@ -10273,11 +10238,11 @@

    +
  • - +

    symmetric matrix where

    I = [ E F; F G ]

    @@ -10291,11 +10256,11 @@

    +
  • - +

    second fundamental form (shape operator)

    @@ -10304,11 +10269,11 @@

    +
  • - +

    symmetric matrix where

    II = [ L M; M N ]

    @@ -10322,11 +10287,11 @@

    +
  • - +

    principal curvatures are the eigenvalues of the second fundamental form

    @@ -10343,11 +10308,11 @@

    +
  • - +

    structure of the derivatives

    @@ -10356,11 +10321,11 @@

    +
  • - +

    pos du vuu dv duv @@ -10387,11 +10352,11 @@

    +
  • - +

    contains: lambda - x E - x

    @@ -10413,11 +10378,11 @@

    +
  • - +

    rational_surface_derivs( degree_u, knots_u, degree_v, knots_v, homo_control_points, num_derivs, u, v)

    Compute the derivatives at a point on a NURBS surface

    @@ -10488,11 +10453,11 @@

    +
  • - +

    rational_surface_point( degree_u, knots_u, degree_v, knots_v, homo_control_points, u, v )

    Compute a point on a NURBS surface

    @@ -10524,11 +10489,11 @@

    +
  • - +

    `

    rational_curve_derivs( degree, knots, homo_control_points, u, num_derivs )

    @@ -10553,11 +10518,11 @@

    ra

  • -
  • +
  • - +

    compute the derivatives of the control points separate derivative array into two

    @@ -10587,11 +10552,11 @@

    ra

  • -
  • +
  • - +

    separate_homo_derivs_1d( ck )

    Separate the array of derivatives into the A(u) component and w(u), i.e. the weight and everything else without dehomogenization

    @@ -10626,11 +10591,11 @@

    separate_homo_derivs_1d( ck )

  • -
  • +
  • - +

    separate_homo_derivs_2d( skl )

    Separate the array of derivatives into the A(u) component and w(u), i.e. the weight and everything else without dehomogenization

    @@ -10664,11 +10629,11 @@

    separate_homo_derivs_2d( skl )

  • -
  • +
  • - +

    rational_curve_point( degree, knots, homo_control_points, u)

    Compute a point on a NURBS curve

    @@ -10697,11 +10662,11 @@

    rational_curve

  • -
  • +
  • - +

    dehomogenize( homo_point )

    Dehomogenize a point

    @@ -10733,11 +10698,11 @@

    dehomogenize( homo_point )

  • -
  • +
  • - +

    weights_1d( homo_points )

    Obtain the weight from a collection of points in homogeneous space, assuming all @@ -10765,11 +10730,11 @@

    weights_1d( homo_points )

  • -
  • +
  • - +

    dehomogenize_1d( homo_points )

    Dehomogenize a point

    @@ -10794,11 +10759,11 @@

    dehomogenize_1d( homo_points )

  • -
  • +
  • - +

    homogenize_1d( control_points, weights)

    Transform a 1d array of points into their homogeneous equivalents

    @@ -10819,11 +10784,11 @@

    homogenize_1d( control_points, we

  • -
  • +
  • - +
    @@ -10851,11 +10816,11 @@

    homogenize_1d( control_points, we

  • -
  • +
  • - +

    append the weight

    @@ -10873,11 +10838,11 @@

    homogenize_1d( control_points, we

  • -
  • +
  • - +

    homogenize_2d( control_points, weights)

    params

    @@ -10897,11 +10862,11 @@

    homogenize_2d( control_points, we

  • -
  • +
  • - +
    @@ -10929,11 +10894,11 @@

    homogenize_2d( control_points, we

  • -
  • +
  • - +

    surface_derivs( degree_u, knots_u, degree_v, knots_v, control_points, num_derivatives, u, v )

    Compute the derivatives on a non-uniform, non-rational B spline surface

    @@ -10968,11 +10933,11 @@

    +
  • - +

    surface_derivs_given_n_m( n, degree_u, knots_u, m, degree_v, knots_v, control_points, num_derivatives, u, v )

    Compute the derivatives on a non-uniform, non-rational B spline surface @@ -11047,11 +11012,11 @@

    +
  • - +

    surface_point( degree_u, knots_u, degree_v, knots_v, control_points, u, v)

    Compute a point on a non-uniform, non-rational B-spline surface

    @@ -11086,11 +11051,11 @@

    sur

  • -
  • +
  • - +

    volume_point( degree_u, knots_u, degree_v, knots_v, degree_w, knots_w, control_points, u, v, w )

    Compute a point in a non-uniform, non-rational B spline volume

    @@ -11131,11 +11096,11 @@

    +
  • - +

    volume_point_given_n_m_l( n, degree_u, knots_u, m, degree_v, knots_v, l, degree_w, knots_w, control_points, u, v, w )

    Compute a point in a non-uniform, non-rational B spline volume

    @@ -11204,11 +11169,11 @@

    +
  • - +

    sample u isoline

    @@ -11220,11 +11185,11 @@

    +
  • - +

    add weighted contribution of u isoline

    @@ -11236,11 +11201,11 @@

    +
  • - +

    add weighted contribution from uv isosurfaces

    @@ -11256,11 +11221,11 @@

    +
  • - +

    surface_point_given_n_m( n, degree_u, knots_u, m, degree_v, knots_v, control_points, u, v )

    Compute a point on a non-uniform, non-rational B spline surface @@ -11313,11 +11278,11 @@

    +
  • - +

    sample u isoline

    @@ -11330,11 +11295,11 @@

    +
  • - +

    add point from u isoline

    @@ -11349,11 +11314,11 @@

    +
  • - +

    curve_derivs( degree, knots, control_points, u, num_derivs )

    Determine the derivatives of a non-uniform, non-rational B-spline curve at a given parameter

    @@ -11382,11 +11347,11 @@

    curve_derivs( de

  • -
  • +
  • - +

    curve_derivs_given_n( n, degree, knots, control_points, u, num_derivatives )

    Determine the derivatives of a non-uniform, non-rational B-spline curve at a given parameter @@ -11434,11 +11399,11 @@

    c

  • -
  • +
  • - +

    are_valid_relations( degree, num_control_points, knots_length )

    Confirm the relations between degree (p), number of control points(n+1), and the number of knots (m+1) @@ -11464,11 +11429,11 @@

    are_valid_r

  • -
  • +
  • - +

    curve_point( degree, knots, control_points, u)

    Compute a point on a non-uniform, non-rational b-spline curve

    @@ -11497,11 +11462,11 @@

    curve_point( degree, knots,

  • -
  • +
  • - +

    curve_point_given_n( n, degree, knots, control_points, u)

    Compute a point on a non-uniform, non-rational b-spline curve @@ -11543,11 +11508,11 @@

    curve_point_given_

  • -
  • +
  • - +

    zeros_1d(size)

    Generate a 1d array of zeros

    @@ -11570,11 +11535,11 @@

    zeros_1d(size)

  • -
  • +
  • - +

    zeros_2d(rows, cols)

    Generate a 2D array of zeros

    @@ -11601,11 +11566,11 @@

    zeros_2d(rows, cols)

  • -
  • +
  • - +

    zeros_3d(rows, cols, dim)

    Generate a 3D array of zeros

    @@ -11633,11 +11598,11 @@

    zeros_3d(rows, cols, dim)

  • -
  • +
  • - +

    deriv_basis_functions( u, degree, knots )

    Compute the non-vanishing basis functions and their derivatives

    @@ -11667,11 +11632,11 @@

    deriv_basis_functions( u, degree,

  • -
  • +
  • - +

    deriv_basis_functions_given_n_i( knot_span_index, u, p, n, knots )

    Compute the non-vanishing basis functions and their derivatives @@ -11799,11 +11764,11 @@

    deriv_basi

  • -
  • +
  • - +

    basis_functions( u, degree, knots )

    Compute the non-vanishing basis functions

    @@ -11830,11 +11795,11 @@

    basis_functions( u, degree, knots )

    -
  • +
  • - +

    basis_functions_given_knot_span_index( knot_span_index, u, degree, knots )

    Compute the non-vanishing basis functions @@ -11887,11 +11852,11 @@

    b

  • -
  • +
  • - +

    knot_span( degree, u, knots )

    Find the span on the knot vector without supplying n

    @@ -11922,11 +11887,11 @@

    knot_span( degree, u, knots )

  • -
  • +
  • - +

    knot_span_given_n( n, degree, u, knots )

    Find the span on the knot vector knots of the given parameter diff --git a/example/threeMeshIntersectExample.html b/example/threeMeshIntersectExample.html index 3bf4b045..be8dcfa4 100644 --- a/example/threeMeshIntersectExample.html +++ b/example/threeMeshIntersectExample.html @@ -65,6 +65,24 @@ return geometry; } + function tess(srf){ + var srfObj = { + degree_u : srf.get('degreeU'), + degree_v : srf.get('degreeV'), + knots_u : srf.get('knotsU'), + knots_v : srf.get('knotsV'), + homo_control_points : srf.homogenize() + }; + + var tess = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj.degree_u, + srfObj.knots_u, + srfObj.degree_v, + srfObj.knots_v, + srfObj.homo_control_points); + + return tess; + } + // verb.NurbsSurface -> THREE.Geometry function tessellate(srf, udivs, vdivs) { @@ -76,14 +94,11 @@ homo_control_points : srf.homogenize() }; - var tessOptions = { minDivsU: 20, minDivsV: 20, tol: 5e-2 }; - var tess = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj.degree_u, srfObj.knots_u, srfObj.degree_v, srfObj.knots_v, - srfObj.homo_control_points, - tessOptions ); + srfObj.homo_control_points ); // var f = new verb.eval.nurbs.AdaptiveRefinementNode( srfObj ); // f.divide({ minDepth: 2, tol: 5e-2 }); @@ -132,7 +147,7 @@ var hexString = Math.floor(Math.random()*16777215).toString(16); var hex = parseInt(hexString, 16); - var lineMat = new THREE.LineBasicMaterial({ linewidth: 2, color: hex}); + var lineMat = new THREE.LineBasicMaterial({ linewidth: 2, color: 0xffffff}); var l = new THREE.Line( geom, lineMat ); scene.add( l ); @@ -366,24 +381,38 @@ var srf1, srf2; // exampleTorusCylinderSuccess(); - // exampleGlancingPlaneCylinderSuccess(); - //examplePlanePlaneSuccess(); + //exampleGlancingPlaneCylinderSuccess(); + // examplePlanePlaneSuccess(); //exampleTorusCylinderSuccess2(); - // exampleTorusCylinderSuccess3(); + exampleTorusCylinderSuccess3(); //examplePlanePlaneSuccess(); - exampleNurbsSurfacePlane(); + //exampleNurbsSurfacePlane(); - addMeshToScene( tessellate(srf1, udivs0, vdivs0), true ); - addMeshToScene( tessellate(srf2, udivs1, vdivs1), true); + addMeshToScene( tessellate(srf1, udivs0, vdivs0), false ); + addMeshToScene( tessellate(srf2, udivs1, vdivs1), false); - var tess1 = srf1.tessellate({ minDivsU: udivs0, minDivsV: vdivs0 }); - var tess2 = srf2.tessellate({ minDivsU: udivs1, minDivsV: vdivs1 }); + var tess1 = tess(srf1, udivs0, vdivs0); + var tess2 = tess(srf2, udivs1, vdivs1); - // var res = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, - // tess1.uvs, tess2.points, tess2.faces, tess2.uvs ); + var res = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, + tess1.uvs, tess2.points, tess2.faces, tess2.uvs ); var ref = verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine(srf1.get('degreeU'), srf1.get('knotsU'), srf1.get('degreeV'), srf1.get('knotsV'), srf1.homogenize(), srf2.get('degreeU'), srf2.get('knotsU'), srf2.get('degreeV'), srf2.get('knotsV'), srf2.homogenize(), 1e-6); + var runs = 10; + + var d1 = Date.now(); + + for (var i = 0 ; i < runs; i++){ + + var ref = verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine(srf1.get('degreeU'), srf1.get('knotsU'), srf1.get('degreeV'), srf1.get('knotsV'), srf1.homogenize(), srf2.get('degreeU'), srf2.get('knotsU'), srf2.get('degreeV'), srf2.get('knotsV'), srf2.homogenize(), 1e-6); + + } + + var d2 = Date.now(); + + console.log("intersected in ", (d2 - d1) / runs, "ms") + for (var i = 0; i < ref.length; i++){ var homo = verb.eval.nurbs.homogenize_1d( ref[i].control_points, ref[i].weights ); diff --git a/example/threeSurfaceExample.html b/example/threeSurfaceExample.html index dcb3d279..81034f92 100644 --- a/example/threeSurfaceExample.html +++ b/example/threeSurfaceExample.html @@ -89,31 +89,23 @@ srf.get('knotsU'), srf.get('degreeV'), srf.get('knotsV'), - srf.homogenize(), - { minDivsU: du, minDivsV : dv, edgeTol: 0.01 } ); - - console.log( srf.derivatives( 1,1) ) + srf.homogenize() ); var du = (srfObj.homo_control_points.length - 1) * 2; var dv = (srfObj.homo_control_points[0].length - 1) * 2; var d1 = Date.now(); - var runs = 20; - - // for (var i = 0; i < runs; i++){ + var runs = 40; - // var mesh = verb.eval.nurbs.tessellate_rational_surface_adaptive( srf.get('degreeU'), - // srf.get('knotsU'), - // srf.get('degreeV'), - // srf.get('knotsV'), - // srf.homogenize(), - // { refine: true } ); + for (var i = 0; i < runs; i++){ - // // var f = new verb.eval.nurbs.AdaptiveRefinementNode( srfObj ); - // // f.divide({ edgeTol: 5e-2 }); - // // var mesh = f.triangulate(); - // } + var mesh = verb.eval.nurbs.tessellate_rational_surface_adaptive( srf.get('degreeU'), + srf.get('knotsU'), + srf.get('degreeV'), + srf.get('knotsV'), + srf.homogenize() ); + } var d2 = Date.now(); diff --git a/src/eval/eval.js b/src/eval/eval.js index f7977cba..226d62a1 100644 --- a/src/eval/eval.js +++ b/src/eval/eval.js @@ -122,6 +122,9 @@ verb.eval.nurbs.curve_split = function( degree, knots, control_points, u ) { } +verb.eval.nurbs.surface_knot_refine = function( degree_u, knots_u, degree_v, knots_v, homo_control_points, num_derivs, u, v) + + // // ####curve_knot_refine( degree, knots, control_points, knots_to_insert ) // diff --git a/src/eval/intersect.js b/src/eval/intersect.js index dbd0c629..92adcc02 100644 --- a/src/eval/intersect.js +++ b/src/eval/intersect.js @@ -1030,14 +1030,12 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de }; // todo: need to be able to predict the number of divisions - var tessOptions = { minDivsU: 20, minDivsV: 20, tol: 5e-2 }; var tess1 = verb.eval.nurbs.tessellate_rational_surface_adaptive( srfObj1.degree_u, srfObj1.knots_u, srfObj1.degree_v, srfObj1.knots_v, - srfObj1.homo_control_points, - tessOptions ); + srfObj1.homo_control_points); var srfObj2 = { degree_u : degree_u2, @@ -1051,8 +1049,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de srfObj2.knots_u, srfObj2.degree_v, srfObj2.knots_v, - srfObj2.homo_control_points, - tessOptions ); + srfObj2.homo_control_points); var resApprox = verb.eval.mesh.intersect_meshes_by_aabb( tess1.points, tess1.faces, tess1.uvs, tess2.points, tess2.faces, tess2.uvs ); @@ -1066,7 +1063,7 @@ verb.eval.nurbs.intersect_rational_surface_surface_by_aabb_refine = function( de // 3) perform cubic interpolation return exactPls.map(function(x){ - return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 2 ); + return verb.eval.nurbs.rational_interp_curve( x.map(function(x){ return x.pt; }), 3 ); }); // TODO: represent this in uv space @@ -1096,11 +1093,10 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points res[1].tri2id = ids[1]; return res; - }) - .filter(function(x){ return x; }) + }).filter(function(x){ return x; }) .filter(function(x){ var dif = numeric.sub( x[0].pt, x[1].pt ); - return numeric.dot( dif, dif ) > verb.TOLERANCE + return numeric.dot( dif, dif ) > verb.EPSILON }); // TODO: this is too expensive and this only occurs when the intersection @@ -1120,8 +1116,8 @@ verb.eval.mesh.intersect_meshes_by_aabb = function( points1, tris1, uvs1, points var s4 = numeric.sub( a[1].uvtri1, b[0].uvtri1 ); var d4 = numeric.dot( s4, s4 ); - return ( d1 < verb.TOLERANCE && d2 < verb.TOLERANCE ) || - ( d3 < verb.TOLERANCE && d4 < verb.TOLERANCE ); + return ( d1 < verb.EPSILON && d2 < verb.EPSILON ) || + ( d3 < verb.EPSILON && d4 < verb.EPSILON ); }); @@ -1241,7 +1237,7 @@ verb.eval.mesh.lookup_adj_segment = function( segEnd, tree, numSegments ) { // we expect one result to be self, one to be neighbor and no more var adj = tree.nearest({ x: segEnd.pt[0], y: segEnd.pt[1], z: segEnd.pt[2] }, numResults) .filter(function(r){ - return segEnd != r[0].ele && r[1] < verb.TOLERANCE; + return segEnd != r[0].ele && r[1] < verb.EPSILON; }) .map(function(r){ return r[0].ele; }); diff --git a/src/eval/tessellate.js b/src/eval/tessellate.js index 3df79cb5..a962154d 100644 --- a/src/eval/tessellate.js +++ b/src/eval/tessellate.js @@ -686,14 +686,6 @@ verb.eval.nurbs.AdaptiveRefinementNode.prototype.shouldDivide = function( option this.splitHoriz = numeric.norm2Squared( numeric.sub( this.corners[1].normal, this.corners[2].normal ) ) > options.normTol || numeric.norm2Squared( numeric.sub( this.corners[3].normal, this.corners[0].normal ) ) > options.normTol; - // is curved in u direction? - // this.splitVert = verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[0].point, this.corners[1].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[2].point, this.midpoints[2].point, this.corners[3].point ) > options.edgeTol; - - // // is curved in v direction? - // this.splitHoriz = verb.eval.nurbs.dist_to_seg( this.corners[1].point, this.midpoints[1].point, this.corners[2].point ) > options.edgeTol || - // verb.eval.nurbs.dist_to_seg( this.corners[0].point, this.midpoints[3].point, this.corners[3].point ) > options.edgeTol; - if ( this.splitVert || this.splitHoriz ) return true; var center = this.center(); diff --git a/src/verb.js b/src/verb.js index e8bc09a4..dc875dd9 100644 --- a/src/verb.js +++ b/src/verb.js @@ -26,7 +26,7 @@ verb.eval.mesh = verb.eval.mesh || {}; // ####verb.EPSILON // // Used for numeric comparisons -verb.EPSILON = 1e-8; +verb.EPSILON = 1e-10; // ####verb.TOLERANCE // diff --git a/test/test.js b/test/test.js index 1907669e..0fa753d1 100644 --- a/test/test.js +++ b/test/test.js @@ -1,10 +1,6 @@ var should = require('should') , verb = require('../build/verb.js'); -console.log('running from ', process.cwd() ); -console.log(verb); - - function vecShouldBe( expected, test, tol ){ if (tol === undefined) tol = verb.TOLERANCE; @@ -1339,7 +1335,7 @@ describe("verb.eval.nurbs.get_revolved_surface",function(){ }); -describe("verb.eval.nurbs.d_surface",function(){ +describe("verb.eval.nurbs.get_extruded_surface",function(){ it('can extrude a line into a plane', function(){ @@ -5701,5 +5697,13 @@ describe("verb.eval.nurbs.tessellate_rational_surface_adaptive",function(){ }); }); +describe("verb.eval.nurbs.tessellate_rational_surface_adaptive",function(){ + it('produces a mesh from a divided surface', function(){ + + // tessellate a trim curve + + }); +}); +