markuno_lib 1.2.10 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/markcad.js +5 -5
- package/package.json +1 -1
- package/types/markcad.d.ts +1 -1
package/bin/markcad.js
CHANGED
|
@@ -286,7 +286,7 @@ function sharpCorners(path,thresholdDeg=45){const result=[],n=path.length;if(n<3
|
|
|
286
286
|
* @param {number} thresholdDeg - Angolo in gradi.
|
|
287
287
|
* @returns {Array<{ index: number, point: {x:number,y:number}, angle: number }>}
|
|
288
288
|
*/
|
|
289
|
-
segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},move(x=0,y=0){"object"==typeof x&&x.x&&(y=x.y||0,x=x.x);for(let p of pt)p.x+=x,p.y+=y;return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=function simplify(points,tolerance,highestQuality){if(points.length<=2)return points;var sqTolerance=void 0!==tolerance?tolerance*tolerance:1;return simplifyDouglasPeucker(points=highestQuality?points:function simplifyRadialDist(points,sqTolerance){for(var point,p1,p2,dx,dy,prevPoint=points[0],newPoints=[prevPoint],i=1,len=points.length;i<len;i++)p2=prevPoint,dx=void 0,dy=void 0,(dx=(p1=point=points[i]).x-p2.x)*dx+(dy=p1.y-p2.y)*dy>sqTolerance&&(newPoints.push(point),prevPoint=point);return prevPoint!==point&&newPoints.push(point),newPoints}(points,sqTolerance),sqTolerance)}(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},fromstr(str){return pt=removeduplicate(function processTokens(tokens){const points=[];for(let i=0;i<tokens.length;i++){const token=tokens[i];if("point"===token.type)points.push(token.point);else if("command"===token.type)switch(token.cmd){case"x":{const p1=points[points.length-1],p2="point"===tokens[i+1]?.type?tokens[i+1].point:points[0],bulge=parseFloat(token.params[0])||5;{const STEP=1;let dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>1&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-STEP)/(STEP+2))+1))}break}case"b":{if(points.length<2)continue;const npt=parseInt(token.params[0])||5,p1=points[points.length-2],p2=points[points.length-1];let p3="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p4="point"===tokens[i+2]?.type?tokens[i+2].point:void 0;p3?p4||(p4=points[0]):(p3=points[0],p4=points[1]);const raccordo=raccordabezier(p1,p2,p3,p4,npt);points.push(...raccordo),i+=1;break}case"r":{if(points.length<1)continue;const dist=parseFloat(token.params[0])||5,npt=parseInt(token.params[1])||10,p1=points[points.length-1];let p2="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p3="point"===tokens[i+2]?.type?tokens[i+2].point:"point"===tokens[i+3]?.type?tokens[i+3].point:void 0;p2?p3||(p3=points[0]):(p2=points[0],p3=points[1],points.splice(0,1));const raccordo=raccordabezier3(p1,p2,p3,dist,npt);points.push(...raccordo),i+=1;break}case"c":{const radius=parseFloat(token.params[0])||50,segments=parseInt(token.params[1])||12,center="point"===tokens[i+1]?.type?tokens[i+1].point:new Punto2(0,0);for(let j=0;j<segments;j++)points.push(new Punto2(center.x+radius*Math.cos(j/segments*Math.PI*2),center.y+radius*Math.sin(j/segments*Math.PI*2)));i+=1;break}case"a":{let npt,p1="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p2="point"===tokens[i+2]?.type?tokens[i+2].point:void 0,p3="point"===tokens[i+3]?.type?tokens[i+3].point:void 0;if(!p1||!p3)continue;if(p2)if(token.params[0])npt=clamp(parseInt(token.params[0]),1,24);else{const chord=Math.hypot(p3.x-p1.x,p3.y-p1.y),sagitta=Math.abs((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))/(2*chord);npt=Math.round(chord*Math.sqrt(sagitta/(chord+.1))*10),npt=clamp(npt,1,24),npt=1}else p2=p3,npt=0;const arcoPoints=arcfrom3point(npt,p1,p2,p3);points.push(...arcoPoints),i+=3;break}}}return points}(function tokenize(str){const tokens=[],values=str.replace(/[\n\r,;]/g," ").replace(/\s+/g," ").toLowerCase().trim().split(" ").filter((s=>s.length>0));let i=0;for(;i<values.length;){const val=values[i];/^[brcax]/.test(val)?(tokens.push({type:"command",cmd:val[0],params:val.slice(1).split(":")}),i++):i<values.length-1&&/^-?\d+(\.\d+)?$/.test(values[i])&&/^-?\d+(\.\d+)?$/.test(values[i+1])?(tokens.push({type:"point",point:new Punto2(parseFloat(values[i]),parseFloat(values[i+1]))}),i+=2):i++}return tokens}(str))),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
|
|
289
|
+
segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},move(x=0,y=0){"object"==typeof x&&x.x&&(y=x.y||0,x=x.x);for(let p of pt)p.x+=x,p.y+=y;return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=function simplify(points,tolerance,highestQuality){if(points.length<=2)return points;var sqTolerance=void 0!==tolerance?tolerance*tolerance:1;return simplifyDouglasPeucker(points=highestQuality?points:function simplifyRadialDist(points,sqTolerance){for(var point,p1,p2,dx,dy,prevPoint=points[0],newPoints=[prevPoint],i=1,len=points.length;i<len;i++)p2=prevPoint,dx=void 0,dy=void 0,(dx=(p1=point=points[i]).x-p2.x)*dx+(dy=p1.y-p2.y)*dy>sqTolerance&&(newPoints.push(point),prevPoint=point);return prevPoint!==point&&newPoints.push(point),newPoints}(points,sqTolerance),sqTolerance)}(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},fromstr(str){return pt=removeduplicate(function processTokens(tokens){const points=[];for(let i=0;i<tokens.length;i++){const token=tokens[i];if("point"===token.type)points.push(token.point);else if("command"===token.type)switch(token.cmd){case"x":{const p1=points[points.length-1],p2="point"===tokens[i+1]?.type?tokens[i+1].point:points[0],bulge=parseFloat(token.params[0])||5;{const STEP=1;let dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>1&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-STEP)/(STEP+2))+1))}break}case"b":{if(points.length<2)continue;const npt=parseInt(token.params[0])||5,p1=points[points.length-2],p2=points[points.length-1];let p3="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p4="point"===tokens[i+2]?.type?tokens[i+2].point:void 0;p3?p4||(p4=points[0]):(p3=points[0],p4=points[1]);const raccordo=raccordabezier(p1,p2,p3,p4,npt);points.push(...raccordo),i+=1;break}case"r":{if(points.length<1)continue;const dist=parseFloat(token.params[0])||5,npt=parseInt(token.params[1])||10,p1=points[points.length-1];let p2="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p3="point"===tokens[i+2]?.type?tokens[i+2].point:"point"===tokens[i+3]?.type?tokens[i+3].point:void 0;p2?p3||(p3=points[0]):(p2=points[0],p3=points[1],points.splice(0,1));const raccordo=raccordabezier3(p1,p2,p3,dist,npt);points.push(...raccordo),i+=1;break}case"c":{const radius=parseFloat(token.params[0])||50,segments=parseInt(token.params[1])||12,center="point"===tokens[i+1]?.type?tokens[i+1].point:new Punto2(0,0);for(let j=0;j<segments;j++)points.push(new Punto2(center.x+radius*Math.cos(j/segments*Math.PI*2),center.y+radius*Math.sin(j/segments*Math.PI*2)));i+=1;break}case"a":{let npt,p1="point"===tokens[i+1]?.type?tokens[i+1].point:void 0,p2="point"===tokens[i+2]?.type?tokens[i+2].point:void 0,p3="point"===tokens[i+3]?.type?tokens[i+3].point:void 0;if(!p1||!p3)continue;if(p2)if(token.params[0])npt=clamp(parseInt(token.params[0]),1,24);else{const chord=Math.hypot(p3.x-p1.x,p3.y-p1.y),sagitta=Math.abs((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))/(2*chord);npt=Math.round(chord*Math.sqrt(sagitta/(chord+.1))*10),npt=clamp(npt,1,24),npt=1}else p2=p3,npt=0;const arcoPoints=arcfrom3point(npt,p1,p2,p3);points.push(...arcoPoints),i+=3;break}}}return points}(function tokenize(str){const tokens=[],values=str.replace(/[\n\r,;]/g," ").replace(/\s+/g," ").toLowerCase().trim().split(" ").filter((s=>s.length>0));let i=0;for(;i<values.length;){const val=values[i];/^[brcax]/.test(val)?(tokens.push({type:"command",cmd:val[0],params:val.slice(1).split(":")}),i++):i<values.length-1&&/^-?\d+(\.\d+)?$/.test(values[i])&&/^-?\d+(\.\d+)?$/.test(values[i+1])?(tokens.push({type:"point",point:new Punto2(parseFloat(values[i]),parseFloat(values[i+1]))}),i+=2):i++}return tokens}(str))),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},sliceony(stag){let yvalues=stag.pt.map((e=>e.y)).slice(1,-1);const res=[],n=pt.length;let imin=0,yMin=pt[0].y;for(let i=1;i<n;i++)pt[i].y<yMin&&(yMin=pt[i].y,imin=i);const pts=[...pt.slice(imin),...pt.slice(0,imin)],m=pts.length,ymap=new Map;for(let i=0;i<m;i++)for(let y of yvalues)Math.abs(pts[i].y-y)<1e-5&&(ymap.has(y)?ymap.get(y).i2=i:ymap.set(y,{i1:i,i2:i}));const pairs=yvalues.map((y=>ymap.get(y))).filter((p=>p&&p.i1>=0&&p.i2>=0));pairs.length>0&&pairs[0].i1>0&&res.push([...pts.slice(0,pairs[0].i1+1),...pts.slice(pairs[0].i2,pairs[0].length)]);for(let i=0;i<pairs.length-1;i++){const a=pairs[i],b=pairs[i+1];res.push([...pts.slice(a.i1,b.i1+1),...pts.slice(b.i2,a.i2+1)])}const last=pairs[pairs.length-1];last.i2>last.i1&&res.push(pts.slice(last.i1,last.i2+1));return res.filter((arr=>arr.length>0))},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
|
|
290
290
|
/**
|
|
291
291
|
* Calcola i punti di un arco passante per tre punti
|
|
292
292
|
* @param {number} segments - Numero di segmenti (punti-1)
|
|
@@ -610,7 +610,7 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
|
|
|
610
610
|
* @param {THREE.Material} mat - Materiale da applicare
|
|
611
611
|
* @param {Object} options - Opzioni di configurazione
|
|
612
612
|
* @returns {Promise<THREE.Group>} Gruppo contenente il box
|
|
613
|
-
*/function getface(gcad,x,y,mat,scaled=!1){let ky=hash(`f:${x}|${y}|${scaled?1:0}`);if(!gcad.geo[ky]){const geometry=new THREE.PlaneGeometry(x,y),uvs=geometry.attributes.uv;if(!scaled)for(let i=0;i<uvs.count;i++)uvs.setXY(i,uvs.getX(i)*x,uvs.getY(i)*y);gcad.geo[ky]=geometry}const plane=new THREE.Mesh(gcad.geo[ky],mat);return plane.position.set(x/2,y/2,0),mat?.transparent&&plane.layers.set(2),plane}function getcyl(gcad,height,radius,mat,options){options||(options={});let{center:center=!1,nolines:nolines=!1,segments:segments=16,radiusBottom:radiusBottom=-1}=options;radiusBottom<0&&(radiusBottom=radius);let grp=new THREE.Group;const cylinder=new THREE.CylinderGeometry(radius,radiusBottom,height,segments);if(grp.position.set(0,center?0:height/2,0),!nolines){let segments=edgesfromgeometry(cylinder);grp.add(segments)}return grp.add(getmesh(cylinder,mat||mwhite)),grp}function getbox(gcad,x,y,z,mat,options){options||(options={});let{center:center,nolines:nolines}=options,grp=new THREE.Group;const box=function boxgeometry(gcad,x,y,z){let ky=hash(`b:${x}|${y}|${z}`);if(!gcad.geo[ky]){const bx=new THREE.BoxGeometry(x,y,z);gcad.geo[ky]=bx}return gcad.geo[ky]}(gcad,x,y,z);if(grp.position.set(
|
|
613
|
+
*/function getface(gcad,x,y,mat,scaled=!1){let ky=hash(`f:${x}|${y}|${scaled?1:0}`);if(!gcad.geo[ky]){const geometry=new THREE.PlaneGeometry(x,y),uvs=geometry.attributes.uv;if(!scaled)for(let i=0;i<uvs.count;i++)uvs.setXY(i,uvs.getX(i)*x,uvs.getY(i)*y);gcad.geo[ky]=geometry}const plane=new THREE.Mesh(gcad.geo[ky],mat);return plane.position.set(x/2,y/2,0),mat?.transparent&&plane.layers.set(2),plane}function getcyl(gcad,height,radius,mat,options){options||(options={});let{center:center=!1,nolines:nolines=!1,segments:segments=16,radiusBottom:radiusBottom=-1}=options;radiusBottom<0&&(radiusBottom=radius);let grp=new THREE.Group;const cylinder=new THREE.CylinderGeometry(radius,radiusBottom,height,segments);if(grp.position.set(0,center?0:height/2,0),!nolines){let segments=edgesfromgeometry(cylinder);grp.add(segments)}return grp.add(getmesh(cylinder,mat||mwhite)),grp}function getbox(gcad,x,y,z,mat,options){options||(options={});let{center:center,nolines:nolines}=options,grp=new THREE.Group;const box=function boxgeometry(gcad,x,y,z){let ky=hash(`b:${x}|${y}|${z}`);if(!gcad.geo[ky]){const bx=new THREE.BoxGeometry(x,y,z);gcad.geo[ky]=bx}return gcad.geo[ky]}(gcad,x,y,z);if(center||grp.position.set(x/2,y/2,z/2),!nolines){let segments=edgesfromgeometry(box);grp.add(segments)}return grp.add(getmesh(box,mat||mwhite)),grp}
|
|
614
614
|
/**
|
|
615
615
|
* @param {BufferGeometry} geometry
|
|
616
616
|
* @param {number} tolerance
|
|
@@ -621,7 +621,7 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
|
|
|
621
621
|
* @param {number} drawMode
|
|
622
622
|
* @return {BufferGeometry}
|
|
623
623
|
*/
|
|
624
|
-
function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),geometry;if(drawMode===TriangleFanDrawMode||drawMode===TriangleStripDrawMode){let index=geometry.getIndex();if(null===index){const indices=[],position=geometry.getAttribute("position");if(void 0===position)return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),geometry;for(let i=0;i<position.count;i++)indices.push(i);geometry.setIndex(indices),index=geometry.getIndex()}const numberOfTriangles=index.count-2,newIndices=[];if(drawMode===TriangleFanDrawMode)for(let i=1;i<=numberOfTriangles;i++)newIndices.push(index.getX(0)),newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1));else for(let i=0;i<numberOfTriangles;i++)i%2==0?(newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i+2))):(newIndices.push(index.getX(i+2)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i)));newIndices.length/3!==numberOfTriangles&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const newGeometry=geometry.clone();return newGeometry.setIndex(newIndices),newGeometry.clearGroups(),newGeometry}return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",drawMode),geometry}function pannellogeometry(gcad,l,a,p,r1=0,r2=0,r3=0,r4=0,b=0,npt=2){let ky=hash(`pg--${l}|${a}|${p}|${r1}|${r2}|${r3}|${r4}|${b}|${npt}`);if(l-=.01,a-=.01,p-=.01,!gcad.geo[ky]){l-=2*b,a-=2*b,p-=2*b;let tm=getshape();const vv=[{x:r4,y:0},{x:a-r1,y:0},{x:a,y:r1},{x:a,y:p-r2},{x:a-r2,y:p},{x:r3,y:p},{x:0,y:p-r3},{x:0,y:r4}];tm.addpt(vv[0]),tm.addpt(vv[1]),r1&&tm.addpt(raccordabezier(vv[0],vv[1],vv[2],vv[3],npt)),tm.addpt(vv[2]),tm.addpt(vv[3]),r2&&tm.addpt(raccordabezier(vv[2],vv[3],vv[4],vv[5],npt)),tm.addpt(vv[4]),tm.addpt(vv[5]),r3&&tm.addpt(raccordabezier(vv[4],vv[5],vv[6],vv[7],npt)),tm.addpt(vv[6]),tm.addpt(vv[7]),r2&&tm.addpt(raccordabezier(vv[6],vv[7],vv[0],vv[1],npt)),tm.removeduplicate(.01);let pts=tm.pt;const shape=new THREE.Shape;shape.moveTo(pts[0].x,pts[0].y);for(let i=1;i<pts.length;i++)shape.lineTo(pts[i].x,pts[i].y);shape.lineTo(pts[0].x,pts[0].y);const extrudeSettings={depth:l,bevelEnabled:b>0,bevelThickness:b,bevelSize:b,bevelSegments:1};let xgeo=new THREE.ExtrudeGeometry(shape,extrudeSettings);xgeo=function mergeVertices(geometry,tolerance=1e-4){tolerance=Math.max(tolerance,Number.EPSILON);const hashToIndex={},indices=geometry.getIndex(),positions=geometry.getAttribute("position"),vertexCount=indices?indices.count:positions.count;let nextIndex=0;const attributeNames=Object.keys(geometry.attributes),tmpAttributes={},tmpMorphAttributes={},newIndices=[],getters=["getX","getY","getZ","getW"],setters=["setX","setY","setZ","setW"];for(let i=0,l=attributeNames.length;i<l;i++){const name=attributeNames[i],attr=geometry.attributes[name];tmpAttributes[name]=new attr.constructor(new attr.array.constructor(attr.count*attr.itemSize),attr.itemSize,attr.normalized);const morphAttributes=geometry.morphAttributes[name];morphAttributes&&(tmpMorphAttributes[name]||(tmpMorphAttributes[name]=[]),morphAttributes.forEach(((morphAttr,i)=>{const array=new morphAttr.array.constructor(morphAttr.count*morphAttr.itemSize);tmpMorphAttributes[name][i]=new morphAttr.constructor(array,morphAttr.itemSize,morphAttr.normalized)})))}const halfTolerance=.5*tolerance,exponent=Math.log10(1/tolerance),hashMultiplier=Math.pow(10,exponent),hashAdditive=halfTolerance*hashMultiplier;for(let i=0;i<vertexCount;i++){const index=indices?indices.getX(i):i;let hash="";for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),itemSize=attribute.itemSize;for(let k=0;k<itemSize;k++)hash+=~~(attribute[getters[k]](index)*hashMultiplier+hashAdditive)+","}if(hash in hashToIndex)newIndices.push(hashToIndex[hash]);else{for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),morphAttributes=geometry.morphAttributes[name],itemSize=attribute.itemSize,newArray=tmpAttributes[name],newMorphArrays=tmpMorphAttributes[name];for(let k=0;k<itemSize;k++){const getterFunc=getters[k],setterFunc=setters[k];if(newArray[setterFunc](nextIndex,attribute[getterFunc](index)),morphAttributes)for(let m=0,ml=morphAttributes.length;m<ml;m++)newMorphArrays[m][setterFunc](nextIndex,morphAttributes[m][getterFunc](index))}}hashToIndex[hash]=nextIndex,newIndices.push(nextIndex),nextIndex++}}const result=geometry.clone();for(const name in geometry.attributes){const tmpAttribute=tmpAttributes[name];if(result.setAttribute(name,new tmpAttribute.constructor(tmpAttribute.array.slice(0,nextIndex*tmpAttribute.itemSize),tmpAttribute.itemSize,tmpAttribute.normalized)),name in tmpMorphAttributes)for(let j=0;j<tmpMorphAttributes[name].length;j++){const tmpMorphAttribute=tmpMorphAttributes[name][j];result.morphAttributes[name][j]=new tmpMorphAttribute.constructor(tmpMorphAttribute.array.slice(0,nextIndex*tmpMorphAttribute.itemSize),tmpMorphAttribute.itemSize,tmpMorphAttribute.normalized)}}return result.setIndex(newIndices),result}(xgeo),xgeo.computeVertexNormals();const uv=xgeo.attributes.uv;let x1=Math.random()*l,y1=Math.random()*(a+p);for(let i=0;i<uv.count;i++)uv.setXY(i,uv.getX(i)+x1,uv.getY(i)+y1);uv.needsUpdate=!0,gcad.geo[ky]=xgeo}return gcad.geo[ky]}function getpannello(gcad,orientamento,x,y,z,mat1,mat2,options){options||(options={});let l,a,p,{r:r,r1:r1,r2:r2,r3:r3,r4:r4,b:b,npt:npt}=options;r1=r1||r||0,r2=r2||r||0,r3=r3||r||0,r4=r4||r||0,npt=npt||2,b=b||0,(b>=x/2||b>=y/2||b>=z/2)&&(b=0),l="L"==(orientamento=orientamento.trim().toUpperCase())[0]?x:"A"==orientamento[0]?y:z,a="L"==orientamento[1]?x:"A"==orientamento[1]?y:z,p="L"==orientamento[2]?x:"A"==orientamento[2]?y:z;let grp=new THREE.Group;if(!options.nolines){let segments=edgesfromgeometry(new THREE.BoxGeometry(x,y,z));segments.position.set(x/2,y/2,z/2),grp.add(segments)}let mesh=getmesh(pannellogeometry(gcad,l,a,p,r1,r2,r3,r4,b,npt),[mat2||mgreen,mat1||mwhite]);mesh.name="pannello",mesh.layers.set(1);let m2=mesh;return b&&(mesh.position.set(b,b,b),m2=new THREE.Group,m2.add(mesh)),mesh=function meshrotate(orientamento,mesh,x=0,y=0,z=0){switch(orientamento.trim().toUpperCase()){case"LPA":mesh.rotation.y=Math.PI/2,mesh.rotation.x=Math.PI,mesh.position.set(0,z,0);break;case"ALP":mesh.rotation.x=Math.PI/2,mesh.position.set(0,x,0);break;case"APL":mesh.rotation.x=-Math.PI/2,mesh.rotation.z=-Math.PI/2;break;case"PLA":break;case"PAL":mesh.rotation.z=Math.PI/2,mesh.position.set(z,0,0);break;case"LAP":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI/2}return mesh}(orientamento,m2,l,a,p),grp.add(mesh),grp}function earcut(data,holeIndices,dim=2){const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedList(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,invSize;if(hasHoles&&(outerNode=function eliminateHoles(data,holeIndices,outerNode,dim){const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const list=linkedList(data,holeIndices[i]*dim,i<len-1?holeIndices[i+1]*dim:data.length,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort(compareXYSlope);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode);return outerNode}(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=1/0,minY=1/0;let maxX=-1/0,maxY=-1/0;for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?32767/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize,0),triangles}function linkedList(data,start,end,dim,clockwise){let last;if(clockwise===function signedArea(data,start,end,dim){let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum}(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);return last&&equals(last,last.next)&&(removeNode(last),last=last.next),last}function filterPoints(start,end){if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals(p,p.next)&&0!==area(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end}function earcutLinked(ear,triangles,dim,minX,minY,invSize,pass){if(!ear)return;!pass&&invSize&&function indexCurve(start,minX,minY,invSize){let p=start;do{0===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,function sortLinked(list){let numMerges,inSize=1;do{let e,p=list;list=null;let tail=null;for(numMerges=0;p;){numMerges++;let q=p,pSize=0;for(let i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||p.z<=q.z)?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1);return list}(p)}(ear,minX,minY,invSize);let stop=ear;for(;ear.prev!==ear.next;){const prev=ear.prev,next=ear.next;if(invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i,ear.i,next.i),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?earcutLinked(ear=cureLocalIntersections(filterPoints(ear),triangles),triangles,dim,minX,minY,invSize,2):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}}}function isEar(ear){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy);let p=c.next;for(;p!==a;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.next}return!0}function isEarHashed(ear,minX,minY,invSize){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy),minZ=zOrder(x0,y0,minX,minY,invSize),maxZ=zOrder(x1,y1,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0}function cureLocalIntersections(start,triangles){let p=start;do{const a=p.prev,b=p.next.next;!equals(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i,p.i,b.i),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)}function splitEarcut(start,triangles,dim,minX,minY,invSize){let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize,0),void earcutLinked(c,triangles,dim,minX,minY,invSize,0)}b=b.next}a=a.next}while(a!==start)}function compareXYSlope(a,b){let result=a.x-b.x;if(0===result&&(result=a.y-b.y,0===result)){result=(a.next.y-a.y)/(a.next.x-a.x)-(b.next.y-b.y)/(b.next.x-b.x)}return result}function eliminateHole(hole,outerNode){const bridge=function findHoleBridge(hole,outerNode){let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;if(equals(hole,p))return p;do{if(equals(hole,p.next))return p.next;if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx&&(qx=x,m=p.x<p.next.x?p:p.next,x===hx))return m}p=p.next}while(p!==outerNode);if(!m)return null;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&§orContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m}(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole);return filterPoints(bridgeReverse,bridgeReverse.next),filterPoints(bridge,bridge.next)}function sectorContainsSector(m,p){return area(m.prev,m,p.prev)<0&&area(p.next,m,m.next)<0}function zOrder(x,y,minX,minY,invSize){return(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=(x-minX)*invSize|0)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=(y-minY)*invSize|0)|y<<8))|y<<4))|y<<2))|y<<1))<<1}function getLeftmost(start){let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost}function pointInTriangle(ax,ay,bx,by,cx,cy,px,py){return(cx-px)*(ay-py)>=(ax-px)*(cy-py)&&(ax-px)*(by-py)>=(bx-px)*(ay-py)&&(bx-px)*(cy-py)>=(cx-px)*(by-py)}function pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,px,py){return!(ax===px&&ay===py)&&pointInTriangle(ax,ay,bx,by,cx,cy,px,py)}function isValidDiagonal(a,b){return a.next.i!==b.i&&a.prev.i!==b.i&&!function intersectsPolygon(a,b){let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1}(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&function middleInside(a,b){let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside}(a,b)&&(area(a.prev,a,b.prev)||area(a,b.prev,b))||equals(a,b)&&area(a.prev,a,a.next)>0&&area(b.prev,b,b.next)>0)}function area(p,q,r){return(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y)}function equals(p1,p2){return p1.x===p2.x&&p1.y===p2.y}function intersects(p1,q1,p2,q2){const o1=sign(area(p1,q1,p2)),o2=sign(area(p1,q1,q2)),o3=sign(area(p2,q2,p1)),o4=sign(area(p2,q2,q1));return o1!==o2&&o3!==o4||(!(0!==o1||!onSegment(p1,p2,q1))||(!(0!==o2||!onSegment(p1,q2,q1))||(!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2)))))}function onSegment(p,q,r){return q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y)}function sign(num){return num>0?1:num<0?-1:0}function locallyInside(a,b){return area(a.prev,a,a.next)<0?area(a,b,a.next)>=0&&area(a,a.prev,b)>=0:area(a,b,a.prev)<0||area(a,a.next,b)<0}function splitPolygon(a,b){const a2=createNode(a.i,a.x,a.y),b2=createNode(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2}function insertNode(i,x,y,last){const p=createNode(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p}function removeNode(p){p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)}function createNode(i,x,y){return{i:i,x:x,y:y,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function infoestrudi(shape,hshape,pts,options){options||(options={}),pts||(pts=[]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),{mi:mi,ma:ma}=shape.pt.reduce(((t,e)=>(t.mi.x=Math.min(t.mi.x,e.x),t.mi.y=Math.min(t.mi.y,e.y),t.ma.x=Math.max(t.ma.x,e.x),t.ma.y=Math.max(t.ma.y,e.y),t)),{mi:{x:1e9,y:1e9},ma:{x:-1e9,y:-1e9}}),lmax=0,lmin=1e9;function getpars(p){p.z1=getzeta(p.x,p.y,p0,coeffbase1,coeffbase2),p.z2=getzeta(p.x,p.y,p1,coefftop1,coefftop2),p.l=Math.abs(p.z2-p.z1)}for(let p of pts)getpars(p);getpars(mi),getpars(ma);let rect=[{x:mi.x,y:mi.y},{x:ma.x,y:mi.y},{x:ma.x,y:ma.y},{x:mi.x,y:ma.y}];for(let r of rect)getpars(r),r.l>lmax&&(lmax=r.l),r.l<lmin&&(lmin=r.l);return{aini:options.coeffbase1||0,aini2:options.coeffbase2||0,afin:options.coefftop1||0,afin2:options.coefftop2||0,pts:pts,mi:mi,ma:ma,rect:rect,dimx:ma.x-mi.x,dimy:ma.y-mi.y,lnom:p1-p0,lmax:lmax,lmin:lmin,lmed:(lmax+lmin)/2}}function getzeta(x,y,zbase,cx,cy){return x*cx+y*cy+zbase}function sidegeomfromshapes(gcad,ky,s1,s2,invert=!1){if(s1&&s2){if(s1.length!==s2.length)throw new Error("shapes with different length");if(s1.length<2)throw new Error("I percorsi devono contenere almeno due punti ciascuno.");if(!gcad.geo[ky]){const positions=[],uvs=[],indices=[],np=s1.length,addpts=ss=>{for(const s of ss)positions.push(s.x,s.y,s.z),uvs.push(s.u,s.v)},equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z,addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)};addpts(s1),addpts(s2);for(let i=0;i<np-1;i++){const j=i+1;equalpos(s1[i],s1[j])||addindexquad(i,j,i+np,j+np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}}function bottomgeomfromshape(gcad,inverti,outer,holes,c=0,a=0,b=0,shape=null){let ky=`bg:${c}|${a}${b}|${outer.key}|${inverti}`;for(let h of holes)ky=`${ky}|${h.key}`;if(ky=hash(ky),!gcad.geo[ky]){let triangles,pos=[],hl=[],cc=outer.pt.length;if(pos=outer.vec,Array.isArray(holes)){for(let h of holes)hl.push(cc),cc+=h.pt.length,pos=[...pos,...h.vec];triangles=earcut(pos,hl)}else triangles=earcut(pos);const geometry=new THREE.BufferGeometry,vertices=[],uvs=[],indices=[];for(let i=0;i<triangles.length;i++){const index=triangles[i],x=pos[2*index],y=-pos[2*index+1],z=getzeta(x,y,c,a,b);vertices.push(x,y,z),uvs.push(y,x)}for(let i=0;i<triangles.length;i+=3)inverti?indices.push(i,i+2,i+1):indices.push(i,i+1,i+2);geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}function estrusorotate(orientamento,mesh,z=0){switch(orientamento.trim().toUpperCase().slice(0,1)){case"A":mesh.rotation.x=-Math.PI/2;break;case"L":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI;break;case"P":mesh.rotation.z=Math.PI/2}return mesh}
|
|
624
|
+
function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),geometry;if(drawMode===TriangleFanDrawMode||drawMode===TriangleStripDrawMode){let index=geometry.getIndex();if(null===index){const indices=[],position=geometry.getAttribute("position");if(void 0===position)return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),geometry;for(let i=0;i<position.count;i++)indices.push(i);geometry.setIndex(indices),index=geometry.getIndex()}const numberOfTriangles=index.count-2,newIndices=[];if(drawMode===TriangleFanDrawMode)for(let i=1;i<=numberOfTriangles;i++)newIndices.push(index.getX(0)),newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1));else for(let i=0;i<numberOfTriangles;i++)i%2==0?(newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i+2))):(newIndices.push(index.getX(i+2)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i)));newIndices.length/3!==numberOfTriangles&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const newGeometry=geometry.clone();return newGeometry.setIndex(newIndices),newGeometry.clearGroups(),newGeometry}return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",drawMode),geometry}function pannellogeometry(gcad,l,a,p,r1=0,r2=0,r3=0,r4=0,b=0,npt=2){let ky=hash(`pg--${l}|${a}|${p}|${r1}|${r2}|${r3}|${r4}|${b}|${npt}`);if(l-=.01,a-=.01,p-=.01,!gcad.geo[ky]){l-=2*b,a-=2*b,p-=2*b;let tm=getshape();const vv=[{x:r4,y:0},{x:a-r1,y:0},{x:a,y:r1},{x:a,y:p-r2},{x:a-r2,y:p},{x:r3,y:p},{x:0,y:p-r3},{x:0,y:r4}];tm.addpt(vv[0]),tm.addpt(vv[1]),r1&&tm.addpt(raccordabezier(vv[0],vv[1],vv[2],vv[3],npt)),tm.addpt(vv[2]),tm.addpt(vv[3]),r2&&tm.addpt(raccordabezier(vv[2],vv[3],vv[4],vv[5],npt)),tm.addpt(vv[4]),tm.addpt(vv[5]),r3&&tm.addpt(raccordabezier(vv[4],vv[5],vv[6],vv[7],npt)),tm.addpt(vv[6]),tm.addpt(vv[7]),r2&&tm.addpt(raccordabezier(vv[6],vv[7],vv[0],vv[1],npt)),tm.removeduplicate(.01);let pts=tm.pt;const shape=new THREE.Shape;shape.moveTo(pts[0].x,pts[0].y);for(let i=1;i<pts.length;i++)shape.lineTo(pts[i].x,pts[i].y);shape.lineTo(pts[0].x,pts[0].y);const extrudeSettings={depth:l,bevelEnabled:b>0,bevelThickness:b,bevelSize:b,bevelSegments:1};let xgeo=new THREE.ExtrudeGeometry(shape,extrudeSettings);xgeo=function mergeVertices(geometry,tolerance=1e-4){tolerance=Math.max(tolerance,Number.EPSILON);const hashToIndex={},indices=geometry.getIndex(),positions=geometry.getAttribute("position"),vertexCount=indices?indices.count:positions.count;let nextIndex=0;const attributeNames=Object.keys(geometry.attributes),tmpAttributes={},tmpMorphAttributes={},newIndices=[],getters=["getX","getY","getZ","getW"],setters=["setX","setY","setZ","setW"];for(let i=0,l=attributeNames.length;i<l;i++){const name=attributeNames[i],attr=geometry.attributes[name];tmpAttributes[name]=new attr.constructor(new attr.array.constructor(attr.count*attr.itemSize),attr.itemSize,attr.normalized);const morphAttributes=geometry.morphAttributes[name];morphAttributes&&(tmpMorphAttributes[name]||(tmpMorphAttributes[name]=[]),morphAttributes.forEach(((morphAttr,i)=>{const array=new morphAttr.array.constructor(morphAttr.count*morphAttr.itemSize);tmpMorphAttributes[name][i]=new morphAttr.constructor(array,morphAttr.itemSize,morphAttr.normalized)})))}const halfTolerance=.5*tolerance,exponent=Math.log10(1/tolerance),hashMultiplier=Math.pow(10,exponent),hashAdditive=halfTolerance*hashMultiplier;for(let i=0;i<vertexCount;i++){const index=indices?indices.getX(i):i;let hash="";for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),itemSize=attribute.itemSize;for(let k=0;k<itemSize;k++)hash+=~~(attribute[getters[k]](index)*hashMultiplier+hashAdditive)+","}if(hash in hashToIndex)newIndices.push(hashToIndex[hash]);else{for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),morphAttributes=geometry.morphAttributes[name],itemSize=attribute.itemSize,newArray=tmpAttributes[name],newMorphArrays=tmpMorphAttributes[name];for(let k=0;k<itemSize;k++){const getterFunc=getters[k],setterFunc=setters[k];if(newArray[setterFunc](nextIndex,attribute[getterFunc](index)),morphAttributes)for(let m=0,ml=morphAttributes.length;m<ml;m++)newMorphArrays[m][setterFunc](nextIndex,morphAttributes[m][getterFunc](index))}}hashToIndex[hash]=nextIndex,newIndices.push(nextIndex),nextIndex++}}const result=geometry.clone();for(const name in geometry.attributes){const tmpAttribute=tmpAttributes[name];if(result.setAttribute(name,new tmpAttribute.constructor(tmpAttribute.array.slice(0,nextIndex*tmpAttribute.itemSize),tmpAttribute.itemSize,tmpAttribute.normalized)),name in tmpMorphAttributes)for(let j=0;j<tmpMorphAttributes[name].length;j++){const tmpMorphAttribute=tmpMorphAttributes[name][j];result.morphAttributes[name][j]=new tmpMorphAttribute.constructor(tmpMorphAttribute.array.slice(0,nextIndex*tmpMorphAttribute.itemSize),tmpMorphAttribute.itemSize,tmpMorphAttribute.normalized)}}return result.setIndex(newIndices),result}(xgeo),xgeo.computeVertexNormals();const uv=xgeo.attributes.uv;let x1=Math.random()*l,y1=Math.random()*(a+p);for(let i=0;i<uv.count;i++)uv.setXY(i,uv.getX(i)+x1,uv.getY(i)+y1);uv.needsUpdate=!0,gcad.geo[ky]=xgeo}return gcad.geo[ky]}function getpannello(gcad,orientamento,x,y,z,mat1,mat2,options){options||(options={});let l,a,p,{r:r,r1:r1,r2:r2,r3:r3,r4:r4,b:b,npt:npt}=options;r1=r1||r||0,r2=r2||r||0,r3=r3||r||0,r4=r4||r||0,npt=npt||2,b=b||0,(b>=x/2||b>=y/2||b>=z/2)&&(b=0),l="L"==(orientamento=orientamento.trim().toUpperCase())[0]?x:"A"==orientamento[0]?y:z,a="L"==orientamento[1]?x:"A"==orientamento[1]?y:z,p="L"==orientamento[2]?x:"A"==orientamento[2]?y:z;let grp=new THREE.Group;if(!options.nolines){let segments=edgesfromgeometry(new THREE.BoxGeometry(x,y,z));segments.position.set(x/2,y/2,z/2),grp.add(segments)}let mesh=getmesh(pannellogeometry(gcad,l,a,p,r1,r2,r3,r4,b,npt),[mat2||mgreen,mat1||mwhite]);mesh.name="pannello",mesh.layers.set(1);let m2=mesh;return b&&(mesh.position.set(b,b,b),m2=new THREE.Group,m2.add(mesh)),mesh=function meshrotate(orientamento,mesh,x=0,y=0,z=0){switch(orientamento.trim().toUpperCase()){case"LPA":mesh.rotation.y=Math.PI/2,mesh.rotation.x=Math.PI,mesh.position.set(0,z,0);break;case"ALP":mesh.rotation.x=Math.PI/2,mesh.position.set(0,x,0);break;case"APL":mesh.rotation.x=-Math.PI/2,mesh.rotation.z=-Math.PI/2;break;case"PLA":break;case"PAL":mesh.rotation.z=Math.PI/2,mesh.position.set(z,0,0);break;case"LAP":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI/2}return mesh}(orientamento,m2,l,a,p),grp.add(mesh),grp}function earcut(data,holeIndices,dim=2){const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedList(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,invSize;if(hasHoles&&(outerNode=function eliminateHoles(data,holeIndices,outerNode,dim){const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const list=linkedList(data,holeIndices[i]*dim,i<len-1?holeIndices[i+1]*dim:data.length,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort(compareXYSlope);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode);return outerNode}(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=1/0,minY=1/0;let maxX=-1/0,maxY=-1/0;for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?32767/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize,0),triangles}function linkedList(data,start,end,dim,clockwise){let last;if(clockwise===function signedArea(data,start,end,dim){let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum}(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);return last&&equals(last,last.next)&&(removeNode(last),last=last.next),last}function filterPoints(start,end){if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals(p,p.next)&&0!==area(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end}function earcutLinked(ear,triangles,dim,minX,minY,invSize,pass){if(!ear)return;!pass&&invSize&&function indexCurve(start,minX,minY,invSize){let p=start;do{0===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,function sortLinked(list){let numMerges,inSize=1;do{let e,p=list;list=null;let tail=null;for(numMerges=0;p;){numMerges++;let q=p,pSize=0;for(let i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||p.z<=q.z)?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1);return list}(p)}(ear,minX,minY,invSize);let stop=ear;for(;ear.prev!==ear.next;){const prev=ear.prev,next=ear.next;if(invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i,ear.i,next.i),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?earcutLinked(ear=cureLocalIntersections(filterPoints(ear),triangles),triangles,dim,minX,minY,invSize,2):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}}}function isEar(ear){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy);let p=c.next;for(;p!==a;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.next}return!0}function isEarHashed(ear,minX,minY,invSize){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy),minZ=zOrder(x0,y0,minX,minY,invSize),maxZ=zOrder(x1,y1,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0}function cureLocalIntersections(start,triangles){let p=start;do{const a=p.prev,b=p.next.next;!equals(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i,p.i,b.i),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)}function splitEarcut(start,triangles,dim,minX,minY,invSize){let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize,0),void earcutLinked(c,triangles,dim,minX,minY,invSize,0)}b=b.next}a=a.next}while(a!==start)}function compareXYSlope(a,b){let result=a.x-b.x;if(0===result&&(result=a.y-b.y,0===result)){result=(a.next.y-a.y)/(a.next.x-a.x)-(b.next.y-b.y)/(b.next.x-b.x)}return result}function eliminateHole(hole,outerNode){const bridge=function findHoleBridge(hole,outerNode){let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;if(equals(hole,p))return p;do{if(equals(hole,p.next))return p.next;if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx&&(qx=x,m=p.x<p.next.x?p:p.next,x===hx))return m}p=p.next}while(p!==outerNode);if(!m)return null;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&§orContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m}(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole);return filterPoints(bridgeReverse,bridgeReverse.next),filterPoints(bridge,bridge.next)}function sectorContainsSector(m,p){return area(m.prev,m,p.prev)<0&&area(p.next,m,m.next)<0}function zOrder(x,y,minX,minY,invSize){return(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=(x-minX)*invSize|0)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=(y-minY)*invSize|0)|y<<8))|y<<4))|y<<2))|y<<1))<<1}function getLeftmost(start){let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost}function pointInTriangle(ax,ay,bx,by,cx,cy,px,py){return(cx-px)*(ay-py)>=(ax-px)*(cy-py)&&(ax-px)*(by-py)>=(bx-px)*(ay-py)&&(bx-px)*(cy-py)>=(cx-px)*(by-py)}function pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,px,py){return!(ax===px&&ay===py)&&pointInTriangle(ax,ay,bx,by,cx,cy,px,py)}function isValidDiagonal(a,b){return a.next.i!==b.i&&a.prev.i!==b.i&&!function intersectsPolygon(a,b){let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1}(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&function middleInside(a,b){let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside}(a,b)&&(area(a.prev,a,b.prev)||area(a,b.prev,b))||equals(a,b)&&area(a.prev,a,a.next)>0&&area(b.prev,b,b.next)>0)}function area(p,q,r){return(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y)}function equals(p1,p2){return p1.x===p2.x&&p1.y===p2.y}function intersects(p1,q1,p2,q2){const o1=sign(area(p1,q1,p2)),o2=sign(area(p1,q1,q2)),o3=sign(area(p2,q2,p1)),o4=sign(area(p2,q2,q1));return o1!==o2&&o3!==o4||(!(0!==o1||!onSegment(p1,p2,q1))||(!(0!==o2||!onSegment(p1,q2,q1))||(!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2)))))}function onSegment(p,q,r){return q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y)}function sign(num){return num>0?1:num<0?-1:0}function locallyInside(a,b){return area(a.prev,a,a.next)<0?area(a,b,a.next)>=0&&area(a,a.prev,b)>=0:area(a,b,a.prev)<0||area(a,a.next,b)<0}function splitPolygon(a,b){const a2=createNode(a.i,a.x,a.y),b2=createNode(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2}function insertNode(i,x,y,last){const p=createNode(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p}function removeNode(p){p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)}function createNode(i,x,y){return{i:i,x:x,y:y,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function unifyVertices(vertices,uvs,indices){const vertMap=new Map,verticesOut=[],uvsOut=[],indicesOut=[];for(let i=0;i<indices.length;i++){const idx=indices[i],vx=vertices[3*idx+0],vy=vertices[3*idx+1],vz=vertices[3*idx+2],ux=uvs[2*idx+0],uy=uvs[2*idx+1],key=`${vx},${vy},${vz}|${ux},${uy}`;if(vertMap.has(key))indicesOut.push(vertMap.get(key));else{const newIndex=verticesOut.length/3;vertMap.set(key,newIndex),verticesOut.push(vx,vy,vz),uvsOut.push(ux,uy),indicesOut.push(newIndex)}}return{vertices:verticesOut,uvs:uvsOut,indices:indicesOut}}function infoestrudi(shape,hshape,pts,options,sh){options||(options={}),pts||(pts=[]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),{mi:mi,ma:ma}=shape.pt.reduce(((t,e)=>(t.mi.x=Math.min(t.mi.x,e.x),t.mi.y=Math.min(t.mi.y,e.y),t.ma.x=Math.max(t.ma.x,e.x),t.ma.y=Math.max(t.ma.y,e.y),t)),{mi:{x:1e9,y:1e9},ma:{x:-1e9,y:-1e9}}),lmax=0,lmin=1e9;function getpars(p){p.z1=getzeta(p.x,p.y,p0,coeffbase1,coeffbase2,sh),p.z2=getzeta(p.x,p.y,p1,coefftop1,coefftop2,sh),p.l=Math.abs(p.z2-p.z1)}for(let p of pts)getpars(p);getpars(mi),getpars(ma);let rect=[{x:mi.x,y:mi.y},{x:ma.x,y:mi.y},{x:ma.x,y:ma.y},{x:mi.x,y:ma.y}];for(let r of rect)getpars(r),r.l>lmax&&(lmax=r.l),r.l<lmin&&(lmin=r.l);return{aini:options.coeffbase1||0,aini2:options.coeffbase2||0,afin:options.coefftop1||0,afin2:options.coefftop2||0,pts:pts,mi:mi,ma:ma,rect:rect,dimx:ma.x-mi.x,dimy:ma.y-mi.y,lnom:p1-p0,lmax:lmax,lmin:lmin,lmed:(lmax+lmin)/2}}function getzeta(x,y,zbase,cx,cy,sh,invert=!1){let z=x*cx+y*cy+zbase;if(sh){let t=sh.xfromy(-y,0,!0);invert?z-=t:z=t}return z}function sidegeomfromshapes(gcad,ky,s1,s2,invert=!1,stonda=!1){if(s1&&s2){if(s1.length!==s2.length)throw new Error("shapes with different length");if(s1.length<2)throw new Error("I percorsi devono contenere almeno due punti ciascuno.");if(!gcad.geo[ky]){const vertices=[],uvs=[],indices=[],np=s1.length,addpts=ss=>{for(const s of ss)vertices.push(s.x,s.y,s.z),uvs.push(s.u,s.v)},equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z,addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)};addpts(s1),addpts(s2);for(let i=0;i<np-1;i++){const j=i+1;equalpos(s1[i],s1[j])||addindexquad(i,j,i+np,j+np)}const geometry=new THREE.BufferGeometry;if(stonda){let tm=unifyVertices(vertices,uvs,indices);geometry.setAttribute("position",new THREE.Float32BufferAttribute(tm.vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(tm.uvs,2)),geometry.setIndex(tm.indices)}else geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices);geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}}function bottomgeomfromshape(gcad,inverti,outer,holes,c=0,a=0,b=0,shape=null,stonda=!1){let ky=`bg:${c}|${a}${b}|${outer.key}|${inverti}|${shape?.key||""}`;for(let h of holes)ky=`${ky}|${h.key}`;if(ky=hash(ky),!gcad.geo[ky]){let triangles,pos=[],hl=[],cc=outer.pt.length;pos=outer.vec;const geometry=new THREE.BufferGeometry,vertices=[],uvs=[],indices=[];function addvertexes(triangles,pos){let i0=vertices.length/3;for(let i=0;i<triangles.length;i++){const index=triangles[i],x=pos[2*index],y=-pos[2*index+1],z=getzeta(x,y,c,a,b,shape,inverti);vertices.push(x,y,z),uvs.push(y,x)}for(let i=0;i<triangles.length;i+=3)inverti?indices.push(i+i0,i+i0+2,i+i0+1):indices.push(i+i0,i+i0+1,i+i0+2)}if(shape){let cl2=outer.sliceony(shape);for(let c of cl2){let x=c.flatMap((p=>[p.x,p.y]));addvertexes(earcut(x,[]),x)}}else if(Array.isArray(holes)&&holes.length){for(let h of holes)hl.push(cc),cc+=h.pt.length,pos=[...pos,...h.vec];triangles=earcut(pos,hl),addvertexes(triangles,pos)}else triangles=earcut(pos),addvertexes(triangles,pos);if(stonda){let tm=unifyVertices(vertices,uvs,indices);geometry.setAttribute("position",new THREE.Float32BufferAttribute(tm.vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(tm.uvs,2)),geometry.setIndex(tm.indices)}else geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices);geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}function estrusorotate(orientamento,mesh,z=0){switch(orientamento.trim().toUpperCase().slice(0,1)){case"A":mesh.rotation.x=-Math.PI/2;break;case"L":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI;break;case"P":mesh.rotation.z=Math.PI/2}return mesh}
|
|
625
625
|
/**
|
|
626
626
|
* Crea una geometria estrusa con opzioni avanzate
|
|
627
627
|
* @param {string} orient - Orientamento dell'estrusione
|
|
@@ -631,7 +631,7 @@ function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)
|
|
|
631
631
|
* @param {Array} mats - Array di materiali
|
|
632
632
|
* @param {Object} options - Opzioni di configurazione
|
|
633
633
|
* @returns {THREE.Group} Gruppo contenente la geometria estrusa
|
|
634
|
-
*/function estruso(gcad,orient,hshape,shape,holes,mats,options){options||(options={}),mats||(mats=[]),Array.isArray(mats)||(mats=[mats,mats,mats]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),shapetop=options.shapetop,shapebase=options.shapebase||options.shapebottom;shapetop&&(coefftop2=0),shapebase&&(coefftop2=0);let shb=shapebase?shapebase.key:"",sht=shapetop?shapetop.key:"",opinvert=options.invert||!1,open=options.open||!1,grp=new THREE.Group;if(shape){if(!options.nobase
|
|
634
|
+
*/function estruso(gcad,orient,hshape,shape,holes,mats,options){options||(options={}),mats||(mats=[]),Array.isArray(mats)||(mats=[mats,mats,mats]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),shapetop=options.shapetop,shapebase=options.shapebase||options.shapebottom;shapetop&&(coefftop2=0),shapebase&&(coefftop2=0);let shb=shapebase?shapebase.key:"",sht=shapetop?shapetop.key:"",opinvert=options.invert||!1,open=options.open||!1,grp=new THREE.Group;if(shape){if(!options.nobase){let g1=bottomgeomfromshape(gcad,!1,shape,open?[]:holes,p0,coeffbase1,coeffbase2,shapebase);options.nolines||grp.add(edgesfromgeometry(g1)),grp.add(getmesh(g1,mats[0]||mwhite))}if(!options.notop){let g3=bottomgeomfromshape(gcad,!0,shape,open?[]:holes,p1,coefftop1,coefftop2,shapetop);grp.add(getmesh(g3,mats[1]||mats[0]||mwhite)),options.nolines||grp.add(edgesfromgeometry(g3))}if(!options.nosides){let pat1=shape.to3d(0,p0,coeffbase1,-coeffbase2,open,shapebase,!opinvert),pat2=shape.to3d(1,p1,coefftop1,-coefftop2,open,shapetop,opinvert),ky=`${shape.key}${opinvert?1:0}|${p0}|${p1}|${coeffbase1}|${coeffbase2||shb}|${coefftop1}|${coefftop2||sht}|${open}`,geo1=sidegeomfromshapes(gcad,ky,pat1,pat2,!1);if(options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),holes&&!open)for(var h of holes){pat1=h.to3d(0,p0,coeffbase1,coeffbase2),pat2=h.to3d(0,p1,coefftop1,coefftop2),ky=`${h.key}|${p0}|${p1}|${coeffbase1}|${coeffbase2}|${coefftop1}|${coefftop2}`;let geo2=sidegeomfromshapes(gcad,ky,pat1,pat2,!0);options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo2)),grp.add(getmesh(geo2,mats[3]||mats[0]||mwhite))}}return estrusorotate(orient,grp,hshape)}return grp}function revolve(gcad,shape,orient,mat,options){options||(options={});let segmenti=options.segmenti??12,ky=hash(`rev|${shape.key}|${orient}|${segmenti}`),geometria=gcad.geo[ky],grp=new THREE.Group;if(!geometria){const punti3D=shape.pt.map((p=>new THREE.Vector3(p.x,p.y,0)));geometria=new THREE.LatheGeometry(punti3D,segmenti,0,2*Math.PI),gcad.geo[ky]=geometria}const mesh=new THREE.Mesh(geometria,mat);return grp.add(mesh),options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geometria)),grp}
|
|
635
635
|
/**
|
|
636
636
|
* Crea una geometria estrusa con opzioni avanzate
|
|
637
637
|
* @param {string} orient - Orientamento dell'estrusione
|
|
@@ -641,7 +641,7 @@ function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)
|
|
|
641
641
|
* @param {Array} mats - Array di materiali
|
|
642
642
|
* @param {Object} options - Opzioni di configurazione
|
|
643
643
|
* @returns {THREE.Group} Gruppo contenente la geometria estrusa
|
|
644
|
-
*/function estrusopat(gcad,orient,pat,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase){let gb=new THREE.Group,g1=bottomgeomfromshape(gcad,!1,shape,[],0,0,0);gb.add(getmesh(g1,mats[0]||mwhite)),gb.add(edgesfromgeometry(g1));let seg1=pat.infosegmento(0,!0);grp.add(posiziona(gb,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}if(!options.notop){let gt=new THREE.Group,g2=bottomgeomfromshape(gcad,!0,shape,[],0,0,0);gt.add(getmesh(g2,mats[1]||mats[0]||mwhite)),gt.add(edgesfromgeometry(g2));let seg1=pat.infosegmento(pat.pt.length-1,!0);grp.add(posiziona(gt,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}const geo1=function sidegeomfrompat(gcad,pbase,pat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${invert}`;if(ky=hash(ky),!gcad.geo[ky]){const
|
|
644
|
+
*/function estrusopat(gcad,orient,pat,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase){let gb=new THREE.Group,g1=bottomgeomfromshape(gcad,!1,shape,[],0,0,0);gb.add(getmesh(g1,mats[0]||mwhite)),gb.add(edgesfromgeometry(g1));let seg1=pat.infosegmento(0,!0);grp.add(posiziona(gb,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}if(!options.notop){let gt=new THREE.Group,g2=bottomgeomfromshape(gcad,!0,shape,[],0,0,0);gt.add(getmesh(g2,mats[1]||mats[0]||mwhite)),gt.add(edgesfromgeometry(g2));let seg1=pat.infosegmento(pat.pt.length-1,!0);grp.add(posiziona(gt,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}const geo1=function sidegeomfrompat(gcad,pbase,pat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${invert}`;if(ky=hash(ky),!gcad.geo[ky]){const vertices=[],uvs=[],indices=[],np=pbase.length,lp=pat.pt.length,equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z;let l0=0;for(let ii=0;ii<lp;ii++){const addpts=(ss,mat,deltav)=>{for(const s of ss){let p=new THREE.Vector3(s.x,s.y,s.z);p.applyMatrix4(mat),vertices.push(p.x,p.y,p.z),uvs.push(s.u,s.v+deltav)}};let seg1=pat.infosegmento(ii,!0),obj=new THREE.Object3D;obj.position.set(seg1.x,0,seg1.y),obj.rotation.set(0,(90-seg1.ang)*PIF,0),obj.updateMatrix(),addpts(pbase,obj.matrix,l0),l0+=seg1.l}for(let li=0;li<lp-1;li++)for(let i=0;i<np-1;i++){const addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)},j=i+1;equalpos(pbase[i],pbase[j])||addindexquad(i+li*np,j+li*np,i+(li+1)*np,j+(li+1)*np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad[ky]=geometry}return gcad[ky]}(gcad,pbase,pat,invert);return options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),estrusorotate(orient,grp,0)}async function spritemat(gcad,file){try{let tm={transparent:!0,depthTest:!1,depthWrite:!1,fog:!1,toneMapped:!1};if(file.startsWith("#"))tm.color=file;else{let tx=await gcad.tex(file,1e3,1e3);tx?tm.map=tx:tm.color="black"}return new THREE.SpriteMaterial(tm)}catch(error){return mwhite}}function getsprite0(ispunto,x,y,z,mat,options={}){options||(options={});let{size:size=50,pick:pick=!1,screen:screen=!1,sizex:sizex,sizey:sizey}=options;const sprite=new THREE.Sprite(mat);sprite.position.set(0,0,0),sprite.userData.issprite=!0,sprite.userData.ispunto=ispunto,sprite.userData.ispick=pick,sprite.userData.isScreen=screen,sprite.renderOrder=999,sprite.layers.set(29),sprite.name=ispunto?"_punto":"_sprite";let gr=new THREE.Group;return gr.position.set(x,y,z),gr.scale.set(sizex||size,sizey||sizex||size,1),gr.add(sprite),gr.traverse((obj=>{obj.material&&(obj.material.depthTest=!1,obj.material.depthWrite=!1)})),gr.renderOrder=999,gr}async function getpunto(gcad,x,y,z,color="yellow",options){options||(options={size:20}),options.screen=!0;const texture=await function createCircleTexture(gcad,size=64,color="rgba(255,0,0,1)"){const ky=`ct|${size}|${color}`;if(!gcad.textures[ky]){const canvas=document.createElement("canvas");canvas.width=canvas.height=size;const ctx=canvas.getContext("2d"),radius=size/2;ctx.clearRect(0,0,size,size),ctx.fillStyle=color,ctx.beginPath(),ctx.arc(radius,radius,radius,0,2*Math.PI),ctx.fill();const texture=new THREE.CanvasTexture(canvas);texture.needsUpdate=!0,gcad.textures[ky]=texture}return gcad.textures[ky]}(gcad,64,color);return getsprite0(!0,x,y,z,new THREE.SpriteMaterial({map:texture,transparent:!0,fog:!1,toneMapped:!1}),options)}function getsprite(gcad,x,y,z,mat,options={}){return getsprite0(!1,x,y,z,mat,options)}class GLTFLoader extends Loader{constructor(manager){super(manager),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register((function(parser){return new GLTFMaterialsClearcoatExtension(parser)})),this.register((function(parser){return new GLTFMaterialsDispersionExtension(parser)})),this.register((function(parser){return new GLTFTextureBasisUExtension(parser)})),this.register((function(parser){return new GLTFTextureWebPExtension(parser)})),this.register((function(parser){return new GLTFTextureAVIFExtension(parser)})),this.register((function(parser){return new GLTFMaterialsSheenExtension(parser)})),this.register((function(parser){return new GLTFMaterialsTransmissionExtension(parser)})),this.register((function(parser){return new GLTFMaterialsVolumeExtension(parser)})),this.register((function(parser){return new GLTFMaterialsIorExtension(parser)})),this.register((function(parser){return new GLTFMaterialsEmissiveStrengthExtension(parser)})),this.register((function(parser){return new GLTFMaterialsSpecularExtension(parser)})),this.register((function(parser){return new GLTFMaterialsIridescenceExtension(parser)})),this.register((function(parser){return new GLTFMaterialsAnisotropyExtension(parser)})),this.register((function(parser){return new GLTFMaterialsBumpExtension(parser)})),this.register((function(parser){return new GLTFLightsExtension(parser)})),this.register((function(parser){return new GLTFMeshoptCompression(parser)})),this.register((function(parser){return new GLTFMeshGpuInstancing(parser)}))}load(url,onLoad,onProgress,onError){const scope=this;let resourcePath;if(""!==this.resourcePath)resourcePath=this.resourcePath;else if(""!==this.path){const relativeUrl=LoaderUtils.extractUrlBase(url);resourcePath=LoaderUtils.resolveURL(relativeUrl,this.path)}else resourcePath=LoaderUtils.extractUrlBase(url);this.manager.itemStart(url);const _onError=function(e){onError?onError(e):console.error(e),scope.manager.itemError(url),scope.manager.itemEnd(url)},loader=new FileLoader(this.manager);loader.setPath(this.path),loader.setResponseType("arraybuffer"),loader.setRequestHeader(this.requestHeader),loader.setWithCredentials(this.withCredentials),loader.load(url,(function(data){try{scope.parse(data,resourcePath,(function(gltf){onLoad(gltf),scope.manager.itemEnd(url)}),_onError)}catch(e){_onError(e)}}),onProgress,_onError)}setDRACOLoader(dracoLoader){return this.dracoLoader=dracoLoader,this}setDDSLoader(){throw new Error('THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".')}setKTX2Loader(ktx2Loader){return this.ktx2Loader=ktx2Loader,this}setMeshoptDecoder(meshoptDecoder){return this.meshoptDecoder=meshoptDecoder,this}register(callback){return-1===this.pluginCallbacks.indexOf(callback)&&this.pluginCallbacks.push(callback),this}unregister(callback){return-1!==this.pluginCallbacks.indexOf(callback)&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback),1),this}parse(data,path,onLoad,onError){let json;const extensions={},plugins={},textDecoder=new TextDecoder;if("string"==typeof data)json=JSON.parse(data);else if(data instanceof ArrayBuffer){if(textDecoder.decode(new Uint8Array(data,0,4))===BINARY_EXTENSION_HEADER_MAGIC){try{extensions[EXTENSIONS.KHR_BINARY_GLTF]=new GLTFBinaryExtension(data)}catch(error){return void(onError&&onError(error))}json=JSON.parse(extensions[EXTENSIONS.KHR_BINARY_GLTF].content)}else json=JSON.parse(textDecoder.decode(data))}else json=data;if(void 0===json.asset||json.asset.version[0]<2)return void(onError&&onError(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.")));const parser=new GLTFParser(json,{path:path||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});parser.fileLoader.setRequestHeader(this.requestHeader);for(let i=0;i<this.pluginCallbacks.length;i++){const plugin=this.pluginCallbacks[i](parser);plugin.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),plugins[plugin.name]=plugin,extensions[plugin.name]=!0}if(json.extensionsUsed)for(let i=0;i<json.extensionsUsed.length;++i){const extensionName=json.extensionsUsed[i],extensionsRequired=json.extensionsRequired||[];switch(extensionName){case EXTENSIONS.KHR_MATERIALS_UNLIT:extensions[extensionName]=new GLTFMaterialsUnlitExtension;break;case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:extensions[extensionName]=new GLTFDracoMeshCompressionExtension(json,this.dracoLoader);break;case EXTENSIONS.KHR_TEXTURE_TRANSFORM:extensions[extensionName]=new GLTFTextureTransformExtension;break;case EXTENSIONS.KHR_MESH_QUANTIZATION:extensions[extensionName]=new GLTFMeshQuantizationExtension;break;default:extensionsRequired.indexOf(extensionName)>=0&&void 0===plugins[extensionName]&&console.warn('THREE.GLTFLoader: Unknown extension "'+extensionName+'".')}}parser.setExtensions(extensions),parser.setPlugins(plugins),parser.parse(onLoad,onError)}parseAsync(data,path){const scope=this;return new Promise((function(resolve,reject){scope.parse(data,path,resolve,reject)}))}}function GLTFRegistry(){let objects={};return{get:function(key){return objects[key]},add:function(key,object){objects[key]=object},remove:function(key){delete objects[key]},removeAll:function(){objects={}}}}
|
|
645
645
|
/*********************************/
|
|
646
646
|
/********** EXTENSIONS ***********/
|
|
647
647
|
/*********************************/const EXTENSIONS={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};
|
package/package.json
CHANGED
package/types/markcad.d.ts
CHANGED
|
@@ -549,7 +549,7 @@ export function getsubrules(nodocorrente: any): ({
|
|
|
549
549
|
*/ export function gettarghetta(gcad: any, testo: any[] | string, dim?: number, options?: any): THREE.Mesh;
|
|
550
550
|
export function groupfromgeometry(geometry: any, material: any, x: any, y: any, z: any, name: any, layer: any): any;
|
|
551
551
|
export function hash(obj: any): string;
|
|
552
|
-
export function infoestrudi(shape: any, hshape: any, pts: any, options: any): {
|
|
552
|
+
export function infoestrudi(shape: any, hshape: any, pts: any, options: any, sh: any): {
|
|
553
553
|
aini: any;
|
|
554
554
|
aini2: any;
|
|
555
555
|
afin: any;
|