markuno_lib 1.2.33 → 1.2.35

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 CHANGED
@@ -270,7 +270,7 @@ function tovec(){return pt.flatMap((p=>[p.x,p.y]))}function move(x=0,y=0){"objec
270
270
  * Aggiunge punti da array di coordinate
271
271
  * @param {Array<number>} aa - Array [x1,y1,x2,y2,...]
272
272
  */
273
- function _addvec(aa){for(let i=0;i<aa.length;i+=2)pt.push({x:aa[i],y:aa[i+1]})}function 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}function dims(pts){let{p1:p1,p2:p2}=pts.reduce(((m,p)=>(m.p1.x=Math.min(m.p1.x,p.x),m.p2.x=Math.max(m.p2.x,p.x),m.p1.y=Math.min(m.p1.y,p.y),m.p2.y=Math.max(m.p2.y,p.y),m)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}),isrect=!1;if(4==pts.length){const TOLL=.001;function findpunto(x,y){let f=pts.find((p=>Math.abs(p.x-x)<TOLL&&Math.abs(p.y-y)<TOLL));return!!f}findpunto(p1.x,p1.y)&&findpunto(p1.x,p2.y)&&findpunto(p2.x,p1.y)&&findpunto(p2.x,p2.y)&&(isrect=!0)}return{p1:p1,p2:p2,isrect:isrect,width:p2.x-p1.x,height:p2.y-p1.y}}return{get key(){return hash(tovec().join("\t"))},orienta:function orienta(p0,p1){if(!p0||!p1)return null;const dx=p1.x-p0.x,dy=p1.y-p0.y,angolo=180*Math.atan2(dy,dx)/Math.PI,matrix=new Matrix3D;matrix.rotateZ(-angolo),matrix.translate(-p0.x,-p0.y,0);const ptTrasformati=pt.map((p=>matrix.transform(p.x,p.y)));let mm=ptTrasformati.reduce(((m,p)=>(m.p1.x=Math.min(m.p1.x,p.x),m.p2.x=Math.max(m.p2.x,p.x),m.p1.y=Math.min(m.p1.y,p.y),m.p2.y=Math.max(m.p2.y,p.y),m)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)});return{shape:getshape().frompt(ptTrasformati),origine:new Punto2(p0.x,p0.y),angolo:angolo,mm:mm,width:mm.p2.x-mm.p1.x,height:mm.p2.y-mm.p1.y}},rebase:function rebase(angolo,forceorigin=!1,ox=0,oy=0){const matrix=new Matrix3D;matrix.rotateZ(-angolo);let ptTrasformati=pt.map((p=>matrix.transform(p.x,p.y))),{p1:p1,p2:p2,width:width,height:height}=dims(ptTrasformati);return forceorigin||(ox=p1.x,oy=p1.y),ptTrasformati=ptTrasformati.map((p=>new Punto2(p.x-ox,p.y-oy))),{shape:getshape().frompt(ptTrasformati),origine:new Punto2(ox,oy),angolo:angolo,width:width,height:height}},fromstr:fromstr,move:move,get pt(){return pt},set pt(val){Array.isArray(val)&&(pt=val)},get npt(){return pt?.length||0},get vec(){return tovec()},toJSON:()=>({vec:tovec(),orient:orientation()}),get orient(){return orientation()},corners:(angolo=45)=>
273
+ function _addvec(aa){for(let i=0;i<aa.length;i+=2)pt.push({x:aa[i],y:aa[i+1]})}function 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])||0;if(dist>0){const npt=parseInt(token.params[1])||Math.min(dist,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}function dims(pts){let{p1:p1,p2:p2}=pts.reduce(((m,p)=>(m.p1.x=Math.min(m.p1.x,p.x),m.p2.x=Math.max(m.p2.x,p.x),m.p1.y=Math.min(m.p1.y,p.y),m.p2.y=Math.max(m.p2.y,p.y),m)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}),isrect=!1;if(4==pts.length){const TOLL=.001;function findpunto(x,y){let f=pts.find((p=>Math.abs(p.x-x)<TOLL&&Math.abs(p.y-y)<TOLL));return!!f}findpunto(p1.x,p1.y)&&findpunto(p1.x,p2.y)&&findpunto(p2.x,p1.y)&&findpunto(p2.x,p2.y)&&(isrect=!0)}return{p1:p1,p2:p2,isrect:isrect,width:p2.x-p1.x,height:p2.y-p1.y}}return{get key(){return hash(tovec().join("\t"))},orienta:function orienta(p0,p1){if(!p0||!p1)return null;const dx=p1.x-p0.x,dy=p1.y-p0.y,angolo=180*Math.atan2(dy,dx)/Math.PI,matrix=new Matrix3D;matrix.rotateZ(-angolo),matrix.translate(-p0.x,-p0.y,0);const ptTrasformati=pt.map((p=>matrix.transform(p.x,p.y)));let mm=ptTrasformati.reduce(((m,p)=>(m.p1.x=Math.min(m.p1.x,p.x),m.p2.x=Math.max(m.p2.x,p.x),m.p1.y=Math.min(m.p1.y,p.y),m.p2.y=Math.max(m.p2.y,p.y),m)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)});return{shape:getshape().frompt(ptTrasformati),origine:new Punto2(p0.x,p0.y),angolo:angolo,mm:mm,width:mm.p2.x-mm.p1.x,height:mm.p2.y-mm.p1.y}},rebase:function rebase(angolo,forceorigin=!1,ox=0,oy=0){const matrix=new Matrix3D;matrix.rotateZ(-angolo);let ptTrasformati=pt.map((p=>matrix.transform(p.x,p.y))),{p1:p1,p2:p2,width:width,height:height}=dims(ptTrasformati);return forceorigin||(ox=p1.x,oy=p1.y),ptTrasformati=ptTrasformati.map((p=>new Punto2(p.x-ox,p.y-oy))),{shape:getshape().frompt(ptTrasformati),origine:new Punto2(ox,oy),angolo:angolo,width:width,height:height}},fromstr:fromstr,move:move,get pt(){return pt},set pt(val){Array.isArray(val)&&(pt=val)},get npt(){return pt?.length||0},get vec(){return tovec()},toJSON:()=>({vec:tovec(),orient:orientation()}),get orient(){return orientation()},corners:(angolo=45)=>
274
274
  /**
275
275
  * Trova i punti in cui l’angolo interno è maggiore di `thresholdDeg`.
276
276
  *
@@ -504,7 +504,7 @@ ClipperLib.ExPolygon=function(){this.outer=null,this.holes=null},ClipperLib.JS.A
504
504
  * @property {Function} inflate - Espande o contrae una forma
505
505
  * @property {Function} unisci - Unisce più forme con gestione di fori e tagli
506
506
  */
507
- function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if(n1<1||n2<1)return sag2.slice();let bestOffset=0,minSum=1/0;for(let k=0;k<n2;k++){const p0=sag1[0],q0=sag2[k%n2],dx0=p0.x-q0.x,dy0=p0.y-q0.y,p1=sag1[n1-1],q1=sag2[isopen?Math.min(k+n1-1,n2-1):(k+n1-1)%n2],dx1=p1.x-q1.x,dy1=p1.y-q1.y,sum=dx0*dx0+dy0*dy0+dx1*dx1+dy1*dy1;sum<minSum&&(minSum=sum,bestOffset=k)}return[...sag2.slice(bestOffset),...sag2.slice(0,bestOffset)]}function shapeclip(){function toclipformat(pts){let tm=pts.map((e=>({X:Math.round(1e4*e.x),Y:Math.round(1e4*e.y)})));return ensureOrientation(tm)}function fromclipformat(pts){return pts.map((e=>({x:e.X/1e4,y:e.Y/1e4})))}const ensureOrientation=poly=>ClipperLib.Clipper.Orientation(poly)?poly:poly.slice().reverse();function orientation(pt){if(!pt.length)return 0;let area=0;const n=pt.length;for(let i=0;i<n;i++){const current=pt[i],next=pt[(i+1)%n];area+=current.X*next.Y-next.X*current.Y}return area>0?1:area<0?-1:0}const _inflate=(pt,delta,cut=!1)=>{const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.AddPath(pt,ClipperLib.JoinType.jtMiter,cut||2==pt.length?ClipperLib.EndType.etOpenButt:ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;return co.Execute(solution,delta),solution};function _inflateopen(pts,delta){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*delta,pshape=toclipformat(pts);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return getshape().frompt(tm)}return{offset(shape,delta,full=!1){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*Math.abs(delta),pshape=toclipformat(shape.pt);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etOpenButt);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return full?getshape().frompt(tm):getshape().frompt(getptsoffset(shape.pt,tm,delta))},inflate:function inflate(shape,delta=2,mantainorder=!1,isopen=0){let pshape=toclipformat(shape.pt),tm=_inflate(pshape,1e4*delta);if(!tm||!tm.length)return getshape().frompt([]);let p2=getshape().frompt(fromclipformat(tm[0]));if(mantainorder){p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,isopen);if(p2.frompt(p3),isopen>0&&shape.pt.length>=3){function estendi1(sh1,sh2){let l1=sh1.segment(0).ruotata(-Math.PI/2,200,!0),l2=sh1.segment(-2).ruotata(-Math.PI/2,200),q2=sh2.segment(-2).interseca(l2),q1=sh2.segment(0).interseca(l1);q1&&(sh2.pt[0]=q1),q2&&(sh2.pt[sh2.pt.length-1]=q2)}function estendi2(sh1,sh2){let lfin=sh1.segment(-1),l2=sh2.segment(0),q1=lfin.interseca(l2);q1&&(sh2.pt[0]=q1),l2=sh2.segment(-2);let q2=lfin.interseca(l2);q2&&(sh2.pt[sh2.pt.length-1]=q2)}1==isopen?estendi1(shape,p2):estendi2(shape,p2)}}return p2},inflateopen:_inflateopen,inflateclose(shape,delta){let p2=_inflateopen(shape.pt,delta);p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,0);return p2.frompt(p3),p2},inflatecornici(shape,delta=2,linetruncateini,linetruncateend){let l1=new Linea2(shape.pt[0],shape.pt[shape.npt-1]),len1=l1.len,l2=l1.perpendicolare(l1.p1,len1),l3=l1.perpendicolare(l1.p2,len1);l2.isparallela(shape.segment(0))&&(l2=l1.perpendicolare(l1.puntot(.1),len1)),l3.isparallela(shape.segment(shape.npt-2))&&(l3=l1.perpendicolare(l1.puntot(.9),len1));let n2=Math.floor(shape.npt/2),{t:t}=l2.proiezionet(shape.pt[n2]),t2=2*(t>0?-1:1),px2=l2.puntot(t2),px3=l3.puntot(t2),p2=_inflateopen([...shape.pt,px3,px2],delta),idx=p2.pt.reduce(((imin,p,i)=>(p.x-px2.x)**2+(p.y-px2.y)**2<(p2.pt[imin].x-px2.x)**2+(p2.pt[imin].y-px2.y)**2?i:imin),0);return p2.pt=p2.pt.slice(idx+2).concat(p2.pt.slice(0,idx)),p2.orient!=shape.orient&&p2.reverse(),linetruncateini&&(shape.truncatebefore(linetruncateini),p2.truncatebefore(linetruncateini)),linetruncateend&&(p2.truncateafter(linetruncateend),shape.truncateafter(linetruncateend)),p2},intersecasplitter(areabase,forma1){const clipper=new ClipperLib.Clipper,pt1=[toclipformat(forma1.pt)],pt2=[toclipformat(areabase.pt)];clipper.AddPaths(pt1,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(pt2,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;let res;if(clipper.Execute(ClipperLib.ClipType.ctIntersection,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)&&solution.length>0){const path=solution[0];if(1===orientation(path)){res=getshape().frompt(fromclipformat(path)),res.orient!=forma1.orient&&res.reverse();for(let iu=0;iu<forma1.pt.length;iu++){let p2=forma1.pt[iu],id=res.pt.findIndex((p=>Math.abs(p.x-p2.x)<.01&&Math.abs(p.y-p2.y)<.01));if(id>0){id-=iu,0!=id&&res.selezionaprimo(id);break}}}}return res},offsetpts(pts,delta=.01){const DELTA=1e4*delta;let tm=_inflate(toclipformat(pts),DELTA);if(tm&&tm.length)return fromclipformat(tm[0])},areesplitter(shapept,clipspt,useInflatedClipping=!0){if(!Array.isArray(shapept)||shapept.length<3)return;if(!clipspt||0==clipspt.length)return[shapept];const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;let shape_in=useInflatedClipping?_inflate(toclipformat(shapept),-100):[toclipformat(shapept)],clips_in=useInflatedClipping?clipspt.flatMap((c=>_inflate(toclipformat(c),100))):clipspt.map((c=>toclipformat(c)));for(let s of shape_in)subj.push(s);for(let c of clips_in)clip.push(c);const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(!clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero))return;let res=[];for(let x of solution)if(useInflatedClipping){const restored=_inflate(x,100);for(const r of restored)1===orientation(r)&&res.push(fromclipformat(r))}else if(x.length>4&&1==orientation(x)){const cleaned=_inflate(x,-100);if(cleaned.length>0)for(let cc of cleaned){const restored=_inflate(cc,100);for(const rr of restored)1===orientation(rr)&&res.push(fromclipformat(rr))}}else 1==orientation(x)&&res.push(fromclipformat(x));return res},unisci(shapes,holes,cuts){const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;for(let hh of shapes){let h2=[toclipformat(hh.pt)];for(let h of h2)subj.push(h)}if(holes&&holes.length)for(let hh of holes){let h1=toclipformat(hh.pt);clip.push(h1)}if(cuts&&cuts.length)for(let hh of cuts){let h1=toclipformat(hh.pt),h2=_inflate(h1,1,!0);for(let h of h2)clip.push(h)}const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)){let res=[],holes=[];for(let x of solution)if(1==orientation(x)){let yy=[x];for(let y of yy)res.push({shape:getshape().frompt(fromclipformat(y)),holes:[]})}else holes.push(getshape().frompt(fromclipformat(x)));for(let h of holes)for(let s of res)if(s.shape.pointinshape(h.pt[0])){s.holes.push(h);break}return res}return[]}}}class Vis2d{constructor(name,scalalinea=1){this.name=name,this.clear(scalalinea)}clear(scalalinea=1){return this.vec=[],this.gr={},this._sl=scalalinea,this}creategr(name="grp"){return this.gr[name]||(this.gr[name]=new Vis2d(name,this._sl)),this.gr[name]}push(x=0,y=0,op={}){"number"==typeof op&&(op={rot:op}),op||(op={}),this.vec.push({type:"push",x:x,y:y,op:op})}pop(){this.vec.push({type:"pop"})}randomcolor(transp="100%"){return`hsl(${Math.floor(360*Math.random())}, 50%, 40%,${transp})`}addgr(gr){let name=gr;gr?.name&&(name=gr.name),this.gr[name]?this.vec.push({type:"group",name:name}):this.vec.push({type:"err",err:`addgroup: ${name} => missing`})}addquota(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"quota",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addqpunto(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"qpunto",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addpoint(p,id=-1,color="red",spessore=8){return p&&this.vec.push({type:"point",p:p,id:id,color:color,spessore:spessore*this._sl}),this}addline(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"line",l:l,id:id,color:color,spessore:spessore*this._sl}),this}addrect(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"rect",l:l,id:id,color:color,spessore:spessore*this._sl}),this}addrecta(l,id=-1,color=void 0){return l&&this.vec.push({type:"recta",l:l,id:id,color:color,spessore:0}),this}addshape(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shape",s:s,color:color||this.randomcolor(),spessore:spessore*this._sl}),this}addshapelin(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shapelin",s:s,color:color||this.randomcolor(),spessore:spessore*this._sl}),this}addarea(s,color=void 0){return s&&this.vec.push({type:"area",s:s,color:color||this.randomcolor()}),this}addoffset(x,y){return this.vec.push({type:"offset",x:x||0,y:y||0}),this}}function checkoggetto(oggetti,tipo,cod,isrect){if("h"==tipo&&(tipo="o"),oggetti||(oggetti=[]),"number"==typeof cod&&!["a","as"].includes(tipo))return{cod:"__",macro:"",sps:cod};let bb=oggetti.find((e=>e.tipo.includes(tipo)&&e.cod==cod&&(e.isshape||isrect||"a"!=tipo)));return bb||(bb=oggetti.find((e=>e.tipo.includes(tipo)&&(e.isshape||isrect||"a"!=tipo)))),bb||(bb={cod:"__",macro:"",sps:0}),"a"!=tipo&&"as"!=tipo||"__"==bb.cod||bb.color||(bb.color=`hsl(${function stringToHue(str){let hash=0;for(let i=0;i<str.length;i++)hash=31*hash+str.charCodeAt(i)>>>0;return Math.floor(.6180339887*hash%1*360)}(bb.cod)}, 95%, 97%`),bb}function getbordi(oggetti,bordo){let bordi,uguali=!1;if(Array.isArray(bordo)){bordo.length=4;let b0=bordo[0]||"";bordi=bordo.map((b=>checkoggetto(oggetti,"b",b||b0))),uguali=bordi.every((b=>b.sps===bordi[0].sps))}else{let tm=checkoggetto(oggetti,"b",bordo);bordi=[tm,tm,tm,tm],uguali=!0}return{bordi:bordi,uguali:uguali,senza:!(bordi[0].sps||bordi[1].sps||bordi[2].sps||bordi[3].sps),bl:bordi[0].sps,bt:bordi[1].sps,br:bordi[2].sps,bb:bordi[3].sps}}function elaborapercorso(sh1,bordo,taglio,oggetti,countid=0){let sh2,sh3,p1h,p2h,p3h,p4h,p1v,p2v,p3v,p4v,p1s,p2s,line1,line2,i1,i2,dati=[],draws=[];function eseguipezzo(l1,l2,bordo,shape){let info=l1.infoquad(l2);if(info&&info.distanza){let s0=getshape().frompt(shape||[l1.p1,l1.p2,l2.p2,l2.p1]),s1=s0.clone();(info.sx||info.sy)&&s1.move(-info.sx||0,-info.sy||0),info.angle&&s1.rotate(-info.angle||0);let tm={id:++countid,type:`b${bordo}`,info:info};shape&&(tm.shape=s1.pt),draws.push({type:`b${bordo}`,pt:s0.pt}),dati.push(tm)}}countid=countid||0;let np=sh1.pt.length,idr=np-1;oggetti||(oggetti=[]);let{bordi:bordi,uguali:uguali,senza:senza}=getbordi(oggetti,bordo);if(uguali)if(senza||!bordi[0].sps)sh2=sh1.clone();else{let b=bordi[0].sps;sh2=shapeclip().inflate(sh1,-b,!0)}else{let b,ll=[],pp=[];for(let i=0;i<np;i++){b=0==i?bordi[0].sps:i==idr-1?bordi[2].sps:i==idr?bordi[3].sps:bordi[1].sps,"number"!=typeof b&&(b=0);let l=sh1.segment(i).offset(-b);ll.push(l)}for(let i=0;i<np;i++){let p=ll[i].interseca(ll[(i-1+np)%np]);pp.push(p)}sh2=getshape().frompt(pp)}if(!senza){p1h=sh2.segment(idr).interseca(sh1.segment(0)),p2h=sh2.segment(1).interseca(sh1.segment(0)),p3h=sh1.segment(idr-1).interseca(sh2.segment(idr-2)),p4h=sh1.segment(idr-1).interseca(sh2.segment(idr)),p1v=sh1.segment(idr).interseca(sh2.segment(0)),p2v=sh1.segment(1).interseca(sh2.segment(0)),p3v=sh1.segment(idr-2).interseca(sh2.segment(idr-1)),p4v=sh1.segment(idr).interseca(sh2.segment(idr-1)),i1=1,i2=idr-2,line1=sh2.segment(0),line2=sh2.segment(idr-1);for(let i=1;i<idr-1;i++){let l=sh1.segment(i),p=l.interseca(line1);p&&l.onsegment(p)&&(i1=i,p2v=p),p=l.interseca(line2),p&&l.onsegment(p)&&(i2=i,p3v=p)}i1-=1,i2=idr-2-i2;let p1=sh1.pt[0],p2=sh2.pt[0],p3=sh2.pt[idr],p4=sh1.pt[idr];switch(taglio[0]){case"v":eseguipezzo(new Linea2(p4v,p1v),sh2.segment(idr),3),p2=p1v,p3=p4v;break;case"o":eseguipezzo(sh1.segment(idr),new Linea2(p4h,p1h),3),p1=p1h,p4=p4h;break;default:eseguipezzo(sh1.segment(idr),sh2.segment(idr),3)}switch(p1s=sh1.pt.slice(1,idr),p2s=sh2.pt.slice(1,idr),taglio[1]){case"v":eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,p2v),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(p3v,p3),2),i1&&(p1s=p1s.slice(i1)),i2&&(p1s=p1s.slice(0,-i2)),p1s[0]=p2v,p1s[p1s.length-1]=p3v;break;case"o":eseguipezzo(new Linea2(p1,p2h),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(p3h,p4),new Linea2(sh2.pt[idr-1],p3),2),p2s[0]=p2h,p2s[p2s.length-1]=p3h;break;default:eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(sh2.pt[idr-1],p3),2)}if(sh3=getshape().frompt(p2s),p1s.length<8&&p1s.length==p2s.length)for(let i=0;i<p1s.length-1;i++)eseguipezzo(new Linea2(p1s[i],p1s[i+1]),new Linea2(p2s[i],p2s[i+1]),1);else{let sh3=getshape().frompt([...p1s,...p2s.reverse()]),l3=new Linea2(p1s[0],p1s[p1s.length-1]),l4=l3.offset(-bordo[1]);eseguipezzo(l3,l4,1,sh3.pt)}}return{countid:countid,shape2:sh2,shapetop:sh3,bordi:bordi,dati:dati,draws:draws}}function creaprofiloesterno(ff,oggetti){let sh1,{x:x,y:y,tipo:tipo,bordo:bordo,taglio:taglio,h1:h1,h2:h2,l1:l1,l2:l2,forma:forma}=ff;x=x<50?50:x,y=y<50?50:y,l1=l1||0,l2=l2||0,h1=h1||0,h2=h2||0;let pts=[0,0];switch(tipo){case"i":case"d":pts.push(l1>0&&l1<x?l1:0,h1>0&&h1<y?y-h1:y),pts.push(l2>0&&l2<x-l1?x-l2:x,h2>0&&h2<y&&h2!=h1?y-h2:y);break;case"a":if(forma){let tm=getshape().fromstr(forma);tm.alignline({x:l1,y:y-h1},{x:x-l2,y:y-h2}),pts.push(...tm.vec)}else if((h1||h2)&&h1>=0&&h1<Math.min(y,x/2)&&h2>=0&&h2<Math.min(y,x/2)){let tm=getshape().fromstr(`a30;${l1||0};${y-h1};${x/2};${y};${x-l2};${y-h2}`);pts.push(...tm.vec)}else pts.push(0,y,x,y);break;case"s":l1>0&&h1>0?pts.push(0,y-h1,l1,y):pts.push(0,y),l2&&l2<x-l1&&h2>0&&h2<y?pts.push(x-l2,y,x,y-h2):pts.push(x,y);break;default:pts.push(0,y,x,y)}pts.push(x,0),sh1=getshape().fromvec(pts);let{countid:countid,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}=elaborapercorso(sh1,bordo,taglio,oggetti,ff.countid);return ff.countid=countid,{shape:sh1,internalshape:shape2,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}}
507
+ function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if(n1<1||n2<1)return sag2.slice();let bestOffset=0,minSum=1/0;for(let k=0;k<n2;k++){const p0=sag1[0],q0=sag2[k%n2],dx0=p0.x-q0.x,dy0=p0.y-q0.y,p1=sag1[n1-1],q1=sag2[isopen?Math.min(k+n1-1,n2-1):(k+n1-1)%n2],dx1=p1.x-q1.x,dy1=p1.y-q1.y,sum=dx0*dx0+dy0*dy0+dx1*dx1+dy1*dy1;sum<minSum&&(minSum=sum,bestOffset=k)}return[...sag2.slice(bestOffset),...sag2.slice(0,bestOffset)]}function shapeclip(){function toclipformat(pts){let tm=pts.map((e=>({X:Math.round(1e4*e.x),Y:Math.round(1e4*e.y)})));return ensureOrientation(tm)}function fromclipformat(pts){return pts.map((e=>({x:e.X/1e4,y:e.Y/1e4})))}const ensureOrientation=poly=>ClipperLib.Clipper.Orientation(poly)?poly:poly.slice().reverse();function orientation(pt){if(!pt.length)return 0;let area=0;const n=pt.length;for(let i=0;i<n;i++){const current=pt[i],next=pt[(i+1)%n];area+=current.X*next.Y-next.X*current.Y}return area>0?1:area<0?-1:0}const _inflate=(pt,delta,cut=!1)=>{const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.AddPath(pt,ClipperLib.JoinType.jtMiter,cut||2==pt.length?ClipperLib.EndType.etOpenButt:ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;return co.Execute(solution,delta),solution};function _inflateopen(pts,delta){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*delta,pshape=toclipformat(pts);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etClosedPolygon);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return getshape().frompt(tm)}return{offset(shape,delta,full=!1){const co=new ClipperLib.ClipperOffset;co.MiterLimit=4,co.ArcTolerance=.25;const DD=1e4*Math.abs(delta),pshape=toclipformat(shape.pt);co.AddPath(pshape,ClipperLib.JoinType.jtMiter,ClipperLib.EndType.etOpenButt);const solution=new ClipperLib.Paths;co.Execute(solution,DD);let tm=fromclipformat(solution[0]);return full?getshape().frompt(tm):getshape().frompt(getptsoffset(shape.pt,tm,delta))},inflate:function inflate(shape,delta=2,mantainorder=!1,isopen=0){let pshape=toclipformat(shape.pt),tm=_inflate(pshape,1e4*delta);if(!tm||!tm.length)return getshape().frompt([]);let p2=getshape().frompt(fromclipformat(tm[0]));if(mantainorder){p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,isopen);if(p2.frompt(p3),isopen>0&&shape.pt.length>=3){function estendi1(sh1,sh2){let l1=sh1.segment(0).ruotata(-Math.PI/2,200,!0),l2=sh1.segment(-2).ruotata(-Math.PI/2,200),q2=sh2.segment(-2).interseca(l2),q1=sh2.segment(0).interseca(l1);q1&&(sh2.pt[0]=q1),q2&&(sh2.pt[sh2.pt.length-1]=q2)}function estendi2(sh1,sh2){let lfin=sh1.segment(-1),l2=sh2.segment(0),q1=lfin.interseca(l2);q1&&(sh2.pt[0]=q1),l2=sh2.segment(-2);let q2=lfin.interseca(l2);q2&&(sh2.pt[sh2.pt.length-1]=q2)}1==isopen?estendi1(shape,p2):estendi2(shape,p2)}}return p2},inflateopen:_inflateopen,inflateclose(shape,delta){let p2=_inflateopen(shape.pt,delta);p2.orient!=shape.orient&&p2.reverse();let p3=alignByMinDist(shape.pt,p2.pt,0);return p2.frompt(p3),p2},inflatecornici(shape,delta=2,linetruncateini,linetruncateend){let l1=new Linea2(shape.pt[0],shape.pt[shape.npt-1]),len1=l1.len,l2=l1.perpendicolare(l1.p1,len1),l3=l1.perpendicolare(l1.p2,len1);l2.isparallela(shape.segment(0))&&(l2=l1.perpendicolare(l1.puntot(.1),len1)),l3.isparallela(shape.segment(shape.npt-2))&&(l3=l1.perpendicolare(l1.puntot(.9),len1));let n2=Math.floor(shape.npt/2),{t:t}=l2.proiezionet(shape.pt[n2]),t2=2*(t>0?-1:1),px2=l2.puntot(t2),px3=l3.puntot(t2),p2=_inflateopen([...shape.pt,px3,px2],delta),idx=p2.pt.reduce(((imin,p,i)=>(p.x-px2.x)**2+(p.y-px2.y)**2<(p2.pt[imin].x-px2.x)**2+(p2.pt[imin].y-px2.y)**2?i:imin),0);return p2.pt=p2.pt.slice(idx+2).concat(p2.pt.slice(0,idx)),p2.orient!=shape.orient&&p2.reverse(),linetruncateini&&(shape.truncatebefore(linetruncateini),p2.truncatebefore(linetruncateini)),linetruncateend&&(p2.truncateafter(linetruncateend),shape.truncateafter(linetruncateend)),p2},intersecasplitter(areabase,forma1){const clipper=new ClipperLib.Clipper,pt1=[toclipformat(forma1.pt)],pt2=[toclipformat(areabase.pt)];clipper.AddPaths(pt1,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(pt2,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;let res;if(clipper.Execute(ClipperLib.ClipType.ctIntersection,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)&&solution.length>0){const path=solution[0];if(1===orientation(path)){res=getshape().frompt(fromclipformat(path)),res.orient!=forma1.orient&&res.reverse();for(let iu=0;iu<forma1.pt.length;iu++){let p2=forma1.pt[iu],id=res.pt.findIndex((p=>Math.abs(p.x-p2.x)<.01&&Math.abs(p.y-p2.y)<.01));if(id>0){id-=iu,0!=id&&res.selezionaprimo(id);break}}}}return res},offsetpts(pts,delta=.01){const DELTA=1e4*delta;let tm=_inflate(toclipformat(pts),DELTA);if(tm&&tm.length)return fromclipformat(tm[0])},areesplitter(shapept,clipspt,useInflatedClipping=!0){if(!Array.isArray(shapept)||shapept.length<3)return;if(!clipspt||0==clipspt.length)return[shapept];const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;let shape_in=useInflatedClipping?_inflate(toclipformat(shapept),-100):[toclipformat(shapept)],clips_in=useInflatedClipping?clipspt.flatMap((c=>_inflate(toclipformat(c),100))):clipspt.map((c=>toclipformat(c)));for(let s of shape_in)subj.push(s);for(let c of clips_in)clip.push(c);const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(!clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero))return;let res=[];for(let x of solution)if(useInflatedClipping){const restored=_inflate(x,100);for(const r of restored)1===orientation(r)&&res.push(fromclipformat(r))}else if(x.length>4&&1==orientation(x)){const cleaned=_inflate(x,-100);if(cleaned.length>0)for(let cc of cleaned){const restored=_inflate(cc,100);for(const rr of restored)1===orientation(rr)&&res.push(fromclipformat(rr))}}else 1==orientation(x)&&res.push(fromclipformat(x));return res},unisci(shapes,holes,cuts){const subj=new ClipperLib.Paths,clip=new ClipperLib.Paths;for(let hh of shapes){let h2=[toclipformat(hh.pt)];for(let h of h2)subj.push(h)}if(holes&&holes.length)for(let hh of holes){let h1=toclipformat(hh.pt);clip.push(h1)}if(cuts&&cuts.length)for(let hh of cuts){let h1=toclipformat(hh.pt),h2=_inflate(h1,1,!0);for(let h of h2)clip.push(h)}const clipper=new ClipperLib.Clipper;clipper.AddPaths(subj,ClipperLib.PolyType.ptSubject,!0),clipper.AddPaths(clip,ClipperLib.PolyType.ptClip,!0);const solution=new ClipperLib.Paths;if(clipper.Execute(ClipperLib.ClipType.ctDifference,solution,ClipperLib.PolyFillType.pftNonZero,ClipperLib.PolyFillType.pftNonZero)){let res=[],holes=[];for(let x of solution)if(1==orientation(x)){let yy=[x];for(let y of yy)res.push({shape:getshape().frompt(fromclipformat(y)),holes:[]})}else holes.push(getshape().frompt(fromclipformat(x)));for(let h of holes)for(let s of res)if(s.shape.pointinshape(h.pt[0])){s.holes.push(h);break}return res}return[]}}}class Vis2d{constructor(name,scalalinea=1){this.name=name,this.clear(scalalinea)}clear(scalalinea=1){return this.vec=[],this.gr={},this._sl=scalalinea,this}creategr(name="grp"){return this.gr[name]||(this.gr[name]=new Vis2d(name,this._sl)),this.gr[name]}push(x=0,y=0,op={}){"number"==typeof op&&(op={rot:op}),op||(op={}),this.vec.push({type:"push",x:x,y:y,op:op})}pop(){this.vec.push({type:"pop"})}randomcolor(transp="100%"){return`hsl(${Math.floor(360*Math.random())}, 50%, 40%,${transp})`}addgr(gr){let name=gr;gr?.name&&(name=gr.name),this.gr[name]?this.vec.push({type:"group",name:name}):this.vec.push({type:"err",err:`addgroup: ${name} => missing`})}addquota(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"quota",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addqpunto(x1,y1,x2,y2,d=0,text="",scalafont=1,spessore=.25){this.vec.push({type:"qpunto",x1:x1,y1:y1,x2:x2,y2:y2,d:d,text:text,spessore:spessore,color:"black",scalafont:scalafont})}addpoint(p,id=-1,color="red",spessore=8){return p&&this.vec.push({type:"point",p:p,id:id,color:color,spessore:spessore*this._sl}),this}addline(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"line",l:l,id:id,color:color,spessore:spessore*this._sl}),this}addrect(l,id=-1,color=void 0,spessore=1){return l&&this.vec.push({type:"rect",l:l,id:id,color:color,spessore:spessore*this._sl}),this}addrecta(l,id=-1,color=void 0){return l&&this.vec.push({type:"recta",l:l,id:id,color:color,spessore:0}),this}addshape(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shape",s:s,color:color||this.randomcolor(),spessore:spessore*this._sl}),this}addshapelin(s,color=void 0,spessore=1){return s&&this.vec.push({type:"shapelin",s:s,color:color||this.randomcolor(),spessore:spessore*this._sl}),this}addarea(s,color=void 0){return s&&this.vec.push({type:"area",s:s,color:color||this.randomcolor()}),this}addoffset(x,y){return this.vec.push({type:"offset",x:x||0,y:y||0}),this}}function checkoggetto(oggetti,tipo,cod,isrect){if("h"==tipo&&(tipo="o"),oggetti||(oggetti=[]),"number"==typeof cod&&!["a","as"].includes(tipo))return{cod:"__",macro:"",sps:cod};let bb=oggetti.find((e=>e.tipo.includes(tipo)&&e.cod==cod&&(e.isshape||isrect||"a"!=tipo)));return bb||(bb=oggetti.find((e=>e.tipo.includes(tipo)&&(e.isshape||isrect||"a"!=tipo)))),bb||(bb={cod:"__",macro:"",sps:0}),"a"!=tipo&&"as"!=tipo||"__"==bb.cod||bb.color||(bb.color=`hsl(${function stringToHue(str){let hash=0;for(let i=0;i<str.length;i++)hash=31*hash+str.charCodeAt(i)>>>0;return Math.floor(.6180339887*hash%1*360)}(bb.cod)}, 95%, 97%`),bb}function getbordi(oggetti,bordo){let bordi,uguali=!1;if(Array.isArray(bordo)){bordo.length=4;let b0=bordo[0]||"";bordi=bordo.map((b=>checkoggetto(oggetti,"b",b||b0))),uguali=bordi.every((b=>b.sps===bordi[0].sps))}else{let tm=checkoggetto(oggetti,"b",bordo);bordi=[tm,tm,tm,tm],uguali=!0}return{bordi:bordi,uguali:uguali,senza:!(bordi[0].sps||bordi[1].sps||bordi[2].sps||bordi[3].sps),bl:bordi[0].sps,bt:bordi[1].sps,br:bordi[2].sps,bb:bordi[3].sps}}function elaborapercorso(sh1,bordo,taglio,oggetti,countid=0){let sh2,sh3,p1h,p2h,p3h,p4h,p1v,p2v,p3v,p4v,p1s,p2s,line1,line2,i1,i2,dati=[],draws=[];function eseguipezzo(l1,l2,bordo,shape){let info=l1.infoquad(l2);if(info&&info.distanza){let s0=getshape().frompt(shape||[l1.p1,l1.p2,l2.p2,l2.p1]),s1=s0.clone();(info.sx||info.sy)&&s1.move(-info.sx||0,-info.sy||0),info.angle&&s1.rotate(-info.angle||0);let tm={id:++countid,type:`b${bordo}`,info:info};shape&&(tm.shape=s1.pt),draws.push({type:`b${bordo}`,pt:s0.pt}),dati.push(tm)}}countid=countid||0;let np=sh1.pt.length,idr=np-1;oggetti||(oggetti=[]);let{bordi:bordi,uguali:uguali,senza:senza}=getbordi(oggetti,bordo);if(uguali)if(senza||!bordi[0].sps)sh2=sh1.clone();else{let b=bordi[0].sps;sh2=shapeclip().inflate(sh1,-b,!0)}else{let b,ll=[],pp=[];for(let i=0;i<np;i++){b=0==i?bordi[0].sps:i==idr-1?bordi[2].sps:i==idr?bordi[3].sps:bordi[1].sps,"number"!=typeof b&&(b=0);let l=sh1.segment(i).offset(-b);ll.push(l)}for(let i=0;i<np;i++){let p=ll[i].interseca(ll[(i-1+np)%np]);pp.push(p)}sh2=getshape().frompt(pp)}if(!senza){p1h=sh2.segment(idr).interseca(sh1.segment(0)),p2h=sh2.segment(1).interseca(sh1.segment(0)),p3h=sh1.segment(idr-1).interseca(sh2.segment(idr-2)),p4h=sh1.segment(idr-1).interseca(sh2.segment(idr)),p1v=sh1.segment(idr).interseca(sh2.segment(0)),p2v=sh1.segment(1).interseca(sh2.segment(0)),p3v=sh1.segment(idr-2).interseca(sh2.segment(idr-1)),p4v=sh1.segment(idr).interseca(sh2.segment(idr-1)),i1=1,i2=idr-2,line1=sh2.segment(0),line2=sh2.segment(idr-1);for(let i=1;i<idr-1;i++){let l=sh1.segment(i),p=l.interseca(line1);p&&l.onsegment(p)&&(i1=i,p2v=p),p=l.interseca(line2),p&&l.onsegment(p)&&(i2=i,p3v=p)}i1-=1,i2=idr-2-i2;let p1=sh1.pt[0],p2=sh2.pt[0],p3=sh2.pt[idr],p4=sh1.pt[idr];switch(taglio[0]){case"v":eseguipezzo(new Linea2(p4v,p1v),sh2.segment(idr),3),p2=p1v,p3=p4v;break;case"o":eseguipezzo(sh1.segment(idr),new Linea2(p4h,p1h),3),p1=p1h,p4=p4h;break;default:eseguipezzo(sh1.segment(idr),sh2.segment(idr),3)}switch(p1s=sh1.pt.slice(1,idr),p2s=sh2.pt.slice(1,idr),taglio[1]){case"v":eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,p2v),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(p3v,p3),2),i1&&(p1s=p1s.slice(i1)),i2&&(p1s=p1s.slice(0,-i2)),p1s[0]=p2v,p1s[p1s.length-1]=p3v;break;case"o":eseguipezzo(new Linea2(p1,p2h),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(p3h,p4),new Linea2(sh2.pt[idr-1],p3),2),p2s[0]=p2h,p2s[p2s.length-1]=p3h;break;default:eseguipezzo(new Linea2(p1,sh1.pt[1]),new Linea2(p2,sh2.pt[1]),0),eseguipezzo(new Linea2(sh1.pt[idr-1],p4),new Linea2(sh2.pt[idr-1],p3),2)}if(sh3=getshape().frompt(p2s),p1s.length<8&&p1s.length==p2s.length)for(let i=0;i<p1s.length-1;i++)eseguipezzo(new Linea2(p1s[i],p1s[i+1]),new Linea2(p2s[i],p2s[i+1]),1);else{let sh3=getshape().frompt([...p1s,...p2s.reverse()]),l3=new Linea2(p1s[0],p1s[p1s.length-1]),l4=l3.offset(-bordo[1]);eseguipezzo(l3,l4,1,sh3.pt)}}return{countid:countid,shape2:sh2,shapetop:sh3,bordi:bordi,dati:dati,draws:draws}}function creaprofiloesterno(ff,oggetti){let sh1,{x:x,y:y,tipo:tipo,bordo:bordo,taglio:taglio,h1:h1,h2:h2,l1:l1,l2:l2,forma:forma}=ff;x=x<50?50:x,y=y<50?50:y,l1=l1||0,l2=l2||0,h1=h1||0,h2=h2||0;let pts=[0,0];switch(tipo){case"i":case"d":pts.push(l1>0&&l1<x?l1:0,h1>0&&h1<y?y-h1:y),pts.push(l2>0&&l2<x-l1?x-l2:x,h2>0&&h2<y&&h2!=h1?y-h2:y);break;case"a":if(forma){let tm=getshape().fromstr(forma);tm.alignline({x:l1,y:y-h1},{x:x-l2,y:y-h2}),pts.push(...tm.vec)}else if((h1||h2)&&h1>=0&&h1<Math.min(y,x/2)&&h2>=0&&h2<Math.min(y,x/2)){let tm=getshape().fromstr(`a30;${l1||0};${y-h1};${x/2};${y};${x-l2};${y-h2}`);pts.push(...tm.vec)}else pts.push(0,y,x,y);break;case"s":l1>0&&h1>0?pts.push(0,y-h1,l1,y):pts.push(0,y),l2&&l2<x-l1&&h2>0&&h2<y?pts.push(x-l2,y,x,y-h2):pts.push(x,y);break;default:pts.push(0,y,x,y)}pts.push(x,0),ff.countid=0,sh1=getshape().fromvec(pts);let{countid:countid,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}=elaborapercorso(sh1,bordo,taglio,oggetti,ff.countid);return ff.countid=countid,{shape:sh1,internalshape:shape2,shape2:shape2,shapetop:shapetop,bordi:bordi,dati:dati,draws:draws}}
508
508
  /**
509
509
  * Genera segmenti basati su intervalli e punti di interruzione
510
510
  * @param {Array<{a: number, b: number}>} t1 - Array di oggetti che rappresentano intervalli con coordinate a e b
@@ -512,7 +512,7 @@ function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if
512
512
  * @param {boolean} [interna=false] - Se true, usa i bordi interni degli intervalli
513
513
  * @param {boolean} [allbreak=false] - Se true, considera ogni punto degli intervalli come una rottura
514
514
  * @returns {Array<{a: number, b: number}>} Array di segmenti generati
515
- */const tipi={x:"normale",s:"smussato",i:"inclinato",a:"arco/sagomato",d:"diagonali"},tagli={dd:"diagonale",vv:"verticale",oo:"orizzontale",vo:"verticale+orizzontale",vd:"verticale+diagonale",ov:"orizzontale+verticale",od:"orizzontale+diagonale"},tipocut={d:"dist. positiva","d-":"dist. negativa",p:"perc. positiva","p-":"perc negativa"},tipoalign={l:"sinistra",c:"centro",r:"destra"};function findareacod(areacodes,x,y){let mindist=1/0,minkey="";for(let k of areacodes){let dist=(k.x-x)**2+(k.y-y)**2;dist<mindist&&(mindist=dist,minkey=k.k)}return minkey}function generatesegments(t1,t2,interna=!1,allbreak=!1){let t3=[];if(t1?.length>=2){if(allbreak){let tm=[];for(let t of t1)tm.push({a:t.a,b:t.a}),t.a!=t.b&&tm.push({a:t.b,b:t.b});t1=tm}if(t1=t1.sort(((a,b)=>a.a-b.a)),t2?.length){let j=0;for(let i=1;i<t1.length;i++){const ε=1e-6;t2.find((e=>e>t1[i-1].b+ε&&e<t1[i].a-ε))&&(i-1>j&&(interna?t3.push({a:t1[j].b,b:t1[i-1].a}):t3.push({a:t1[j].a,b:t1[i-1].b})),j=i)}j<t1.length-1&&(interna?t3.push({a:t1[j].b,b:t1[t1.length-1].a}):t3.push({a:t1[j].a,b:t1[t1.length-1].b}))}else t3.push({a:t1[0].b,b:t1[t1.length-1].a})}return t3}function makedivisions(ff,shape2,oggetti){let draws=[],areas=[],dati=[],lines=[],{x:dx,y:dy,oriz:oriz,vert:vert,tipo:tipo,minvano:minvano,minvanox:minvanox,minvanoy:minvanoy}=ff,{bb:bb,bt:bt,bl:bl,br:br}=getbordi(oggetti,ff.bordo);minvanox=minvanox||minvano||50,minvanoy=minvanoy||minvano||50;let{dati:h1,punti:ph}=ordinabase(oggetti,"o",oriz,dy,minvanoy,bb,bt,tipo),{dati:v1,punti:pv}=ordinabase(oggetti,"v",vert,dx,minvanox,bl,br),shapecontorno=shape2.clone();function adddatilin(type,cod,l0,l1,sp,id){if("l"==type)areas.push([l0.p1,l0.p2]);else{let ptx=[l0.p1,l0.p2,l1.p2,l1.p1];areas.push(ptx);let s1=getshape().frompt(ptx);if(shapecontorno?.pt&&(s1.orient!=shapecontorno.orient&&s1.reverse(),s1=shapeclip().intersecasplitter(shapecontorno,s1)),s1){s1.pt.length>=4&&(l0.p1=s1.pt[0],l0.p2=s1.pt[1],l1.p1=s1.pt[s1.pt.length-1],l1.p2=s1.pt[s1.pt.length-2]),lines.push([l0.p1.x+("v"==type?sp:0),l0.p1.y+("v"!=type?sp:0),l0.p2.x+("v"==type?sp:0),l0.p2.y+("v"!=type?sp:0)]);let info=l0.infoquad(l1);if(info&&info.distanza){let s2=s1.clone(),c2=checkoggetto(oggetti,type,cod);(info.sx||info.sy)&&s2.move(-info.sx||0,-info.sy||0),info.angle&&s2.rotate(-info.angle||0);let tm={id:id,type:type,cod:cod,c2:c2,shape:s2.pt,info:info};dati.push(tm),tm?.shape&&draws.push({type:type,sx:tm.info.sx,sy:tm.info.sy,rot:tm.info.angle,pt:tm.shape})}}}}function isinseg(segs,v){return!!segs.find((e=>e.a<=v&&e.b>=v))}v1.forEach(((v,i)=>{v.segs=generatesegments(ph,v.cuts,!0),v.segs.forEach(((s,j)=>{let l0=new Linea2({x:v.x,y:s.a},{x:v.x,y:s.b}),l1=new Linea2({x:v.x+v.sp,y:s.a},{x:v.x+v.sp,y:s.b});adddatilin(v.sp?"v":"l",v.cod,l0,l1,v.sp/2,v.id)}))}));for(let h of h1){let cuts=[...h.cuts],pv1=[...pv];for(let v of v1)pv1.push({a:v.x,b:v.x+v.sp}),isinseg(v.segs,h.x+h.sp/2)&&cuts.push(v.x+v.sp/2);h.segs=generatesegments(pv1,cuts,!0,!0);for(let s of h.segs){let l1=new Linea2({x:s.b,y:h.x+h.sp},{x:s.a,y:h.x+h.sp}),l0=new Linea2({x:s.b,y:h.x},{x:s.a,y:h.x});adddatilin(h.sp?"o":"l",h.cod,l0,l1,h.sp,h.id)}}let res=shapeclip().areesplitter(shape2.pt,areas),areacodes=function getareacodes(ff){let k1,x1,k2,x2,out=[];for(let i=0;i<=ff.vert.length;i++){if(0==i)k1="v0",x1=0;else{let t=ff.vert[i-1];k1=`${t.dir}${t.id}`,x1=t._v}for(let j=0;j<=ff.oriz.length;j++){if(0==j)k2="o0",x2=0;else{let t=ff.oriz[j-1];k2=`${t.dir}${t.id}`,x2=t._v}out.push({k:k1+k2,x:x1,y:x2})}}return out}(ff);for(let d of res){let s=getshape().frompt(d),{p1:p1,width:width,height:height,isrect:isrect}=s.dims(),k=findareacod(areacodes,p1.x,p1.y),cod=ff.aree[k]||ff.area||"",c2=checkoggetto(oggetti,"a",cod,isrect),ix=s.pt.findIndex((p=>Math.abs(p.x-p1.x)<.001&&Math.abs(p.y-p1.y)<.001));ix>0&&s.selezionaprimo(ix),s.pt.length&&(s.move(-p1.x,-p1.y),1==s.orient&&s.reverse()),dati.push({id:k,cod:cod,c2:c2,type:"a",shape:isrect?null:s.pt,info:{isrect:isrect?1:0,sx:p1.x,sy:p1.y,rot:0,width:width,height:height}}),draws.push({type:isrect?"a":"as",sx:p1.x,sy:p1.y,dx:width,dy:height,id:k,cod:cod,rot:0,pt:s.pt,color:c2.color})}return{ff:ff,h1:h1,ph:ph,v1:v1,pv:pv,draws:draws,lines:lines,dati:dati}}function ordinabase(oggetti,dir,hh,dd,minvano,b1,b2,tipo){let d1=[];if(hh){for(let h of hh){let sp=checkoggetto(oggetti,dir,h.cod).sps||0,x=0;switch(h.tipo){case"d-":x=dd-h.v;break;case"p":x=dd*h.v/100;break;case"p-":x=dd*(100-h.v)/100;break;default:x=h.v}if(sp&&"c"==h.align?x-=sp/2:sp&&"r"==h.align&&(x-=sp),x=Math.round(10*x)/10,h._x0=x,h._x1=x+sp,h._v=x+sp/2,h._valid=x>0&&x<dd,x>b1&&x<dd-b2){let cuts=[];h.cuts&&h.cuts.length&&h.cuts.forEach((c=>{cuts.push(c<0?dd+c:c)})),d1.push({id:h.id,x:x,sp:sp,cuts:cuts,cod:h.cod})}}d1.sort(((a,b)=>a.x-b.x))}let d2=[],p0=b1;"a"==tipo&&(dd*=1.3);for(let i=0;i<d1.length;i++){let d=d1[i];d.x>=p0+minvano&&d.x+d.sp<=dd-b2-minvano&&(d.min=p0+minvano,d.max=dd-b2-minvano,d2.length>0&&(d2[d2.length-1].max=d.x-minvano),d2.push(d),p0=d.x+d.sp)}let d3=[];d3.push({a:b1,b:b1});for(let d of d2)d3.push({a:d.x,b:d.x+d.sp});return d3.push({a:dd-b2,b:dd-b2}),{dati:d2,punti:d3}}function check(ff){let{x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,d1:d1,x1:x1,y1:y1,d2:d2,x2:x2,y2:y2,vert:vert,oriz:oriz,aree:aree,forma:forma,countid:countid}=ff;return x=x||1e3,x<200&&(x=200),y=y||1e3,y<200&&(y=200),h1=h1||y1||0,h2=h2||y2||0,l1=l1||d1||x1||0,l2=l2||d2||x2||0,h1<0&&h1>y-100&&(h1=0),h2<0&&h2>y-100&&(h2=0),(l2<0||l2>x-l1)&&(l2=0),(l1<0||l1>x-l2)&&(l1=0),minvano=minvano||50,forma&&(tipo="a"),area=area||"__",bordo=bordo||"__",priority=priority||"v",taglio=tagli[taglio]?taglio:"dd",tipo=tipi[tipo]?tipo:"x",vert=vert||[],oriz=oriz||[],aree=aree||{},goriz=goriz||void 0,gvert=gvert||void 0,countid=countid||1,{x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,vert:vert,oriz:oriz,aree:aree,countid:countid}}function newcount(ff){return ff.countid++,ff.countid}function addtaglio(ff,dir,tipodim,dim,cod,align="c",cuts=[]){return{dir:dir,id:newcount(ff),tipo:tipocut[tipodim]?tipodim:"d",align:tipoalign[align]?align:"c",v:dim,cod:cod,cuts:cuts||[]}}function addoriz(ff,tipodim,dim,cod,align,cuts){let x=Array.isArray(ff.bordo)?ff.bordo[0]:ff.bordo;cod||(cod=ff.goriz||x||"__"),Array.isArray(align)&&(cuts=align,align="c");let tm=addtaglio(ff,"o",tipodim,dim,cod,align,cuts);return ff.oriz||(ff.oriz=[]),ff.oriz.push(tm),ff}var SP=Object.freeze({__proto__:null,addhoriz:function addhoriz(ff,tipodim,dim,cod,align,cuts){return addoriz(ff,tipodim,dim,cod,align,cuts)},addoriz:addoriz,addvert:function addvert(ff,tipodim,dim,cod,align,cuts){let x=Array.isArray(ff.bordo)?ff.bordo[0]:ff.bordo;cod||(cod=ff.gvert||x||"__"),Array.isArray(align)&&(cuts=align,align="c");let tm=addtaglio(ff,"v",tipodim,dim,cod,align,cuts);return ff.vert||(ff.vert=[]),ff.vert.push(tm),ff},calcoladivisioni:
515
+ */const tipi={x:"normale",s:"smussato",i:"inclinato",a:"arco/sagomato",d:"diagonali"},tagli={dd:"diagonale",vv:"verticale",oo:"orizzontale",vo:"verticale+orizzontale",vd:"verticale+diagonale",ov:"orizzontale+verticale",od:"orizzontale+diagonale"},tipocut={d:"dist. positiva","d-":"dist. negativa",p:"perc. positiva","p-":"perc negativa"},tipoalign={l:"sinistra",c:"centro",r:"destra"};function findareacod(areacodes,x,y){let mindist=1/0,minkey="";for(let k of areacodes){let dist=(k.x-x)**2+(k.y-y)**2;dist<mindist&&(mindist=dist,minkey=k.k)}return minkey}function generatesegments(t1,t2,interna=!1,allbreak=!1){let t3=[];if(t1?.length>=2){if(allbreak){let tm=[];for(let t of t1)tm.push({a:t.a,b:t.a}),t.a!=t.b&&tm.push({a:t.b,b:t.b});t1=tm}if(t1=t1.sort(((a,b)=>a.a-b.a)),t2?.length){let j=0;for(let i=1;i<t1.length;i++){const ε=1e-6;t2.find((e=>e>t1[i-1].b+ε&&e<t1[i].a-ε))&&(i-1>j&&(interna?t3.push({a:t1[j].b,b:t1[i-1].a}):t3.push({a:t1[j].a,b:t1[i-1].b})),j=i)}j<t1.length-1&&(interna?t3.push({a:t1[j].b,b:t1[t1.length-1].a}):t3.push({a:t1[j].a,b:t1[t1.length-1].b}))}else t3.push({a:t1[0].b,b:t1[t1.length-1].a})}return t3}function makedivisions(ff,shape2,oggetti){delete ff.arre;let draws=[],areas=[],dati=[],lines=[],{x:dx,y:dy,oriz:oriz,vert:vert,tipo:tipo,minvano:minvano,minvanox:minvanox,minvanoy:minvanoy}=ff,{bb:bb,bt:bt,bl:bl,br:br}=getbordi(oggetti,ff.bordo);minvanox=minvanox||minvano||50,minvanoy=minvanoy||minvano||50;let{dati:h1,punti:ph}=ordinabase(oggetti,"o",oriz,dy,minvanoy,bb,bt,tipo),{dati:v1,punti:pv}=ordinabase(oggetti,"v",vert,dx,minvanox,bl,br),shapecontorno=shape2.clone();function adddatilin(type,cod,l0,l1,sp,id){if("l"==type)areas.push([l0.p1,l0.p2]),lines.push([l0.p1.x,l0.p1.y,l0.p2.x,l0.p2.y]);else{let ptx=[l0.p1,l0.p2,l1.p2,l1.p1];areas.push(ptx);let s1=getshape().frompt(ptx);if(shapecontorno?.pt&&(s1.orient!=shapecontorno.orient&&s1.reverse(),s1=shapeclip().intersecasplitter(shapecontorno,s1)),s1){s1.pt.length>=4&&(l0.p1=s1.pt[0],l0.p2=s1.pt[1],l1.p1=s1.pt[s1.pt.length-1],l1.p2=s1.pt[s1.pt.length-2]),lines.push([l0.p1.x+("v"==type?sp:0),l0.p1.y+("v"!=type?sp:0),l0.p2.x+("v"==type?sp:0),l0.p2.y+("v"!=type?sp:0)]);let info=l0.infoquad(l1);if(info&&info.distanza){let s2=s1.clone(),c2=checkoggetto(oggetti,type,cod);(info.sx||info.sy)&&s2.move(-info.sx||0,-info.sy||0),info.angle&&s2.rotate(-info.angle||0);let tm={id:id,type:type,cod:cod,c2:c2,shape:s2.pt,info:info};dati.push(tm),tm?.shape&&draws.push({type:type,sx:tm.info.sx,sy:tm.info.sy,rot:tm.info.angle,pt:tm.shape})}}}}function isinseg(segs,v){return!!segs.find((e=>e.a<=v&&e.b>=v))}v1.forEach(((v,i)=>{v.segs=generatesegments(ph,v.cuts,!0),v.segs.forEach(((s,j)=>{let l0=new Linea2({x:v.x,y:s.a},{x:v.x,y:s.b}),l1=new Linea2({x:v.x+v.sp,y:s.a},{x:v.x+v.sp,y:s.b});adddatilin(v.sp?"v":"l",v.cod,l0,l1,v.sp/2,v.id)}))}));for(let h of h1){let cuts=[...h.cuts],pv1=[...pv];for(let v of v1)pv1.push({a:v.x,b:v.x+v.sp}),isinseg(v.segs,h.x+h.sp/2)&&cuts.push(v.x+v.sp/2);h.segs=generatesegments(pv1,cuts,!0,!0);for(let s of h.segs){let l1=new Linea2({x:s.b,y:h.x+h.sp},{x:s.a,y:h.x+h.sp}),l0=new Linea2({x:s.b,y:h.x},{x:s.a,y:h.x});adddatilin(h.sp?"o":"l",h.cod,l0,l1,h.sp,h.id)}}let res=shapeclip().areesplitter(shape2.pt,areas),areacodes=function getareacodes(ff){let k1,x1,k2,x2,out=[];for(let i=0;i<=ff.vert.length;i++){if(0==i)k1="v0",x1=0;else{let t=ff.vert[i-1];k1=`${t.dir}${t.id}`,x1=t._v}for(let j=0;j<=ff.oriz.length;j++){if(0==j)k2="o0",x2=0;else{let t=ff.oriz[j-1];k2=`${t.dir}${t.id}`,x2=t._v}out.push({k:k1+k2,x:x1,y:x2})}}return out}(ff);for(let d of res){let s=getshape().frompt(d),{p1:p1,width:width,height:height,isrect:isrect}=s.dims(),k=findareacod(areacodes,p1.x,p1.y),cod=ff.aree[k]||ff.area||"",c2=checkoggetto(oggetti,"a",cod,isrect),ix=s.pt.findIndex((p=>Math.abs(p.x-p1.x)<.001&&Math.abs(p.y-p1.y)<.001));ix>0&&s.selezionaprimo(ix),s.pt.length&&(s.move(-p1.x,-p1.y),1==s.orient&&s.reverse()),dati.push({id:k,cod:cod,c2:c2,type:"a",shape:isrect?null:s.pt,info:{isrect:isrect?1:0,sx:p1.x,sy:p1.y,rot:0,width:width,height:height}}),draws.push({type:isrect?"a":"as",sx:p1.x,sy:p1.y,dx:width,dy:height,id:k,cod:cod,rot:0,pt:s.pt,color:c2.color})}return{ff:ff,h1:h1,ph:ph,v1:v1,pv:pv,draws:draws,lines:lines,dati:dati}}function ordinabase(oggetti,dir,hh,dd,minvano,b1,b2,tipo){let d1=[];if(hh){for(let h of hh){let sp=checkoggetto(oggetti,dir,h.cod).sps||0,x=0;switch(h.tipo){case"d-":x=dd-h.v;break;case"p":x=dd*h.v/100;break;case"p-":x=dd*(100-h.v)/100;break;default:x=h.v}if(sp&&"c"==h.align?x-=sp/2:sp&&"r"==h.align&&(x-=sp),x=Math.round(10*x)/10,h._x0=x,h._x1=x+sp,h._v=x+sp/2,h._valid=x>0&&x<dd,x>b1&&x<dd-b2){let cuts=[];h.cuts&&h.cuts.length&&h.cuts.forEach((c=>{cuts.push(c<0?dd+c:c)})),d1.push({id:h.id,x:x,sp:sp,cuts:cuts,cod:h.cod})}}d1.sort(((a,b)=>a.x-b.x))}let d2=[],p0=b1;"a"==tipo&&(dd*=1.3);for(let i=0;i<d1.length;i++){let d=d1[i];d.x>=p0+minvano&&d.x+d.sp<=dd-b2-minvano&&(d.min=p0+minvano,d.max=dd-b2-minvano,d2.length>0&&(d2[d2.length-1].max=d.x-minvano),d2.push(d),p0=d.x+d.sp)}let d3=[];d3.push({a:b1,b:b1});for(let d of d2)d3.push({a:d.x,b:d.x+d.sp});return d3.push({a:dd-b2,b:dd-b2}),{dati:d2,punti:d3}}function check(ff){let{x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,d1:d1,x1:x1,y1:y1,d2:d2,x2:x2,y2:y2,vert:vert,oriz:oriz,aree:aree,forma:forma,countid:countid}=ff;return x=x||1e3,x<200&&(x=200),y=y||1e3,y<200&&(y=200),h1=h1||y1||0,h2=h2||y2||0,l1=l1||d1||x1||0,l2=l2||d2||x2||0,h1<0&&h1>y-100&&(h1=0),h2<0&&h2>y-100&&(h2=0),(l2<0||l2>x-l1)&&(l2=0),(l1<0||l1>x-l2)&&(l1=0),minvano=minvano||50,forma&&(tipo="a"),area=area||"__",bordo=bordo||"__",priority=priority||"v",taglio=tagli[taglio]?taglio:"dd",tipo=tipi[tipo]?tipo:"x",vert=vert||[],oriz=oriz||[],aree=aree||{},goriz=goriz||void 0,gvert=gvert||void 0,countid=countid||1,{x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,vert:vert,oriz:oriz,aree:aree,countid:countid}}function newcount(ff){return ff.countid++,ff.countid}function addtaglio(ff,dir,tipodim,dim,cod,align="c",cuts=[]){return{dir:dir,id:newcount(ff),tipo:tipocut[tipodim]?tipodim:"d",align:tipoalign[align]?align:"c",v:dim,cod:cod,cuts:cuts||[]}}function addoriz(ff,tipodim,dim,cod,align,cuts){let x=Array.isArray(ff.bordo)?ff.bordo[0]:ff.bordo;cod||(cod=ff.goriz||x||"__"),Array.isArray(align)&&(cuts=align,align="c");let tm=addtaglio(ff,"o",tipodim,dim,cod,align,cuts);return ff.oriz||(ff.oriz=[]),ff.oriz.push(tm),ff}var SP=Object.freeze({__proto__:null,addhoriz:function addhoriz(ff,tipodim,dim,cod,align,cuts){return addoriz(ff,tipodim,dim,cod,align,cuts)},addoriz:addoriz,addvert:function addvert(ff,tipodim,dim,cod,align,cuts){let x=Array.isArray(ff.bordo)?ff.bordo[0]:ff.bordo;cod||(cod=ff.gvert||x||"__"),Array.isArray(align)&&(cuts=align,align="c");let tm=addtaglio(ff,"v",tipodim,dim,cod,align,cuts);return ff.vert||(ff.vert=[]),ff.vert.push(tm),ff},calcoladivisioni:
516
516
  /**
517
517
  * Ordina e calcola le posizioni di taglio lungo una dimensione, gestendo bordi e spazi minimi
518
518
  * @param {Array<Object>} hh - Array di oggetti che definiscono i tagli
@@ -523,7 +523,7 @@ function alignByMinDist(sag1,sag2,isopen){const n1=sag1.length,n2=sag2.length;if
523
523
  * - dati: Array di oggetti con le posizioni elaborate dei tagli
524
524
  * - punti: Array di oggetti {a,b} che definiscono inizio e fine di ogni segmento
525
525
  */
526
- function calcoladivisioni(ff,notused,shape2,oggetti){return makedivisions(ff,shape2,oggetti)},check:check,checkoggetto:checkoggetto,creaprofiloesterno:creaprofiloesterno,create:function create(x,y,bordo,options){options||(options={});let{minvano:minvano,priority:priority,taglio:taglio,tipo:tipo,h1:h1,h2:h2,d1:d1,d2:d2,l1:l1,l2:l2,x1:x1,x2:x2,y1:y1,y2:y2,gvert:gvert,goriz:goriz,forma:forma,area:area}=options,ff=check({x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,d1:d1,x1:x1,y1:y1,d2:d2,x2:x2,y2:y2});return ff.forma=forma,ff},elaborapercorso:elaborapercorso,getbordi:getbordi,makedivisions:makedivisions,makeshape:function makeshape(ff,oggetti){return creaprofiloesterno(ff,oggetti)},priorita:{v:"verticale",h:"orizzontale"},tagli:tagli,tipi:tipi,tipilocks:[{cod:"diml",des:"Larghezza"},{cod:"dima",des:"Altezza"},{cod:"etipo",des:"Modifica Tipo"},{cod:"etaglio",des:"Modifica Taglio"},{cod:"ebordi",des:"Modifica Bordi"},{cod:"esag",des:"Shape"},{cod:"vcrea",des:"Crea Div. Verticale"},{cod:"ocrea",des:"Crea Div. Orizzontale"},{cod:"vmov",des:"Sposta Div. Verticale"},{cod:"omov",des:"Sposta Div. Orizzontale"},{cod:"vedit",des:"Modifica Div. Verticale"},{cod:"oedit",des:"Modifica Div. Orizzontale"},{cod:"emods",des:"Modificatori Orizzontali/Verticali"},{cod:"ecuts",des:"Modifica/Aggiungi Cuts"},{cod:"earee",des:"Modifica Aree"}],tipoalign:tipoalign,tipocut:tipocut});function fondilinee(linee){const out=linee.slice();out.forEach((e=>e.valid=!0));for(let i=0;i<out.length;i++)if(!1!==out[i].valid)if(out[i].len<.1)out[i].valid=!1;else for(let j=i+1;j<out.length;j++){if(!1===out[j].valid)continue;const a=out[i],b=out[j];if(!a||!b)continue;if(!a.isparallela(b))continue;const a1_su_b=b.onsegment(a.p1,.1),a2_su_b=b.onsegment(a.p2,.1),b1_su_a=a.onsegment(b.p1,.1),b2_su_a=a.onsegment(b.p2,.1);if(!(a1_su_b||a2_su_b||b1_su_a||b2_su_a))continue;const dot=a.dx*b.dx+a.dy*b.dy,pa1=0,pa2=1,rb1=a.proiezionet(b.p1),rb2=a.proiezionet(b.p2);if(!rb1||!rb2)continue;const pb1=rb1.t,pb2=rb2.t;if(dot>0){const tmin=Math.min(pa1,pa2,pb1,pb2),tmax=Math.max(pa1,pa2,pb1,pb2),pmin=a.puntot(tmin),pmax=a.puntot(tmax),fus=new Linea2(pmin,pmax);out[i].valid=!1,out[j].valid=!1,fus.len>=.1&&(fus.valid=!0,out.push(fus))}else if(dot<0){const a_min=Math.min(pa1,pa2),a_max=Math.max(pa1,pa2),b_min=Math.min(pb1,pb2),b_max=Math.max(pb1,pb2),ov_min=Math.max(a_min,b_min),ov_max=Math.min(a_max,b_max);if(ov_min>ov_max+.1)continue;const gmin=Math.min(a_min,b_min),gmax=Math.max(a_max,b_max);if(gmin<ov_min-.1){const s1=new Linea2(a.puntot(gmin),a.puntot(ov_min));s1.len>=.1&&(s1.valid=!0,out.push(s1))}if(ov_max<gmax-.1){const s2=new Linea2(a.puntot(ov_max),a.puntot(gmax));s2.len>=.1&&(s2.valid=!0,out.push(s2))}out[i].valid=!1,out[j].valid=!1}}const res=out.filter((s=>s.valid)),tt=[];function samepoint(p1,p2){return Math.abs(p1.x-p2.x)+Math.abs(p1.y-p2.y)<.1}for(let r of res){let fi=-1,fe=-1;for(let i=0;i<tt.length;i++){let t=tt[i];if(fi<0&&samepoint(t[0],r.p2)&&(tt[i]=[r.p1,...t],fi=i),fe<0&&samepoint(t[t.length-1],r.p1)&&(tt[i]=[...t,r.p2],fe=i),fi>=0&&fe>=0)break}fi<0&&fe<0?tt.push([r.p1,r.p2]):fi>=0&&fe>=0&&fi!=fe&&(tt[fi]=[...tt[fi],...tt[fe]],tt.splice(fe,1))}return tt}async function valutagrafica(amb,startmacro,rulespec,progetto,fnreload){let{getcolonne:getcolonne,muCalc:muCalc,muEval:muEval,tipifree:tipifree}=amb.muvalutatore;rulespec||(rulespec={});for(let x of["l","a","p"]){!amb.vari.var(x)&&startmacro.dims&&amb.vari.add(x,String(startmacro.dims[x].val||100))}let fnlist=new Set;const PARSGLOBAL=["sl","sa","sp","ul","ua","up","ax","ay","az","scx","scy","scz","scale"];let isdimreload,isfnreload=!1,oo=await muEval(amb,startmacro,startmacro.codice,{leveleval:0,checkheader:op=>{let{variante:variante}=op;if(Array.isArray(startmacro.head)){let ff=startmacro.head.find((e=>e.cod==variante));isfnreload=!!ff}},grafica:async _op=>{let p2,cadv,iscad,des,fatti,{id:id,pars:pars,parametri:parametri,macro:macro,options:options,vari:vari}=_op,isheader=!!(macro&&macro.head&&macro.head.length),sv={l:amb.vari.var("l"),a:amb.vari.var("a"),p:amb.vari.var("p")};const varcad=["l","a","p","#d",...PARSGLOBAL];for(let x of varcad){let tm=amb.vari.dictionary[x];tm&&(sv[x]=tm)}async function _parsepars(x,head){let k,v,r9=/^#(d|des|descrizione)\s*=\s*(.*)\s*$/im.exec(x);if(r9)k="#d",v=await amb.vari.valuta(r9[2]);else{let result=await vari.parametrokeyval(x);k=result.k,v=result.v}k&&!fatti[k]&&(fatti[k]=!0,varcad.includes(k)?"#d"==k?des=v:("string"==typeof v&&(v=muCalc(v)),["l","a","p"].includes(k)&&amb.vari.add(k,String(v)),cadv[k]=v,iscad=!0):"string"==typeof v?p2.push(`${k}=${v}`):amb.vari.add(k,v))}if(p2=[],cadv={},iscad=!1,des="",fatti={},progetto&&progetto.keys&&progetto.keys[id]){let px=progetto.keys[id].pars;if(px)for(let t in px){let t1=amb.vari.dictionary[t];t1&&(sv[t]=t1),await _parsepars(`${t}=${px[t]}`)}}if(console.log(tipifree),pars&&pars.length)for(const par of pars)await _parsepars(par);if(parametri&&parametri.length)for(const param of parametri)await _parsepars(param);if(macro&&macro.head&&macro.head.length){let tm=macro.head.filter((e=>!["g","p"].includes(e.t)));for(const h of tm)await _parsepars(h.cod)}let out={iscad:iscad,isheader:isheader,name:macro.name,des:des,leveleval:options.leveleval};isheader&&id&&(out.id=id),iscad&&(cadv.l?amb.vari.add("l",String(cadv.l)):cadv.l=muCalc(amb.vari.var("l")),cadv.a?amb.vari.add("a",String(cadv.a)):cadv.a=muCalc(amb.vari.var("a")),cadv.p?amb.vari.add("p",String(cadv.p)):cadv.p=muCalc(amb.vari.var("p")),out.cadv=cadv),await macro.impostaparametri(parametri,p2,!0);let ruleid=rulespec[id];if(id&&isheader&&ruleid&&ruleid.pars&&(out.pars=ruleid.pars,options.leveleval++,await macro.setparametri(ruleid.pars)),out.rows=await muEval(amb,macro,macro.codice,options),id&&isheader&&(out.spars=macro.getparametri()),iscad)for(let x in sv)amb.vari.dictionary[x]=sv[x];return out},parsefnpunto:async _op=>{let{dati:dati,vari:vari,id:id,output:output}=_op;dati=dati.trim();let q=dati.indexOf(" "),q2=dati.indexOf(",");q2>0&&q>0&&q2<q&&(q=q2);let fn,pp,pars={},p2={};q>1?(fn=dati.slice(1,q),pp=getcolonne(dati.slice(q+1))):(fn=dati.slice(1),pp=[]),fnlist.has(fn)||fnlist.add(fn);for(let p of pp){let{k:k,v:v}=await vari.parametrokeyval(p);k&&/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(k)&&(pars[k]=v||"")}for(let l of["l","a","p"])pars[l]||(pars[l]=vari.var(l));let tm=Object.keys(pars);for(let l of PARSGLOBAL)tm.includes(l)&&(p2[l]=muCalc(pars[l]),delete pars[l]);output.push({t:"fn",fn:fn,id:id,pars:pars,p2:p2})}});for(let x of["l","a","p"])if(startmacro.dims&&startmacro.dims[x].val!=parseFloat(amb.vari.var(x))){isdimreload=!0;break}return(isfnreload||isdimreload&&"function"==typeof fnreload)&&await fnreload(isdimreload,isfnreload),{oo:oo,vari:amb.vari.dump(!0),fnlist:[...fnlist]}}function ismacro(row){return"object"==typeof row&&row?.name&&row.rows}function isfn(row){return"object"==typeof row&&"fn"==row?.t}function getnodebyid(id,nodocorrente){let res;return nodocorrente&&nodocorrente.rows&&function _getnode(rows){for(let x of rows){if(ismacro(x)){if(x.id==id)return void(res=x);x.rows&&_getnode(x.rows)}if(res)return}}(nodocorrente.rows),res}function getsubrules(nodocorrente){let res=[];return res.push({id:"",level:0,name:"home"}),function _xfiltrati(rr,level){if(rr.rows&&rr.rows.length)for(let x of rr.rows)ismacro(x)&&(x.id&&x.isheader?(res.push({id:x.id,name:x.name,des:x.des||"",spec:x.pars?1:0,level:level}),_xfiltrati(x,level+1)):_xfiltrati(x,level))}(nodocorrente,1),res}function getprojectkeys(project){return project.keys={},function _getkeys(node){if(node.rows&&node.rows.length)for(let x of node.rows)ismacro(x)&&(x.id&&x.isheader&&x.pars&&(project.keys[x.id]={name:x.name,des:x.des||"",pars:x.pars}),_getkeys(x))}(project),project}function getdumpmacro(nodo){let cl=[];return function _dumpnodo(node){if(node.rows&&node.rows.length)for(let x of node.rows)if(ismacro(x)){x.name;let c=[];if(x.iscad&&x.cadv)for(let k in x.cadv){let t=x.cadv[k];"number"==typeof t&&t&&c.push(`${k}=${t}`)}if(x.pars)for(let k in x.pars){let t=x.pars[k];c.push(`${k}=${t}`)}c.length&&cl.push(`--\x3e ${x.name} ${c.join(",")}`),_dumpnodo(x),c.length&&cl.push("<--")}else isfn(x)?cl.push(`FN: ${x.fn} ${JSON.stringify(x.pars)}`):"string"==typeof x&&x.length&&cl.push(x)}(nodo),cl.join("\n")}const mgreen$1=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:THREE.DoubleSide});function getorientate(ori,x,y,z){switch(x=x||0,y=y||0,z=z||0,ori.trim().toLowerCase()){case"alp":return{x:y,y:x,z:z};case"apl":return{x:y,y:z,z:x};case"pla":return{x:z,y:x,z:y};case"pal":return{x:z,y:y,z:x};case"lpa":return{x:x,y:z,z:y};default:return{x:x,y:y,z:z}}}function parselavs(ori,id,x=0,y=0,z=0,lavorazioni="",facce="",def=""){let lavcods=function muClComments(codice,tienivuoti){const righe=(code=codice,code.replace(/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|\/\*[\s\S]*?\*\//g,((match,quoted)=>quoted||""))).split(/\r?\n/);var code;const tm=[];let rigaContinua="";for(const riga of righe){let rigaTrim=riga.trim();if(rigaTrim.includes("//")&&(rigaTrim=rigaTrim.split("//")[0].trim()),0!==rigaTrim.length)if(rigaContinua.length>0&&(rigaTrim=rigaContinua+" "+rigaTrim,rigaContinua=""),rigaTrim.endsWith("\\")){rigaTrim=rigaTrim.slice(0,-1);const indiceCommento=rigaTrim.lastIndexOf("//");-1!==indiceCommento&&(rigaTrim=rigaTrim.slice(0,indiceCommento).trim()),rigaContinua=rigaTrim}else tm.push(rigaTrim)}return tm}(lavorazioni),rets=[];for(let lavcod of lavcods){let rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(lavcod);if(rr&&rr[1]){let lav={name:rr[1].trim().toLowerCase(),...getorientate(ori,x,y,z),id:id,facce:facce};if(rr[2]){let aa=getcolonne(rr[2]);for(let a of aa){let i=a.indexOf("=");i>0&&(lav[a.slice(0,i).trim()]=a.slice(i+1).trim())}}rets.push(lav)}}return!rets.length&&def&&rets.push({name:def,...getorientate(ori,x,y,z),id:id,facce:facce}),rets}function getemitter(data){let{d:d,name:name,x:x,y:y,z:z,lavs:lavs="",ids:ids="",faces:faces=null,size:size=5}=data;ids=getcolonne(clean(ids,!0));const emitter=new THREE.Object3D;if(emitter.position.set(x,y,z),emitter.userData={emitter:!0,lavs:lavs,ids:ids,faces:faces,size:size,name:name},d){const geometry=new THREE.SphereGeometry(size||5,8,8),material=new THREE.MeshBasicMaterial({color:16711680}),mesh=new THREE.Mesh(geometry,material);emitter.add(mesh)}return emitter}function getreceiver(gcad,data){gcad.gmats.__istask=1;let{d:d,ori:ori="LAP",x:x=0,y:y=0,z:z=0,tipo:tipo="",start:start="",end:end=""}=data;tipo=clean(tipo,!0);const receiver=new THREE.Object3D;if(receiver.position.set(x/2,y/2,z/2),receiver.userData={receiver:!0,ori:(ori||"").trim().toLowerCase(),x:x,y:y,z:z,tipo:tipo,start:start,end:end},d){const geometry=new THREE.BoxGeometry(x,y,z),mesh=new THREE.Mesh(geometry,mgreen$1);mesh.position.set(0,0,0),receiver.add(mesh)}return receiver}function calcolatasks(scena){const emitterWorldPosition=new WeakMap,receiverWorldMatrixInverse=new WeakMap;function boxBoxIntersects(pos,l,x,y,z){return pos.x+l>0&&pos.x-l<x&&pos.y+l>0&&pos.y-l<y&&pos.z+l>0&&pos.z-l<z}function getFacceToccate(pos,sogliafaccia,x,y,z,filtra){const facce=[];function addfaccia(f){filtra&&!filtra.includes(f)||facce.push(f)}return Math.abs(pos.x-0)<sogliafaccia&&addfaccia("s"),Math.abs(pos.x-x)<sogliafaccia&&addfaccia("d"),Math.abs(pos.y-0)<sogliafaccia&&addfaccia("b"),Math.abs(pos.y-y)<sogliafaccia&&addfaccia("a"),Math.abs(pos.z-0)<sogliafaccia&&addfaccia("z"),Math.abs(pos.z-z)<sogliafaccia&&addfaccia("f"),facce.join("")}function getEmitterWorldPosition(emitter){if(!emitterWorldPosition.has(emitter)){const pos=new THREE.Vector3;emitter.getWorldPosition(pos),emitterWorldPosition.set(emitter,pos)}return emitterWorldPosition.get(emitter)}function getReceiverWorldMatrixInverse(receiver){if(!receiverWorldMatrixInverse.has(receiver)){const inv=receiver.matrixWorld.clone().invert();receiverWorldMatrixInverse.set(receiver,inv)}return receiverWorldMatrixInverse.get(receiver)}scena.updateMatrixWorld(!0);const receivers=[],emitters=[];!function scan(obj){obj.userData?.receiver&&receivers.push(obj),obj.userData?.emitter&&emitters.push(obj),obj.children&&obj.children.forEach(scan)}(scena);let tasks=[];for(const receiver of receivers){const{mat:mat,ori:ori,x:x,y:y,z:z,start:start,end:end,tipo:tipo,size:size}=receiver.userData;let singletask={id:mat,...getorientate(ori,x,y,z),tipo:tipo,ori:ori,lavs:[]};start&&singletask.lavs.push(...parselavs(ori,"_start",0,0,0,start,"",""));const matrixInverse=getReceiverWorldMatrixInverse(receiver);for(const emitter of emitters){if("string"==typeof tipo&&""!==tipo){const idx=emitter.userData.ids;if(Array.isArray(idx)&&idx.length>0&&!idx.includes("*")&&!idx.includes(tipo))continue}const posLocalAdj=getEmitterWorldPosition(emitter).clone().applyMatrix4(matrixInverse).clone().add(new THREE.Vector3(x/2,y/2,z/2));if(!boxBoxIntersects(posLocalAdj,emitter.userData.size??0,x,y,z))continue;const facceToccate=getFacceToccate(posLocalAdj,emitter.userData.soglia??2,x,y,z,emitter.userData.faces);facceToccate&&facceToccate.length&&singletask.lavs.push(...parselavs(ori,emitter.userData.name,posLocalAdj.x,posLocalAdj.y,posLocalAdj.z,emitter.userData.lavs,facceToccate,"nd"))}end&&singletask.lavs.push(...parselavs(ori,"_end",0,0,0,end,"","")),singletask.lavs.length&&tasks.push(singletask)}return tasks}const SIDE=THREE.DoubleSide;let materialline1=new THREE.LineBasicMaterial({color:3158064}),materialline2=new THREE.LineBasicMaterial({color:5263440});const mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgray1=new THREE.MeshStandardMaterial({color:8421504,roughness:.5,metalness:.4,side:SIDE}),mgray2=new THREE.MeshStandardMaterial({color:11579568,roughness:.5,metalness:.4,side:SIDE}),mred=new THREE.MeshStandardMaterial({color:16711680,roughness:.5,metalness:.4,side:SIDE}),mblue=new THREE.MeshStandardMaterial({color:1982639,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE}),mblack=new THREE.MeshStandardMaterial({color:0,roughness:.5,metalness:.4,side:SIDE}),scaleunit=.001;function groupfromgeometry(geometry,material,x,y,z,name,layer){let child=new THREE.Group;child.position.set(x,y,z),child.name=name;const mesh=new THREE.Mesh(geometry,material);mesh.name=name,mesh.castShadow=!0,mesh.receiveShadow=!0,mesh.layers.set(layer);const edges=new THREE.EdgesGeometry(geometry),lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(30),child.add(mesh),child.add(lineSegments),child}function posiziona(grp,pos={}){let tm=new THREE.Group;if(grp){let g2=grp.clone(),tm2=g2,{sl:sl=0,sa:sa=0,sp:sp=0,ax:ax=0,ay:ay=0,az:az=0,ul:ul=0,ua:ua=0,up:up=0,scale:scale=1,scx:scx=scale,scy:scy=scale,scz:scz=scale,emitters:emitters,emittersname:emittersname,order:order}=pos;if("number"==typeof order&&g2.traverse((child=>{child.isMesh&&(child.renderOrder=order)})),tm.position.set(sl,sa,sp),tm.rotation.set(ax*PIF,ay*PIF,az*PIF),(ul||ua||up)&&(tm2=new THREE.Group,tm2.add(g2),tm2.position.set(ul,ua,up)),tm.scale.set(scx,scy,scz),tm.add(tm2),emitters&&emitters.length)for(let e of emitters)e.name=e.name||emittersname,tm.add(getemitter(e))}return tm}function edgesfromgeometry(g1,layer=30){return getlinesgeom(new THREE.EdgesGeometry(g1,40),layer)}function getlinesgeom(edges,layer=30){const lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(layer),lineSegments}function getmesh(geom,material,layer=1,clone=!1){let m=new THREE.Mesh(geom,clone?material.clone():material);return m.castShadow=!0,m.receiveShadow=!0,m.layers.set(layer),m}function get3dshape(punti,material,layer){if(!punti||punti.length<3)return new THREE.BufferGeometry;const vertices=[];for(let i=0;i<punti.length;i++){const p1=punti[i],p2=punti[(i+1)%punti.length];vertices.push(p1.x,0,p1.y),vertices.push(p2.x,0,p2.y)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3));let m=new THREE.LineSegments(geometry,material);return m.layers.set(layer),m}function creategroup(name){let g=new THREE.Group;return g.name=name||"$$",g}function svuotanodo(n){!function _dispose(node){if(node.children.length){[...node.children].forEach((child=>{_dispose(child),node.remove(child)}))}node.geometry&&node.geometry.dispose(),node.material&&(Array.isArray(node.material)?node.material.forEach((m=>m.dispose())):node.material.dispose())}(n)}function deletegroup(grpbase,name){if(!grpbase?.children)return;let gr=grpbase.children.find((e=>e.name==name));if(gr){for(;gr.children.length>0;){const child=gr.children[0];gr.remove(child)}gr.parent&&gr.parent.remove(gr),gr=null}}function randombasemat(){const material=new THREE.LineBasicMaterial,color=new THREE.Color;return color.setHSL(Math.random(),.7,.4),material.color=color,material}
526
+ function calcoladivisioni(ff,notused,shape2,oggetti){return makedivisions(ff,shape2,oggetti)},check:check,checkoggetto:checkoggetto,creaprofiloesterno:creaprofiloesterno,create:function create(x,y,bordo,options){options||(options={});let{minvano:minvano,priority:priority,taglio:taglio,tipo:tipo,h1:h1,h2:h2,d1:d1,d2:d2,l1:l1,l2:l2,x1:x1,x2:x2,y1:y1,y2:y2,gvert:gvert,goriz:goriz,forma:forma,area:area}=options,ff=check({x:x,y:y,area:area,bordo:bordo,gvert:gvert,goriz:goriz,priority:priority,minvano:minvano,taglio:taglio,tipo:tipo,h1:h1,h2:h2,l1:l1,l2:l2,d1:d1,x1:x1,y1:y1,d2:d2,x2:x2,y2:y2});return ff.forma=forma,ff},elaborapercorso:elaborapercorso,getbordi:getbordi,makedivisions:makedivisions,makeshape:function makeshape(ff,oggetti){return creaprofiloesterno(ff,oggetti)},priorita:{v:"verticale",h:"orizzontale"},tagli:tagli,tipi:tipi,tipilocks:[{cod:"diml",des:"Larghezza"},{cod:"dima",des:"Altezza"},{cod:"etipo",des:"Modifica Tipo"},{cod:"etaglio",des:"Modifica Taglio"},{cod:"ebordi",des:"Modifica Bordi"},{cod:"esag",des:"Shape"},{cod:"vcrea",des:"Crea Div. Verticale"},{cod:"ocrea",des:"Crea Div. Orizzontale"},{cod:"vmov",des:"Sposta Div. Verticale"},{cod:"omov",des:"Sposta Div. Orizzontale"},{cod:"vedit",des:"Modifica Div. Verticale"},{cod:"oedit",des:"Modifica Div. Orizzontale"},{cod:"emods",des:"Modificatori Orizzontali/Verticali"},{cod:"ecuts",des:"Modifica/Aggiungi Cuts"},{cod:"earee",des:"Modifica Aree"}],tipoalign:tipoalign,tipocut:tipocut});function fondilinee(linee){const out=linee.slice();out.forEach((e=>e.valid=!0));for(let i=0;i<out.length;i++)if(!1!==out[i].valid)if(out[i].len<.1)out[i].valid=!1;else for(let j=i+1;j<out.length;j++){if(!1===out[j].valid)continue;const a=out[i],b=out[j];if(!a||!b)continue;if(!a.isparallela(b))continue;const a1_su_b=b.onsegment(a.p1,.1),a2_su_b=b.onsegment(a.p2,.1),b1_su_a=a.onsegment(b.p1,.1),b2_su_a=a.onsegment(b.p2,.1);if(!(a1_su_b||a2_su_b||b1_su_a||b2_su_a))continue;const dot=a.dx*b.dx+a.dy*b.dy,pa1=0,pa2=1,rb1=a.proiezionet(b.p1),rb2=a.proiezionet(b.p2);if(!rb1||!rb2)continue;const pb1=rb1.t,pb2=rb2.t;if(dot>0){const tmin=Math.min(pa1,pa2,pb1,pb2),tmax=Math.max(pa1,pa2,pb1,pb2),pmin=a.puntot(tmin),pmax=a.puntot(tmax),fus=new Linea2(pmin,pmax);out[i].valid=!1,out[j].valid=!1,fus.len>=.1&&(fus.valid=!0,out.push(fus))}else if(dot<0){const a_min=Math.min(pa1,pa2),a_max=Math.max(pa1,pa2),b_min=Math.min(pb1,pb2),b_max=Math.max(pb1,pb2),ov_min=Math.max(a_min,b_min),ov_max=Math.min(a_max,b_max);if(ov_min>ov_max+.1)continue;const gmin=Math.min(a_min,b_min),gmax=Math.max(a_max,b_max);if(gmin<ov_min-.1){const s1=new Linea2(a.puntot(gmin),a.puntot(ov_min));s1.len>=.1&&(s1.valid=!0,out.push(s1))}if(ov_max<gmax-.1){const s2=new Linea2(a.puntot(ov_max),a.puntot(gmax));s2.len>=.1&&(s2.valid=!0,out.push(s2))}out[i].valid=!1,out[j].valid=!1}}const res=out.filter((s=>s.valid)),tt=[];function samepoint(p1,p2){return Math.abs(p1.x-p2.x)+Math.abs(p1.y-p2.y)<.1}for(let r of res){let fi=-1,fe=-1;for(let i=0;i<tt.length;i++){let t=tt[i];if(fi<0&&samepoint(t[0],r.p2)&&(tt[i]=[r.p1,...t],fi=i),fe<0&&samepoint(t[t.length-1],r.p1)&&(tt[i]=[...t,r.p2],fe=i),fi>=0&&fe>=0)break}fi<0&&fe<0?tt.push([r.p1,r.p2]):fi>=0&&fe>=0&&fi!=fe&&(tt[fi]=[...tt[fi],...tt[fe]],tt.splice(fe,1))}return tt}async function valutagrafica(amb,startmacro,rulespec,progetto,fnreload){let{getcolonne:getcolonne,muCalc:muCalc,muEval:muEval,tipifree:tipifree}=amb.muvalutatore;rulespec||(rulespec={});for(let x of["l","a","p"]){!amb.vari.var(x)&&startmacro.dims&&amb.vari.add(x,String(startmacro.dims[x].val||100))}let fnlist=new Set;const PARSGLOBAL=["sl","sa","sp","ul","ua","up","ax","ay","az","scx","scy","scz","scale"];let isdimreload,isfnreload=!1,oo=await muEval(amb,startmacro,startmacro.codice,{leveleval:0,checkheader:op=>{let{variante:variante}=op;if(Array.isArray(startmacro.head)){let ff=startmacro.head.find((e=>e.cod==variante));isfnreload=!!ff}},grafica:async _op=>{let p2,cadv,iscad,des,fatti,{id:id,pars:pars,parametri:parametri,macro:macro,options:options,vari:vari}=_op,isheader=!!(macro&&macro.head&&macro.head.length),sv={l:amb.vari.var("l"),a:amb.vari.var("a"),p:amb.vari.var("p")};const varcad=["l","a","p","#d",...PARSGLOBAL];for(let x of varcad){let tm=amb.vari.dictionary[x];tm&&(sv[x]=tm)}async function _parsepars(x,head){let k,v,r9=/^#(d|des|descrizione)\s*=\s*(.*)\s*$/im.exec(x);if(r9)k="#d",v=await amb.vari.valuta(r9[2]);else{let result=await vari.parametrokeyval(x);k=result.k,v=result.v}k&&!fatti[k]&&(fatti[k]=!0,varcad.includes(k)?"#d"==k?des=v:("string"==typeof v&&(v=muCalc(v)),["l","a","p"].includes(k)&&amb.vari.add(k,String(v)),cadv[k]=v,iscad=!0):"string"==typeof v?p2.push(`${k}=${v}`):amb.vari.add(k,v))}let px;if(p2=[],cadv={},iscad=!1,des="",fatti={},progetto&&progetto.keys&&progetto.keys[id]&&(px=progetto.keys[id].pars,px))for(let t in px){let t1=amb.vari.dictionary[t];t1&&(sv[t]=t1),await _parsepars(`${t}=${px[t]}`)}if(pars&&pars.length)for(const par of pars)await _parsepars(par);if(parametri&&parametri.length)for(const param of parametri)await _parsepars(param);if(macro&&macro.head&&macro.head.length){let tm=macro.head.filter((e=>!["g","p"].includes(e.t)));for(const h of tm)await _parsepars(h.cod)}let out={iscad:iscad,isheader:isheader,name:macro.name,des:des,leveleval:options.leveleval};isheader&&id&&(out.id=id),iscad&&(cadv.l?amb.vari.add("l",String(cadv.l)):cadv.l=muCalc(amb.vari.var("l")),cadv.a?amb.vari.add("a",String(cadv.a)):cadv.a=muCalc(amb.vari.var("a")),cadv.p?amb.vari.add("p",String(cadv.p)):cadv.p=muCalc(amb.vari.var("p")),out.cadv=cadv),await macro.impostaparametri(parametri,p2,!0,px);let ruleid=rulespec[id];id&&isheader&&ruleid&&ruleid.pars&&(out.pars=ruleid.pars,options.leveleval++,await macro.setparametri(ruleid.pars));let tm=amb.vari.var("_rootnode");if(amb.vari.add("_rootnode","0"),out.rows=await muEval(amb,macro,macro.codice,options),amb.vari.add("_rootnode",tm),id&&isheader&&(out.spars=macro.getparametri()),iscad)for(let x in sv)amb.vari.dictionary[x]=sv[x];return out},parsefnpunto:async _op=>{let{dati:dati,vari:vari,id:id,output:output}=_op;dati=dati.trim();let q=dati.indexOf(" "),q2=dati.indexOf(",");q2>0&&q>0&&q2<q&&(q=q2);let fn,pp,pars={},p2={};q>1?(fn=dati.slice(1,q),pp=getcolonne(dati.slice(q+1))):(fn=dati.slice(1),pp=[]),fnlist.has(fn)||fnlist.add(fn);for(let p of pp){let{k:k,v:v}=await vari.parametrokeyval(p);k&&/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(k)&&(pars[k]=v||"")}for(let l of["l","a","p"])pars[l]||(pars[l]=vari.var(l));let tm=Object.keys(pars);for(let l of PARSGLOBAL)tm.includes(l)&&(p2[l]=muCalc(pars[l]),p2[l]&&(pars[l]=p2[l]));output.push({t:"fn",fn:fn,id:id,pars:pars,p2:p2})}});for(let x of["l","a","p"])if(startmacro.dims&&startmacro.dims[x].val!=parseFloat(amb.vari.var(x))){isdimreload=!0;break}return(isfnreload||isdimreload&&"function"==typeof fnreload)&&await fnreload(isdimreload,isfnreload),{oo:oo,vari:amb.vari.dump(!0),fnlist:[...fnlist]}}function ismacro(row){return"object"==typeof row&&row?.name&&row.rows}function isfn(row){return"object"==typeof row&&"fn"==row?.t}function getnodebyid(id,nodocorrente){let res;return nodocorrente&&nodocorrente.rows&&function _getnode(rows){for(let x of rows){if(ismacro(x)){if(x.id==id)return void(res=x);x.rows&&_getnode(x.rows)}if(res)return}}(nodocorrente.rows),res}function getsubrules(nodocorrente){let res=[];return res.push({id:"",level:0,name:"home"}),function _xfiltrati(rr,level){if(rr.rows&&rr.rows.length)for(let x of rr.rows)ismacro(x)&&(x.id&&x.isheader?(res.push({id:x.id,name:x.name,des:x.des||"",spec:x.pars?1:0,level:level}),_xfiltrati(x,level+1)):_xfiltrati(x,level))}(nodocorrente,1),res}function getdumpmacro(nodo){let cl=[];return function _dumpnodo(node){if(node.rows&&node.rows.length)for(let x of node.rows)if(ismacro(x)){x.name;let c=[];if(x.iscad&&x.cadv)for(let k in x.cadv){let t=x.cadv[k];"number"==typeof t&&t&&c.push(`${k}=${t}`)}if(x.pars)for(let k in x.pars){let t=x.pars[k];c.push(`${k}=${t}`)}c.length&&cl.push(`--\x3e ${x.name} ${c.join(",")}`),_dumpnodo(x),c.length&&cl.push("<--")}else isfn(x)?cl.push(`FN: ${x.fn} ${JSON.stringify(x.pars)}`):"string"==typeof x&&x.length&&cl.push(x)}(nodo),cl.join("\n")}const mgreen$1=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:THREE.DoubleSide});function getorientate(ori,x,y,z){switch(x=x||0,y=y||0,z=z||0,ori.trim().toLowerCase()){case"alp":return{x:y,y:x,z:z};case"apl":return{x:y,y:z,z:x};case"pla":return{x:z,y:x,z:y};case"pal":return{x:z,y:y,z:x};case"lpa":return{x:x,y:z,z:y};default:return{x:x,y:y,z:z}}}function parselavs(ori,id,x=0,y=0,z=0,lavorazioni="",facce="",def=""){let lavcods=function muClComments(codice,tienivuoti){const righe=(code=codice,code.replace(/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|\/\*[\s\S]*?\*\//g,((match,quoted)=>quoted||""))).split(/\r?\n/);var code;const tm=[];let rigaContinua="";for(const riga of righe){let rigaTrim=riga.trim();if(rigaTrim.includes("//")&&(rigaTrim=rigaTrim.split("//")[0].trim()),0!==rigaTrim.length)if(rigaContinua.length>0&&(rigaTrim=rigaContinua+" "+rigaTrim,rigaContinua=""),rigaTrim.endsWith("\\")){rigaTrim=rigaTrim.slice(0,-1);const indiceCommento=rigaTrim.lastIndexOf("//");-1!==indiceCommento&&(rigaTrim=rigaTrim.slice(0,indiceCommento).trim()),rigaContinua=rigaTrim}else tm.push(rigaTrim)}return tm}(lavorazioni),rets=[];for(let lavcod of lavcods){let rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(lavcod);if(rr&&rr[1]){let lav={name:rr[1].trim().toLowerCase(),...getorientate(ori,x,y,z),id:id,facce:facce};if(rr[2]){let aa=getcolonne(rr[2]);for(let a of aa){let i=a.indexOf("=");i>0&&(lav[a.slice(0,i).trim()]=a.slice(i+1).trim())}}rets.push(lav)}}return!rets.length&&def&&rets.push({name:def,...getorientate(ori,x,y,z),id:id,facce:facce}),rets}function getemitter$1(data){let{d:d,name:name,x:x,y:y,z:z,lavs:lavs="",ids:ids="",faces:faces=null,size:size=5}=data;ids=getcolonne(clean(ids,!0));const emitter=new THREE.Object3D;if(emitter.position.set(x,y,z),emitter.userData={emitter:!0,lavs:lavs,ids:ids,faces:faces,size:size,name:name},d){const geometry=new THREE.SphereGeometry(size||5,8,8),material=new THREE.MeshBasicMaterial({color:16711680}),mesh=new THREE.Mesh(geometry,material);emitter.add(mesh)}return emitter}function getreceiver(gcad,data){gcad.gmats.__istask=1;let{d:d,ori:ori="LAP",x:x=0,y:y=0,z:z=0,tipo:tipo="",start:start="",end:end=""}=data;tipo=clean(tipo,!0);const receiver=new THREE.Object3D;if(receiver.position.set(x/2,y/2,z/2),receiver.userData={receiver:!0,ori:(ori||"").trim().toLowerCase(),x:x,y:y,z:z,tipo:tipo,start:start,end:end},d){const geometry=new THREE.BoxGeometry(x,y,z),mesh=new THREE.Mesh(geometry,mgreen$1);mesh.position.set(0,0,0),receiver.add(mesh)}return receiver}function calcolatasks(scena){const emitterWorldPosition=new WeakMap,receiverWorldMatrixInverse=new WeakMap;function boxBoxIntersects(pos,l,x,y,z){return pos.x+l>0&&pos.x-l<x&&pos.y+l>0&&pos.y-l<y&&pos.z+l>0&&pos.z-l<z}function getFacceToccate(pos,sogliafaccia,x,y,z,filtra){const facce=[];function addfaccia(f){filtra&&!filtra.includes(f)||facce.push(f)}return Math.abs(pos.x-0)<sogliafaccia&&addfaccia("s"),Math.abs(pos.x-x)<sogliafaccia&&addfaccia("d"),Math.abs(pos.y-0)<sogliafaccia&&addfaccia("b"),Math.abs(pos.y-y)<sogliafaccia&&addfaccia("a"),Math.abs(pos.z-0)<sogliafaccia&&addfaccia("z"),Math.abs(pos.z-z)<sogliafaccia&&addfaccia("f"),facce.join("")}function getEmitterWorldPosition(emitter){if(!emitterWorldPosition.has(emitter)){const pos=new THREE.Vector3;emitter.getWorldPosition(pos),emitterWorldPosition.set(emitter,pos)}return emitterWorldPosition.get(emitter)}function getReceiverWorldMatrixInverse(receiver){if(!receiverWorldMatrixInverse.has(receiver)){const inv=receiver.matrixWorld.clone().invert();receiverWorldMatrixInverse.set(receiver,inv)}return receiverWorldMatrixInverse.get(receiver)}scena.updateMatrixWorld(!0);const receivers=[],emitters=[];!function scan(obj){obj.userData?.receiver&&receivers.push(obj),obj.userData?.emitter&&emitters.push(obj),obj.children&&obj.children.forEach(scan)}(scena);let tasks=[];for(const receiver of receivers){const{mat:mat,ori:ori,x:x,y:y,z:z,start:start,end:end,tipo:tipo,size:size}=receiver.userData;let singletask={id:mat,...getorientate(ori,x,y,z),tipo:tipo,ori:ori,lavs:[]};start&&singletask.lavs.push(...parselavs(ori,"_start",0,0,0,start,"",""));const matrixInverse=getReceiverWorldMatrixInverse(receiver);for(const emitter of emitters){if("string"==typeof tipo&&""!==tipo){const idx=emitter.userData.ids;if(Array.isArray(idx)&&idx.length>0&&!idx.includes("*")&&!idx.includes(tipo))continue}const posLocalAdj=getEmitterWorldPosition(emitter).clone().applyMatrix4(matrixInverse).clone().add(new THREE.Vector3(x/2,y/2,z/2));if(!boxBoxIntersects(posLocalAdj,emitter.userData.size??0,x,y,z))continue;const facceToccate=getFacceToccate(posLocalAdj,emitter.userData.soglia??2,x,y,z,emitter.userData.faces);facceToccate&&facceToccate.length&&singletask.lavs.push(...parselavs(ori,emitter.userData.name,posLocalAdj.x,posLocalAdj.y,posLocalAdj.z,emitter.userData.lavs,facceToccate,"nd"))}end&&singletask.lavs.push(...parselavs(ori,"_end",0,0,0,end,"","")),singletask.lavs.length&&tasks.push(singletask)}return tasks}function getbb(obj,force=!1){if(!force&&obj.userData.bb)return obj.userData._boundingbox;const box=(new THREE.Box3).setFromObject(obj);return obj.userData._boundingbox=box,box}function setorigine(obj,x=0,y=0,z=0){const min=getbb(obj).min,wrapper=new THREE.Group;return wrapper.add(obj),obj.position.sub(new THREE.Vector3(min.x+x,min.y+y,min.z+z)),wrapper}function scalaoggetto(gcad,originale,scale={}){const box=getbb(originale),size=new THREE.Vector3;box.getSize(size);const min=box.min,axes=["x","y","z","u","v"],norm={};for(let ax of axes){let sc=scale[ax];if(void 0===sc)norm[ax]={s:1};else if("number"==typeof sc)norm[ax]={s:sc};else if("object"==typeof sc){let s=sc.s??1,dim="x"===ax?size.x:"y"===ax?size.y:size.z,minv="x"===ax?min.x:"y"===ax?min.y:min.z;void 0!==sc.distperc&&(sc.dist=dim*sc.distperc),void 0!==sc.dist&&(s=(dim+sc.dist)/dim);let p1=sc.p1?sc.p1+minv:void 0,p2=sc.p2?sc.p2+minv:void 0;void 0!==sc.p1perc&&(p1=minv+dim*sc.p1perc),void 0!==sc.p2perc&&(p2=minv+dim*sc.p2perc),norm[ax]={s:s,p1:p1,p2:p2}}}if(axes.every((ax=>void 0===norm[ax].p1||void 0===norm[ax].p2))){if(1===norm.x.s&&1===norm.y.s&&1===norm.z.s)return originale;const wrapper=new THREE.Group;return wrapper.scale.set(norm.x.s,norm.y.s,norm.z.s),wrapper.add(originale),wrapper}const key=hash(`${originale.uuid}|${JSON.stringify(norm)}`);if(gcad.meshes[key])return gcad.meshes[key];const needAxis={};axes.forEach((ax=>{const{s:s,p1:p1,p2:p2}=norm[ax];needAxis[ax]=!(1===s&&void 0===p1&&void 0===p2)}));const clone=originale.clone(!0);return delete clone?.userData._boundingbox,clone.traverse((n=>{if(n.isMesh){const sOld=n.scale.clone();n.geometry=n.geometry.clone();const posAttr=n.geometry.attributes.position,uvAttr=n.geometry.attributes.uv,trasf=(val,ax)=>{if(!needAxis[ax])return val;const{s:s,p1:p1,p2:p2}=norm[ax];if(void 0===p1||void 0===p2)return val*s;const delta=p2*s-p2;if(val<p1)return val;if(val>=p2)return val+delta;return p1+(val-p1)*((p2-p1+delta)/(p2-p1))};if(posAttr&&(needAxis.x||needAxis.y||needAxis.z)){const arr=posAttr.array;for(let i=0;i<arr.length;i+=3)needAxis.x&&(arr[i]=trasf(arr[i],"x")),needAxis.y&&(arr[i+1]=trasf(arr[i+1],"y")),needAxis.z&&(arr[i+2]=trasf(arr[i+2],"z"));posAttr.needsUpdate=!0,n.geometry.computeVertexNormals()}if(uvAttr&&(needAxis.u||needAxis.v)){const arr=uvAttr.array;for(let i=0;i<arr.length;i+=2)needAxis.u&&(arr[i]=trasf(arr[i],"u")),needAxis.v&&(arr[i+1]=trasf(arr[i+1],"v"));uvAttr.needsUpdate=!0}n.scale.set(sOld.x*norm.x.s,sOld.y*norm.y.s,sOld.z*norm.z.s)}})),gcad.meshes[key]=clone,clone}function posiziona(grp,pos={}){let tm=new THREE.Group;if(grp){let g2=grp.clone(),tm2=g2,{sl:sl=0,sa:sa=0,sp:sp=0,ax:ax=0,ay:ay=0,az:az=0,ul:ul=0,ua:ua=0,up:up=0,scale:scale=1,scx:scx=scale,scy:scy=scale,scz:scz=scale,emitters:emitters,emittersname:emittersname,order:order}=pos;if("number"==typeof order&&g2.traverse((child=>{child.isMesh&&(child.renderOrder=order)})),tm.position.set(sl,sa,sp),tm.rotation.set(ax*PIF,ay*PIF,az*PIF),(ul||ua||up)&&(tm2=new THREE.Group,tm2.add(g2),tm2.position.set(ul,ua,up)),tm.scale.set(scx,scy,scz),tm.add(tm2),emitters&&emitters.length)for(let e of emitters)e.name=e.name||emittersname,tm.add(getemitter(e))}return tm}const SIDE=THREE.DoubleSide;let materialline1=new THREE.LineBasicMaterial({color:3158064}),materialline2=new THREE.LineBasicMaterial({color:5263440});const mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgray1=new THREE.MeshStandardMaterial({color:8421504,roughness:.5,metalness:.4,side:SIDE}),mgray2=new THREE.MeshStandardMaterial({color:11579568,roughness:.5,metalness:.4,side:SIDE}),mred=new THREE.MeshStandardMaterial({color:16711680,roughness:.5,metalness:.4,side:SIDE}),mblue=new THREE.MeshStandardMaterial({color:1982639,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE}),mblack=new THREE.MeshStandardMaterial({color:0,roughness:.5,metalness:.4,side:SIDE}),scaleunit=.001;function groupfromgeometry(geometry,material,x,y,z,name,layer){let child=new THREE.Group;child.position.set(x,y,z),child.name=name;const mesh=new THREE.Mesh(geometry,material);mesh.name=name,mesh.castShadow=!0,mesh.receiveShadow=!0,mesh.layers.set(layer);const edges=new THREE.EdgesGeometry(geometry),lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(30),child.add(mesh),child.add(lineSegments),child}function edgesfromgeometry(g1,layer=30){return getlinesgeom(new THREE.EdgesGeometry(g1,40),layer)}function getlinesgeom(edges,layer=30){const lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(layer),lineSegments}function getmesh(geom,material,layer=1,clone=!1){let m=new THREE.Mesh(geom,clone?material.clone():material);return m.castShadow=!0,m.receiveShadow=!0,m.layers.set(layer),m}function get3dshape(punti,material,layer){if(!punti||punti.length<3)return new THREE.BufferGeometry;const vertices=[];for(let i=0;i<punti.length;i++){const p1=punti[i],p2=punti[(i+1)%punti.length];vertices.push(p1.x,0,p1.y),vertices.push(p2.x,0,p2.y)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3));let m=new THREE.LineSegments(geometry,material);return m.layers.set(layer),m}function creategroup(name){let g=new THREE.Group;return g.name=name||"$$",g}function svuotanodo(n){!function _dispose(node){if(node.children.length){[...node.children].forEach((child=>{_dispose(child),node.remove(child)}))}node.geometry&&node.geometry.dispose(),node.material&&(Array.isArray(node.material)?node.material.forEach((m=>m.dispose())):node.material.dispose())}(n)}function deletegroup(grpbase,name){if(!grpbase?.children)return;let gr=grpbase.children.find((e=>e.name==name));if(gr){for(;gr.children.length>0;){const child=gr.children[0];gr.remove(child)}gr.parent&&gr.parent.remove(gr),gr=null}}function randombasemat(){const material=new THREE.LineBasicMaterial,color=new THREE.Color;return color.setHSL(Math.random(),.7,.4),material.color=color,material}
527
527
  /**
528
528
  * Crea una linea 3D
529
529
  * @param {Object} l - Oggetto contenente punti p1 e p2
@@ -538,7 +538,7 @@ function calcoladivisioni(ff,notused,shape2,oggetti){return makedivisions(ff,sha
538
538
  * @param {THREE.Material} [mat=null] - Materiale da applicare
539
539
  * @param {number} [size=5] - Dimensione della sfera
540
540
  * @returns {THREE.Mesh} Punto 3D
541
- */function getpoint(p,id,mat=null,size=5){const pointgeom=new THREE.SphereGeometry(size,8,8);let tm=new THREE.Mesh(pointgeom,mat||randombasemat());return tm.position.set(p.x,0,p.y),tm}async function smat(gcad,file,op={}){op||(op={});let ky=hash(file+JSON.stringify(op));return gcad.smats[ky]||(gcad.smats[ky]=await async function smat0(gcad,file,op={}){let fileini=file,paramstr="",isColore=!1;file.startsWith("#")&&(isColore=!0,/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})(?=$|[[(])/.test(file)||(file=file.slice(1)));let basefile=file;const paramMatch=file.match(/^(.*)\[([^\]]+)\]$/);paramMatch&&(basefile=paramMatch[1],paramstr=paramMatch[2]);const p={};paramstr&&paramstr.split(/[,;]/).forEach((kv=>{let[k,v]=kv.split("=").map((x=>x.trim()));void 0!==v&&(["e"].includes(k)?p[k]=v.startsWith("0x")?parseInt(v):parseFloat(v):isNaN(parseFloat(v))?p[k]=v:p[k]=parseFloat(v))}));const mappaParam={s:["sx","sy"],sx:["sx"],sy:["sy"],rot:["rot"],br:["brightness"],r:["roughness"],m:["metalness"],h:["bumpScale"],n:["normalScale"],d:["bumpScale"],b:["bumpScale"],e:["emissiveIntensity"],ec:["emissive"],o:["opacity"],t:["transparent"],at:["alphaTest"]};let optot={...op};for(let k in p)if(mappaParam[k])for(let t of mappaParam[k])optot[t]=p[k];let transparent=!!optot?.transparent,sx=optot.sx??optot.s??p.sx??p.s??1,sy=optot.sy??optot.s??p.sy??p.s??1,rot=Number(optot.rot??0)*PIF;try{let tm={roughness:optot.roughness??.5,metalness:optot.metalness??0,side:THREE.DoubleSide,envMapIntensity:optot.env??1};if(void 0!==optot.normalScale){let ns=Number(optot.normalScale);isNaN(ns)||0===ns||(tm.normalScale=new THREE.Vector2(ns,ns))}let hasNormal=!1,hasBump=!1;if(file.includes("(")||isColore){let{base:base,files:files,transparent:t2}=function getFilesToLoad(isColore,basefile){let files=[],m=basefile.match(/^([^(]+)\((([a-zA-Z0-9_\-/]+)_([a-z]+)|([a-z]+))\)$/);if(!m)return{base:basefile,files:files};let base=m[1],transparent=!1,mapalias=m[3]||base,suffstr=m[4]||m[5]||"";isColore||files.push({suff:"",file:`${base}.webp`});for(let s of suffstr)"t"==s?(transparent=!0,m[3]&&suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`})):suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`});return{base:base,files:files,transparent:transparent}}(isColore,basefile);if(transparent=t2,files.some((f=>"n"===f.suff))&&(files=files.filter((f=>"h"!==f.suff))),0===optot.roughness&&(files=files.filter((f=>"r"!==f.suff))),0===optot.metalness&&(files=files.filter((f=>"m"!==f.suff))),0===optot.emissiveIntensity&&(files=files.filter((f=>"e"!==f.suff))),files&&files.length){let textures=await Promise.all(files.map((f=>gcad.tex(f.file,sx,sy,rot).catch((()=>null)))));for(let i=0;i<files.length;i++){let t=textures[i];if(!t)continue;let suff=files[i].suff,{prop:prop,extra:extra}=suffissoMap[suff];tm[prop]=t,"normalMap"===extra?(hasNormal=!0,tm.normalMap=t,tm.normalScale=tm.normalScale??new THREE.Vector2(1,1)):"bumpScale"===extra?(hasBump=!0,tm.bumpMap=t):Array.isArray(extra)&&extra.includes("emissive")&&void 0!==optot.emissiveIntensity&&0!==optot.emissiveIntensity&&(tm.emissive=optot.emissive||16777215,tm.emissiveIntensity=optot.emissiveIntensity??1)}}isColore&&(tm.color=new THREE.Color(base))}else if(basefile.includes(".")){let tx=await gcad.tex(basefile,sx,sy,rot);if(!tx)return mwhite;tm.map=tx}if(hasNormal&&hasBump?delete tm.bumpMap:hasBump&&(tm.bumpScale=optot.bumpScale??.03),tm.transparent=!!transparent,tm.transparent&&(tm.depthWrite=!1,tm.opacity=optot?.opacity??1),void 0!==optot.brightness){let bf=Number(optot.brightness);!isNaN(bf)&&bf>0&&1!==bf&&(tm.color||(tm.color=new THREE.Color(1,1,1)),tm.color.multiplyScalar(bf))}return new THREE.MeshStandardMaterial(tm)}catch(error){return console.log("errore mat:",error.message,fileini),mwhite}}
541
+ */function getpoint(p,id,mat=null,size=5){const pointgeom=new THREE.SphereGeometry(size,8,8);let tm=new THREE.Mesh(pointgeom,mat||randombasemat());return tm.position.set(p.x,0,p.y),tm}async function smat(gcad,file,op={}){op||(op={});let ky=hash(file+JSON.stringify(op));return gcad.smats[ky]||(gcad.smats[ky]=await async function smat0(gcad,file,op={}){let fileini=file,paramstr="",isColore=!1;file.startsWith("#")&&(isColore=!0,/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})(?=$|[[(])/.test(file)||(file=file.slice(1)));let basefile=file;const paramMatch=file.match(/^(.*)\[([^\]]+)\]$/);paramMatch&&(basefile=paramMatch[1],paramstr=paramMatch[2]);const p={};paramstr&&paramstr.split(/[,;]/).forEach((kv=>{let[k,v]=kv.split("=").map((x=>x.trim()));void 0!==v&&(["e"].includes(k)?p[k]=v.startsWith("0x")?parseInt(v):parseFloat(v):isNaN(parseFloat(v))?p[k]=v:p[k]=parseFloat(v))}));const mappaParam={s:["sx","sy"],sx:["sx"],sy:["sy"],rot:["rot"],br:["brightness"],r:["roughness"],m:["metalness"],h:["bumpScale"],n:["normalScale"],d:["bumpScale"],b:["bumpScale"],e:["emissiveIntensity"],ec:["emissive"],o:["opacity"],t:["transparent"],at:["alphaTest"]};let rot0=op.rot,optot={...op};for(let k in p)if(mappaParam[k])for(let t of mappaParam[k])optot[t]=p[k];let transparent=!!optot?.transparent,sx=optot.sx??optot.s??p.sx??p.s??1,sy=optot.sy??optot.s??p.sy??p.s??1,rot=Number((optot.rot??0)+(rot0??0))*PIF;try{let tm={roughness:optot.roughness??.5,metalness:optot.metalness??0,side:THREE.DoubleSide,envMapIntensity:optot.env??1};if(void 0!==optot.normalScale){let ns=Number(optot.normalScale);isNaN(ns)||0===ns||(tm.normalScale=new THREE.Vector2(ns,ns))}let hasNormal=!1,hasBump=!1;if(file.includes("(")||isColore){let{base:base,files:files,transparent:t2}=function getFilesToLoad(isColore,basefile){let files=[],m=basefile.match(/^([^(]+)\((([a-zA-Z0-9_\-/]+)_([a-z]+)|([a-z]+))\)$/);if(!m)return{base:basefile,files:files};let base=m[1],transparent=!1,mapalias=m[3]||base,suffstr=m[4]||m[5]||"";isColore||files.push({suff:"",file:`${base}.webp`});for(let s of suffstr)"t"==s?(transparent=!0,m[3]&&suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`})):suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`});return{base:base,files:files,transparent:transparent}}(isColore,basefile);if(transparent=t2,files.some((f=>"n"===f.suff))&&(files=files.filter((f=>"h"!==f.suff))),0===optot.roughness&&(files=files.filter((f=>"r"!==f.suff))),0===optot.metalness&&(files=files.filter((f=>"m"!==f.suff))),0===optot.emissiveIntensity&&(files=files.filter((f=>"e"!==f.suff))),files&&files.length){let textures=await Promise.all(files.map((f=>gcad.tex(f.file,sx,sy,rot).catch((()=>null)))));for(let i=0;i<files.length;i++){let t=textures[i];if(!t)continue;let suff=files[i].suff,{prop:prop,extra:extra}=suffissoMap[suff];tm[prop]=t,"normalMap"===extra?(hasNormal=!0,tm.normalMap=t,tm.normalScale=tm.normalScale??new THREE.Vector2(1,1)):"bumpScale"===extra?(hasBump=!0,tm.bumpMap=t):Array.isArray(extra)&&extra.includes("emissive")&&void 0!==optot.emissiveIntensity&&0!==optot.emissiveIntensity&&(tm.emissive=optot.emissive||16777215,tm.emissiveIntensity=optot.emissiveIntensity??1)}}isColore&&(tm.color=new THREE.Color(base))}else if(basefile.includes(".")){let tx=await gcad.tex(basefile,sx,sy,rot);if(!tx)return mwhite;tm.map=tx}if(hasNormal&&hasBump?delete tm.bumpMap:hasBump&&(tm.bumpScale=optot.bumpScale??.03),tm.transparent=!!transparent,tm.transparent&&(tm.depthWrite=!1,tm.opacity=optot?.opacity??1),void 0!==optot.brightness){let bf=Number(optot.brightness);!isNaN(bf)&&bf>0&&1!==bf&&(tm.color||(tm.color=new THREE.Color(1,1,1)),tm.color.multiplyScalar(bf))}return new THREE.MeshStandardMaterial(tm)}catch(error){return console.log("errore mat:",error.message,fileini),mwhite}}
542
542
  /**
543
543
  * Estrae tutte le texture usate nella scena glb e le converte in file WEBP.
544
544
  * @param {THREE.Object3D} root - nodo root (es: gltf.scene)
@@ -591,7 +591,7 @@ function getriferimento(dati,x=0,y=0,z=0,id="rif"){"string"==typeof dati&&(dati=
591
591
  * @param {number} dim - Larghezza/altezza della targhetta
592
592
  * @param {Object} options - Opzioni aggiuntive
593
593
  * @returns {THREE.Mesh} Mesh con la targhetta
594
- */function gettarghetta(gcad,testo,dim=100,options={}){const{noSfondo:noSfondo=!1,forcey:forcey=!1,coloreSfondo:coloreSfondo="white",coloreBordo:coloreBordo="darkgray",spessoreBordo:spessoreBordo=3,padding:padding=8,layer:layer=21,fontFamily:fontFamily="Arial",raggioAngoli:raggioAngoli=20}=options;let tt=hash(`T:${coloreSfondo}|${coloreBordo}|${padding}|${spessoreBordo}|${raggioAngoli}|${noSfondo}|${testo}`);testo=testo.split("\n").map((e=>{let size=12,color="black";e=e.trim();let rr=/^\s*#(\w)(\d*),(.*)$/.exec(e);if(rr)switch(size=parseInt(rr[2]||12),e=rr[3],rr[1].toLowerCase()){case"r":color="red";break;case"g":color="green";break;case"b":color="blue";break;case"c":color="cyan"}return{testo:e,size:size,color:color}})).filter((e=>e.testo));const{canvas:canvas,context:context}=function getGlobalCanvas(){return globalLabelCanvas||(globalLabelCanvas=document.createElement("canvas"),globalLabelContext=globalLabelCanvas.getContext("2d",{willReadFrequently:!0})),{canvas:globalLabelCanvas,context:globalLabelContext}}();let maxWidth=0,totalHeight=2*padding;testo.forEach(((riga,i)=>{const{testo:testoRiga,size:size=12}=riga,fontSize=2*size;context.font=`${fontSize}px ${fontFamily}`;const textWidth=context.measureText(testoRiga).width,textHeight=fontSize*(i==testo.length-1?1:1.2);maxWidth=Math.max(maxWidth,textWidth),totalHeight+=textHeight})),maxWidth+=2*padding;const aspectRatio=totalHeight/maxWidth||1;let dimx,dimy;if(forcey?(dimy=dim,dimx=Math.ceil(dimy/aspectRatio)):(dimx=dim,dimy=Math.ceil(dimx*aspectRatio)),!gcad.textures[tt]){const canvasWidth=maxWidth+2*spessoreBordo,canvasHeight=totalHeight+2*spessoreBordo;(canvas.width<canvasWidth||canvas.height<canvasHeight)&&(canvas.width=Math.max(canvas.width,canvasWidth),canvas.height=Math.max(canvas.height,canvasHeight)),context.clearRect(0,0,canvasWidth,canvasHeight);const bgColor=new THREE.Color(coloreSfondo),bgColorStyle=`rgb(${Math.floor(255*bgColor.r)}, ${Math.floor(255*bgColor.g)}, ${Math.floor(255*bgColor.b)})`,borderColor=new THREE.Color(coloreBordo),borderColorStyle=`rgb(${Math.floor(255*borderColor.r)}, ${Math.floor(255*borderColor.g)}, ${Math.floor(255*borderColor.b)})`,radius=raggioAngoli;context.beginPath(),noSfondo||(drawRoundedRect(context,0,0,canvasWidth,canvasHeight,radius+spessoreBordo/2),context.fillStyle=borderColorStyle,context.fill(),context.beginPath(),drawRoundedRect(context,spessoreBordo,spessoreBordo,canvasWidth-2*spessoreBordo,canvasHeight-2*spessoreBordo,radius-spessoreBordo/2),context.fillStyle=bgColorStyle,context.fill());let yPosition=padding+spessoreBordo;testo.forEach((riga=>{const{testo:testoRiga,size:size=12,color:color="black"}=riga,fontSize=2*size;context.font=`${fontSize}px ${fontFamily}`,context.fillStyle=color,context.textAlign="center",context.textBaseline="top",context.fillText(testoRiga,canvasWidth/2,yPosition),yPosition+=1.2*fontSize}));const imageData=context.getImageData(0,0,canvasWidth,canvasHeight),texture=new THREE.DataTexture(imageData.data,imageData.width,imageData.height,THREE.RGBAFormat);texture.needsUpdate=!0,texture.flipY=!0,texture.minFilter=THREE.LinearFilter,texture.magFilter=THREE.LinearFilter,gcad.textures[tt]=texture}const materialeTesto=new THREE.MeshBasicMaterial({map:gcad.textures[tt],transparent:!0,side:SIDE}),geometriaTesto=new THREE.PlaneGeometry(dimx,dimy),meshTesto=new THREE.Mesh(geometriaTesto,materialeTesto);return meshTesto.layers.set(layer),meshTesto.userData={dimx:dimx,dimy:dimy},meshTesto}function drawRoundedRect(ctx,x,y,width,height,radius){radius=Math.min(radius,Math.min(width/2,height/2)),ctx.moveTo(x+radius,y),ctx.lineTo(x+width-radius,y),ctx.quadraticCurveTo(x+width,y,x+width,y+radius),ctx.lineTo(x+width,y+height-radius),ctx.quadraticCurveTo(x+width,y+height,x+width-radius,y+height),ctx.lineTo(x+radius,y+height),ctx.quadraticCurveTo(x,y+height,x,y+height-radius),ctx.lineTo(x,y+radius),ctx.quadraticCurveTo(x,y,x+radius,y),ctx.closePath()}
594
+ */function gettarghetta(gcad,testo,dim=100,options={}){const{noSfondo:noSfondo=!1,forcey:forcey=!1,coloreSfondo:coloreSfondo="white",coloreBordo:coloreBordo="gray",spessoreBordo:spessoreBordo=2,padding:padding=8,layer:layer=21,size:size=24,fontFamily:fontFamily="Arial",raggioAngoli:raggioAngoli=10,order:order=0}=options;testo=(testo||"").replaceAll("\\n","\n");let tt=hash(`T:${coloreSfondo}|${coloreBordo}|${fontFamily}|${padding}|${spessoreBordo}|${raggioAngoli}|${noSfondo}|${testo}`);const sizebase=size??24;testo=testo.split("\n").map((e=>{let size=sizebase,bold=!1,italic=!1,color="black";e=e.trim();let rr=/^\s*#(\w)([bi]?)([\d.]*)[,;](.*)$/.exec(e);if(rr)switch(size=parseFloat(rr[3]||1)*sizebase,"b"===rr[2]&&(bold=!0),"i"===rr[2]&&(italic=!0),e=rr[4],rr[1].toLowerCase()){case"r":color="red";break;case"g":color="green";break;case"b":color="blue";break;case"c":color="cyan"}return{testo:e,size:size,color:color,bold:bold,italic:italic}})).filter((e=>e.testo));const{canvas:canvas,context:context}=function getGlobalCanvas(){return globalLabelCanvas||(globalLabelCanvas=document.createElement("canvas"),globalLabelContext=globalLabelCanvas.getContext("2d",{willReadFrequently:!0})),{canvas:globalLabelCanvas,context:globalLabelContext}}();let maxWidth=0,totalHeight=2*padding;testo.forEach(((riga,i)=>{const{testo:testoRiga,size:size=12}=riga,fontSize=2*size;context.font=`${fontSize}px ${fontFamily}`;const textWidth=context.measureText(testoRiga).width,textHeight=fontSize*(i==testo.length-1?1:1.2);maxWidth=Math.max(maxWidth,textWidth),totalHeight+=textHeight})),maxWidth+=2*padding;const aspectRatio=totalHeight/maxWidth||1;let dimx,dimy;if(forcey?(dimy=dim,dimx=Math.ceil(dimy/aspectRatio)):(dimx=dim,dimy=Math.ceil(dimx*aspectRatio)),!gcad.textures[tt]){const canvasWidth=Math.floor(maxWidth+2*spessoreBordo),canvasHeight=Math.floor(totalHeight+2*spessoreBordo);(canvas.width<canvasWidth||canvas.height<canvasHeight)&&(canvas.width=Math.max(canvas.width,canvasWidth),canvas.height=Math.max(canvas.height,canvasHeight)),context.clearRect(0,0,canvasWidth,canvasHeight);const bgColor=new THREE.Color(coloreSfondo),bgColorStyle=`rgb(${Math.floor(255*bgColor.r)}, ${Math.floor(255*bgColor.g)}, ${Math.floor(255*bgColor.b)})`,borderColor=new THREE.Color(coloreBordo),borderColorStyle=`rgb(${Math.floor(255*borderColor.r)}, ${Math.floor(255*borderColor.g)}, ${Math.floor(255*borderColor.b)})`,radius=raggioAngoli;context.beginPath(),noSfondo||(drawRoundedRect(context,0,0,canvasWidth,canvasHeight,radius+spessoreBordo/2),context.fillStyle=borderColorStyle,context.fill(),context.beginPath(),drawRoundedRect(context,spessoreBordo,spessoreBordo,canvasWidth-2*spessoreBordo,canvasHeight-2*spessoreBordo,radius-spessoreBordo/2),context.fillStyle=bgColorStyle,context.fill());let yPosition=padding+spessoreBordo;testo.forEach((riga=>{const{testo:testoRiga,size:size=12,color:color="black",bold:bold,italic:italic}=riga,fontSize=2*size;context.font=`${bold?"bold ":italic?"italic ":""}${fontSize}px ${fontFamily}`,context.fillStyle=color,context.textAlign="center",context.textBaseline="top",context.fillText(testoRiga,canvasWidth/2,yPosition),yPosition+=1.2*fontSize}));const imageData=context.getImageData(0,0,canvasWidth,canvasHeight),texture=new THREE.DataTexture(imageData.data,imageData.width,imageData.height,THREE.RGBAFormat);texture.needsUpdate=!0,texture.flipY=!0,texture.minFilter=THREE.LinearFilter,texture.magFilter=THREE.LinearFilter,gcad.textures[tt]=texture}const materialeTesto=new THREE.MeshBasicMaterial({map:gcad.textures[tt],transparent:!0,alphaTest:.5,side:SIDE}),geometriaTesto=new THREE.PlaneGeometry(dimx,dimy),meshTesto=new THREE.Mesh(geometriaTesto,materialeTesto);return meshTesto.layers.set(layer),meshTesto.renderOrder=order,meshTesto.userData={dimx:dimx,dimy:dimy},meshTesto}function drawRoundedRect(ctx,x,y,width,height,radius){radius=Math.min(radius,Math.min(width/2,height/2)),ctx.moveTo(x+radius,y),ctx.lineTo(x+width-radius,y),ctx.quadraticCurveTo(x+width,y,x+width,y+radius),ctx.lineTo(x+width,y+height-radius),ctx.quadraticCurveTo(x+width,y+height,x+width-radius,y+height),ctx.lineTo(x+radius,y+height),ctx.quadraticCurveTo(x,y+height,x,y+height-radius),ctx.lineTo(x,y+radius),ctx.quadraticCurveTo(x,y,x+radius,y),ctx.closePath()}
595
595
  /**
596
596
  * Crea una quota tra due punti in 3D sul piano XY
597
597
  * @param {string} testo - Testo da visualizzare nella quota
@@ -602,7 +602,7 @@ function getriferimento(dati,x=0,y=0,z=0,id="rif"){"string"==typeof dati&&(dati=
602
602
  * @param {number} sizetesto - Dimensione del testo
603
603
  * @param {Object} options - Opzioni aggiuntive
604
604
  * @returns {THREE.Group} Gruppo contenente la quota
605
- */function getquota(gcad,testo,x1,y1,x2,y2,altezza=30,offset=0,options={}){const{piano:piano="xy",layer:layer=22,delta:delta=5,spessoreLinea:spessoreLinea=3}=options,pp=(x,y)=>"xz"===piano?[x,0,y]:"yz"===piano?[0,x,y]:[x,y,0],quotaGroup=new THREE.Group;quotaGroup.name="quota";const dx=x2-x1,dy=y2-y1,distanza=Math.sqrt(dx*dx+dy*dy),angolo=Math.atan2(dy,dx),offsetX=-Math.sin(angolo)*offset,offsetY=Math.cos(angolo)*offset,targhetta=gettarghetta(gcad,testo||`${distanza.toFixed(1)}`,2*altezza,{noSfondo:!0,layer:layer,forcey:!0}),{dimx:dimx,dimy:dimy}=targhetta.userData;function getCilindro(puntoInizio,puntoFine,spessore){const direzione=(new THREE.Vector3).subVectors(puntoFine,puntoInizio),lunghezza=direzione.length();let geometria,ky=hash(`c:${spessore}|${lunghezza}`);gcad.geo[ky]?geometria=gcad.geo[ky]:(geometria=new THREE.CylinderGeometry(spessore/2,spessore/2,lunghezza,3,1,!0),gcad.geo[ky]=geometria);const cilindro=new THREE.Mesh(geometria,mblack);cilindro.position.copy(puntoInizio).add(direzione.multiplyScalar(.5));const punto=(new THREE.Vector3).copy(puntoFine);return cilindro.lookAt(punto),cilindro.rotateX(Math.PI/2),cilindro}if(dimx>distanza-delta){targhetta.position.set(distanza/2,altezza,0);const lineaOrizzontale=getCilindro(new THREE.Vector3(...pp(0,0)),new THREE.Vector3(...pp(distanza,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale)}else{const spazioTarghetta=dimx+delta,inizioTarghetta=(distanza-spazioTarghetta)/2,fineTarghetta=inizioTarghetta+spazioTarghetta,lineaOrizzontale1=getCilindro(new THREE.Vector3(...pp(0,0)),new THREE.Vector3(...pp(inizioTarghetta,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale1);const lineaOrizzontale2=getCilindro(new THREE.Vector3(...pp(fineTarghetta,0)),new THREE.Vector3(...pp(distanza,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale2),targhetta.position.set(...pp(distanza/2,0))}const h1=offset>altezza/2?-offset:-altezza/2,h2=-offset>altezza/2?-offset:altezza/2,puntoInizioV1=new THREE.Vector3(...pp(0,h1)),puntoFineV1=new THREE.Vector3(...pp(0,h2)),puntoInizioV2=new THREE.Vector3(...pp(distanza,h1)),puntoFineV2=new THREE.Vector3(...pp(distanza,h2)),lineaVerticale1=getCilindro(puntoInizioV1,puntoFineV1,spessoreLinea);quotaGroup.add(lineaVerticale1);const lineaVerticale2=getCilindro(puntoInizioV2,puntoFineV2,spessoreLinea);return quotaGroup.add(lineaVerticale2),targhetta.userData.updateOrientation=function(camera){camera&&this.quaternion.copy(camera.quaternion)},quotaGroup.add(targhetta),"xy"===piano?(quotaGroup.position.set(x1+offsetX,y1+offsetY,0),quotaGroup.rotation.z=angolo):"xz"===piano?(quotaGroup.position.set(x1+offsetX,0,y1+offsetY),quotaGroup.rotation.y=-angolo):"yz"===piano&&(quotaGroup.position.set(0,x1+offsetX,y1+offsetY),quotaGroup.rotation.x=angolo),quotaGroup.traverse((function(object){object.layers.set(layer)})),quotaGroup}
605
+ */function getquota(gcad,testo,x1,y1,x2,y2,options={}){const{altezza:altezza=30,offset:offset=0,piano:piano="xy",layer:layer=22,delta:delta=5,spessoreLinea:spessoreLinea=3}=options,pp=(x,y)=>"xz"===piano?[x,0,y]:"yz"===piano?[0,x,y]:[x,y,0],quotaGroup=new THREE.Group;quotaGroup.name="quota";const dx=x2-x1,dy=y2-y1,distanza=Math.sqrt(dx*dx+dy*dy),angolo=Math.atan2(dy,dx);testo||(testo="$$"),testo.includes("$$")&&(testo=testo.replace("$$",`${distanza.toFixed(1)}`));let linee=testo.split("\n").length;const offsetX=-Math.sin(angolo)*offset,offsetY=Math.cos(angolo)*offset,targhetta=gettarghetta(gcad,testo,2*altezza*linee,{noSfondo:!0,layer:layer,forcey:!0}),{dimx:dimx,dimy:dimy}=targhetta.userData;function getCilindro(puntoInizio,puntoFine,spessore){const direzione=(new THREE.Vector3).subVectors(puntoFine,puntoInizio),lunghezza=direzione.length();let geometria,ky=hash(`c:${spessore}|${lunghezza}`);gcad.geo[ky]?geometria=gcad.geo[ky]:(geometria=new THREE.CylinderGeometry(spessore/2,spessore/2,lunghezza,3,1,!0),gcad.geo[ky]=geometria);const cilindro=new THREE.Mesh(geometria,mblack);cilindro.position.copy(puntoInizio).add(direzione.multiplyScalar(.5));const punto=(new THREE.Vector3).copy(puntoFine);return cilindro.lookAt(punto),cilindro.rotateX(Math.PI/2),cilindro}if(dimx>distanza-delta){targhetta.position.set(distanza/2,altezza,0);const lineaOrizzontale=getCilindro(new THREE.Vector3(...pp(0,0)),new THREE.Vector3(...pp(distanza,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale)}else{const spazioTarghetta=dimx+delta,inizioTarghetta=(distanza-spazioTarghetta)/2,fineTarghetta=inizioTarghetta+spazioTarghetta,lineaOrizzontale1=getCilindro(new THREE.Vector3(...pp(0,0)),new THREE.Vector3(...pp(inizioTarghetta,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale1);const lineaOrizzontale2=getCilindro(new THREE.Vector3(...pp(fineTarghetta,0)),new THREE.Vector3(...pp(distanza,0)),spessoreLinea);quotaGroup.add(lineaOrizzontale2),targhetta.position.set(...pp(distanza/2,0))}const h1=offset>altezza/2?-offset:-altezza/2,h2=-offset>altezza/2?-offset:altezza/2,puntoInizioV1=new THREE.Vector3(...pp(0,h1)),puntoFineV1=new THREE.Vector3(...pp(0,h2)),puntoInizioV2=new THREE.Vector3(...pp(distanza,h1)),puntoFineV2=new THREE.Vector3(...pp(distanza,h2)),lineaVerticale1=getCilindro(puntoInizioV1,puntoFineV1,spessoreLinea);quotaGroup.add(lineaVerticale1);const lineaVerticale2=getCilindro(puntoInizioV2,puntoFineV2,spessoreLinea);return quotaGroup.add(lineaVerticale2),targhetta.userData.updateOrientation=function(camera){camera&&this.quaternion.copy(camera.quaternion)},quotaGroup.add(targhetta),"xy"===piano?(quotaGroup.position.set(x1+offsetX,y1+offsetY,0),quotaGroup.rotation.z=angolo):"xz"===piano?(quotaGroup.position.set(x1+offsetX,0,y1+offsetY),quotaGroup.rotation.y=-angolo):"yz"===piano&&(quotaGroup.position.set(0,x1+offsetX,y1+offsetY),quotaGroup.rotation.x=angolo),quotaGroup.traverse((function(object){object.layers.set(layer)})),quotaGroup}
606
606
  /**
607
607
  * Crea un cilindro 3D con orientamento personalizzabile
608
608
  * @param {string} ori - Orientamento (X/L, Y/A, Z/P)
@@ -622,7 +622,7 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
622
622
  * @param {THREE.Material} mat - Materiale da applicare
623
623
  * @param {Object} options - Opzioni di configurazione
624
624
  * @returns {Promise<THREE.Group>} Gruppo contenente il box
625
- */function getface(gcad,x,y,mat,op={}){let{repeat:repeat,order:order}=op;const key=hash(`f:${x}|${y}|${repeat?1:0}`);if(!gcad.geo[key]){const geometry=new THREE.PlaneGeometry(x,y),uvs=geometry.attributes.uv;if(repeat)for(let i=0;i<uvs.count;i++)uvs.setXY(i,uvs.getX(i)*x,uvs.getY(i)*y);else{const tm=[[0,1e3],[1e3,1e3],[0,0],[1e3,0]];for(let i=0;i<uvs.count;i++){const t=tm[i];uvs.setXY(i,t[0],t[1])}}uvs.needsUpdate=!0,gcad.geo[key]=geometry}const plane=new THREE.Mesh(gcad.geo[key],mat);return"number"==typeof order&&(plane.renderOrder=order),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=!1,nolines:nolines,centerbase:centerbase=!1,px:px=0,py:py=0,pz:pz=0}=options,grp=new THREE.Group;centerbase?grp.position.set(0,y/2,0):px||py||pz?grp.position.set(px||0,py||0,pz||0):center||grp.position.set(x/2,y/2,z/2);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(!nolines){let segments=edgesfromgeometry(box);grp.add(segments)}return mat&&grp.add(getmesh(box,mat||mwhite)),grp}
625
+ */function scalauv(box){const uvAttr=box.attributes.uv;if(uvAttr){const arr=uvAttr.array;for(let i=0;i<arr.length;i++)arr[i]*=1e3;uvAttr.needsUpdate=!0}}function getface(gcad,x,y,mat,op={}){let{repeat:repeat,order:order}=op;const key=hash(`f:${x}|${y}|${repeat?1:0}`);if(!gcad.geo[key]){const geometry=new THREE.PlaneGeometry(x,y),uvs=geometry.attributes.uv;if(repeat)for(let i=0;i<uvs.count;i++)uvs.setXY(i,uvs.getX(i)*x,uvs.getY(i)*y);else{const tm=[[0,1e3],[1e3,1e3],[0,0],[1e3,0]];for(let i=0;i<uvs.count;i++){const t=tm[i];uvs.setXY(i,t[0],t[1])}}uvs.needsUpdate=!0,gcad.geo[key]=geometry}const plane=new THREE.Mesh(gcad.geo[key],mat);return"number"==typeof order&&(plane.renderOrder=order),plane.position.set(x/2,y/2,0),mat?.transparent&&plane.layers.set(2),plane}function getbox(gcad,x,y,z,mat,options){mat&&mat.isMaterial||(options=mat,mat=void 0),options||(options={});let{center:center=!1,nolines:nolines,centerbase:centerbase=!1,px:px=0,py:py=0,pz:pz=0}=options;const box=new THREE.BoxGeometry(x,y,z);scalauv(box);const grp=new THREE.Group;if(centerbase?grp.position.set(0,y/2,0):px||py||pz?grp.position.set(px||0,py||0,pz||0):center||grp.position.set(x/2,y/2,z/2),!nolines||!mat){let segments=edgesfromgeometry(box);grp.add(segments)}return mat&&grp.add(getmesh(box,mat)),grp}function getcyl(gcad,height,radius,mat,options){options||(options={});let{center:center=!1,nolines:nolines=!1,segments:segments=16,top:top=-1,bottom:bottom=-1,heightSegments:heightSegments=1,openEnded:openEnded=!1,thetaStart:thetaStart=0,thetaLength:thetaLength=2*Math.PI}=options;top<0&&(top=radius),bottom<0&&(bottom=radius);const cylinder=new THREE.CylinderGeometry(top,bottom,height,segments,heightSegments,openEnded,thetaStart,thetaLength);scalauv(cylinder);const mesh=getmesh(cylinder,mat||mwhite),grp=new THREE.Group;if(grp.add(mesh),grp.position.set(0,center?0:height/2,0),!nolines){let segs=edgesfromgeometry(cylinder);grp.add(segs)}return grp}
626
626
  /**
627
627
  * Crea una sfera 3D come gruppo (mesh + edges opzionali).
628
628
  * @param {object} gcad - riferimento (non usato ma coerente con getbox)
@@ -630,7 +630,7 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
630
630
  * @param {THREE.Material} mat - materiale della mesh
631
631
  * @param {object} [options] - opzioni: {center: boolean, nolines: boolean}
632
632
  * @returns {THREE.Group}
633
- */function getsphere(gcad,r,mat,options){options||(options={});let{center:center,nolines:nolines,segmenti:segmenti=16}=options,grp=new THREE.Group;const sphere=new THREE.SphereGeometry(r,2*segmenti,segmenti);if(grp.position.set(0,center?0:r,0),!nolines){let segments=edgesfromgeometry(sphere);grp.add(segments)}return grp.add(getmesh(sphere,mat||mwhite)),grp}
633
+ */function getsphere(gcad,r,mat,options){options||(options={});let{nolines:nolines,segmenti:segmenti=16}=options,grp=new THREE.Group;const sphere=new THREE.SphereGeometry(r,2*segmenti,segmenti);if(scalauv(sphere),!nolines){let segments=edgesfromgeometry(sphere);grp.add(segments)}return grp.add(getmesh(sphere,mat||mwhite)),grp}function getextrude(gcad,pts,h=10,holes=[],mat=void 0,op={}){mat&&mat.isMaterial||(op=mat,mat=void 0),op=op??{};let{stonda:stonda,sx:sx,sy:sy,round:round,nolines:nolines}=op,ky=hash(`${JSON.stringify(pts)}|${h}|${JSON.stringify(op)}|${JSON.stringify(holes)}`);sx=sx??stonda??0,sy=sy??stonda??0;let geom=gcad.geo[ky];if(!geom){const sh=function makeShape(points){const shape=new THREE.Shape;shape.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)shape.lineTo(points[i].x,points[i].y);return shape.closePath(),shape}(pts);holes.forEach((hh=>sh.holes.push(function makePath(points){const path=new THREE.Path;path.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)path.lineTo(points[i].x,points[i].y);return path.closePath(),path}(hh)))),geom=new THREE.ExtrudeGeometry(sh,{depth:h,bevelEnabled:sx>0&&sy>0,bevelSize:sx,bevelThickness:sy,bevelSegments:round?3:1,curveSegments:10}),gcad.geo[ky]=geom}return new THREE.Mesh(geom,mat||mwhite)}function getthorus(gcad,r,tuber=.2,mat,options){options||(options={});let{center:center,nolines:nolines,segmenti:segmenti=16,tubi:tubi=12}=options,grp=new THREE.Group;const thorus=new THREE.TorusGeometry(r,tuber,tubi,2*segmenti);if(scalauv(thorus),grp.position.set(0,center?0:r,0),!nolines){let segments=edgesfromgeometry(thorus);grp.add(segments)}return grp.add(getmesh(thorus,mat||mwhite)),grp}
634
634
  /**
635
635
  * @param {BufferGeometry} geometry
636
636
  * @param {number} tolerance
@@ -641,7 +641,7 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
641
641
  * @param {number} drawMode
642
642
  * @return {BufferGeometry}
643
643
  */
644
- 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&&sectorContainsSector(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}
644
+ 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.getY(i)+y1,uv.getX(i)+x1);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}async function getpannello2(gcad,orientamento,l,a,p,mat,round=0){let bb;switch(orientamento){case"lap":bb=getextrude(gcad,getshape().fromrect(l-2*round,a-2*round).pt,p-2*round,[],mat,{round:round,stonda:round}),bb.position.x=round,bb.position.z=p-round,bb.position.y=a-round,bb.rotation.x=Math.PI;break;case"alp":bb=getextrude(gcad,getshape().fromrect(a-2*round,l-2*round).pt,p-2*round,[],mat,{round:round,stonda:round}),bb.position.x=round,bb.position.z=round,bb.position.y=a-round,bb.rotation.z=-Math.PI/2;break;case"apl":bb=getextrude(gcad,getshape().fromrect(a-2*round,p-2*round).pt,l-2*round,[],mat,{round:round,stonda:round}),bb.position.x=round,bb.position.z=round,bb.position.y=round,bb.rotation.y=Math.PI/2,bb.rotation.z=Math.PI/2;break;case"pal":bb=getextrude(gcad,getshape().fromrect(p-2*round,a-2*round).pt,l-2*round,[],mat,{round:round,stonda:round}),bb.position.x=round,bb.position.z=p-round,bb.position.y=round,bb.rotation.y=Math.PI/2;break;case"pla":bb=getextrude(gcad,getshape().fromrect(p-2*round,l-2*round).pt,a-2*round,[],mat,{round:round,stonda:round}),bb.rotation.z=-Math.PI/2,bb.rotation.x=-Math.PI/2,bb.position.x=round,bb.position.z=round,bb.position.y=round;break;default:bb=getextrude(gcad,getshape().fromrect(l-2*round,p-2*round).pt,a-2*round,[],mat,{round:3,stonda:3}),bb.position.x=round,bb.position.z=round,bb.rotation.x=Math.PI/2,bb.position.y=a-round}return bb}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&&sectorContainsSector(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}
645
645
  /**
646
646
  * Crea una geometria estrusa con opzioni avanzate
647
647
  * @param {string} orient - Orientamento dell'estrusione
@@ -651,7 +651,7 @@ function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)
651
651
  * @param {Array} mats - Array di materiali
652
652
  * @param {Object} options - Opzioni di configurazione
653
653
  * @returns {THREE.Group} Gruppo contenente la geometria estrusa
654
- */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:"",notopholes=options.notopholes||!1,nobottomholes=options.nobottomholes||options.nobaseholes||!1,opinvert=options.invert||!1,open=options.open||!1,grp=new THREE.Group;if(shape){if(!options.nobase){let h1=holes;nobottomholes&&(h1=Array.isArray(nobottomholes)?h1.filter(((_,i)=>!nobottomholes[i])):[]);let g1=bottomgeomfromshape(gcad,!1,shape,open?[]:h1,p0,coeffbase1,coeffbase2,shapebase);options.nolines||grp.add(edgesfromgeometry(g1)),grp.add(getmesh(g1,mats[0]||mwhite))}if(!options.notop){let h1=holes;notopholes&&(h1=Array.isArray(notopholes)?h1.filter(((_,i)=>!notopholes[i])):[]);let g3=bottomgeomfromshape(gcad,!0,shape,open?[]:h1,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&&!nobottomholes&&!notopholes)for(let 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}function estrusopat(gcad,orient,pat,plink,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open,closepat=options.closepat;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase&&!options.open&&!closepat){let gb=new THREE.Group,angolo=angle3point(plink[0],pat.pt[0],pat.pt[1])+Math.PI/2,g1=bottomgeomfromshape(gcad,!1,shape,[],0,-Math.tan(angolo));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&&!options.open&&!closepat){let gt=new THREE.Group,angolo=-(angle3point(pat.pt[pat.npt-2],pat.pt[pat.npt-1],plink[pat.npt-1])+Math.PI/2),g2=bottomgeomfromshape(gcad,!0,shape,[],0,-Math.tan(angolo),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,plink,closepat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${closepat}|${invert}`;if(pat.npt==plink.length){if(ky=hash(ky),!gcad.geo[ky]){const vertices=[],uvs=[],indices=[],np=pbase.length,equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z;let l0=0,pt=pat.pt,ptl=pat.npt;const addpts=(ss,mat,deltav,coeffz)=>{for(const s of ss){let p=new THREE.Vector3(s.x,s.y,s.x*coeffz);p.applyMatrix4(mat),vertices.push(p.x,p.y,p.z),uvs.push(s.u,s.v+deltav)}};let lp=ptl;for(let ii=0;ii<ptl;ii++){let angolo;angolo=ii<ptl-1?angle3point(plink[ii],pt[ii],pt[ii+1])+Math.PI/2:-(angle3point(pt[ii-1],pt[ii],plink[ii])+Math.PI/2);let coefficente=-Math.tan(angolo),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,coefficente),l0+=seg1.l}if(closepat){let seg1=pat.infosegmento(0,!0),obj=new THREE.Object3D;obj.position.set(seg1.x,0,seg1.y),obj.rotation.set(0,(90-seg1.ang)*PIF,0);let angolo=angle3point(pt[ptl-1],pt[0],plink[0])+Math.PI/2,coefficente=-Math.tan(angolo);obj.updateMatrix(),addpts(pbase,obj.matrix,l0,coefficente),l0+=seg1.l,lp++}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,plink,closepat?1:0,invert?1:0);return geo1&&(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={}}}}
654
+ */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:"",notopholes=options.notopholes||!1,nobottomholes=options.nobottomholes||options.nobaseholes||!1,opinvert=options.invert||!1,open=options.open||!1,grp=new THREE.Group;if(shape){if(!options.nobase){let h1=holes;nobottomholes&&(h1=Array.isArray(nobottomholes)?h1.filter(((_,i)=>!nobottomholes[i])):[]);let g1=bottomgeomfromshape(gcad,!1,shape,open?[]:h1,p0,coeffbase1,coeffbase2,shapebase);options.nolines||grp.add(edgesfromgeometry(g1)),grp.add(getmesh(g1,mats[0]||mwhite))}if(!options.notop){let h1=holes;notopholes&&(h1=Array.isArray(notopholes)?h1.filter(((_,i)=>!notopholes[i])):[]);let g3=bottomgeomfromshape(gcad,!0,shape,open?[]:h1,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(let i=0;i<holes.length;i++){let h=holes[i];if(Array.isArray(notopholes)){if(notopholes[i])continue}else if(notopholes)continue;if(Array.isArray(nobottomholes)){if(nobottomholes[i])continue}else if(nobottomholes)continue;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}function estrusopat(gcad,orient,pat,plink,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open,closepat=options.closepat;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase&&!options.open&&!closepat){let gb=new THREE.Group,angolo=angle3point(plink[0],pat.pt[0],pat.pt[1])+Math.PI/2,g1=bottomgeomfromshape(gcad,!1,shape,[],0,-Math.tan(angolo));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&&!options.open&&!closepat){let gt=new THREE.Group,angolo=-(angle3point(pat.pt[pat.npt-2],pat.pt[pat.npt-1],plink[pat.npt-1])+Math.PI/2),g2=bottomgeomfromshape(gcad,!0,shape,[],0,-Math.tan(angolo),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,plink,closepat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${closepat}|${invert}`;if(pat.npt==plink.length){if(ky=hash(ky),!gcad.geo[ky]){const vertices=[],uvs=[],indices=[],np=pbase.length,equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z;let l0=0,pt=pat.pt,ptl=pat.npt;const addpts=(ss,mat,deltav,coeffz)=>{for(const s of ss){let p=new THREE.Vector3(s.x,s.y,s.x*coeffz);p.applyMatrix4(mat),vertices.push(p.x,p.y,p.z),uvs.push(s.u,s.v+deltav)}};let lp=ptl;for(let ii=0;ii<ptl;ii++){let angolo;angolo=ii<ptl-1?angle3point(plink[ii],pt[ii],pt[ii+1])+Math.PI/2:-(angle3point(pt[ii-1],pt[ii],plink[ii])+Math.PI/2);let coefficente=-Math.tan(angolo),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,coefficente),l0+=seg1.l}if(closepat){let seg1=pat.infosegmento(0,!0),obj=new THREE.Object3D;obj.position.set(seg1.x,0,seg1.y),obj.rotation.set(0,(90-seg1.ang)*PIF,0);let angolo=angle3point(pt[ptl-1],pt[0],plink[0])+Math.PI/2,coefficente=-Math.tan(angolo);obj.updateMatrix(),addpts(pbase,obj.matrix,l0,coefficente),l0+=seg1.l,lp++}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,plink,closepat?1:0,invert?1:0);return geo1&&(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={}}}}
655
655
  /*********************************/
656
656
  /********** EXTENSIONS ***********/
657
657
  /*********************************/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"};
@@ -1095,7 +1095,7 @@ constructor(data,position,debugMessage){this.data=data,this.offset=position,this
1095
1095
  /**
1096
1096
  * Libera tutte le risorse caricate
1097
1097
  */
1098
- async function clearmat(){for(const key in _textures)if(_textures[key]){const texture=await _textures[key];texture?.dispose()}for(const key in _smats)_smats[key]&&_smats[key]?.dispose();for(const[key,texOrPromise]of textureCache.entries()){const texture=texOrPromise instanceof Promise?await texOrPromise:texOrPromise;texture?.dispose&&texture.dispose()}textureCache.clear(),_textures={},_smats={}}return{clearmatricole:()=>{_gmatricole={}},islog:islog,clear:async function clear(){function destroymesh(mesh){function disposeMaterial(material){material.map&&material.map.dispose(),material.lightMap&&material.lightMap.dispose(),material.bumpMap&&material.bumpMap.dispose(),material.normalMap&&material.normalMap.dispose(),material.specularMap&&material.specularMap.dispose(),material.dispose()}mesh&&mesh.traverse((child=>{child.isMesh&&(child.geometry.dispose(),child.material&&(Array.isArray(child.material)?child.material.forEach(disposeMaterial):disposeMaterial(child.material)))}))}_gmatricole={},THREE.Cache.clear();for(const c in _geometries)_geometries[c]?.dispose();for(const key in _meshes)if(_meshes[key]){destroymesh(await _meshes[key])}await clearmat(),_movs={},_textures={},_meshes={},_geometries={},_smats={},_scripts={}},clearmat:clearmat,getScript:async function getScript(file){file.endsWith(".custom")?file=file.slice(-7):file.endsWith(".js")&&(file=file.slice(-3));let key=hash(`${getcat()}|${file}`);if(!_scripts[key]){let script;try{script=await P.fetch("mufiles/customfn",{id:getcat(),name:file,ispar:1})}catch(error){script=`log('undefined ${getcat()}/${file}: ${error.message}');`}_scripts[key]=script}return _scripts[key]},checkScripts:async function checkScripts(files){let cl=[];if(!files||!Array.isArray(files))return;let ct=getcat();for(let f of files){let key=hash(`${ct}|${f}`);_scripts[key]||cl.push(f)}if(cl?.length){let scripts=await P.fetch("mufiles/customfn",{id:ct,name:cl,ispar:1});if(scripts)for(let s of scripts){let key=hash(`${ct}|${s.n}`);_scripts[key]=s.v}}},get loaderGLTF(){return _loaderGLTF},get gmats(){return _gmatricole},scripts:()=>Object.keys(_scripts),get geo(){return _geometries},get movs(){return _movs},get textures(){return _textures},get smats(){return _smats},dump(){console.log(`SMATS:\n${Object.keys(_smats).join(" - ")};\nGEOMS:\n${Object.keys(_geometries).join(" - ")};\nTEX:\n${Object.keys(_textures).join(" - ")};\nMESH:\n${Object.keys(_meshes).join(" - ")};\n`)},get cat(){return getcat()},pushcat(cat){cats.push(cat)},popcat:()=>(cats.length>1&&cats.length--,getcat()),async tex(file,sx=1,sy,rot){sy||(sy=sx),rot||(rot=0);const key=hash(`${getcat()}|${file}|${sx}|${sy}|${rot}`);return _textures[key]||(_textures[key]=new Promise(((resolve,reject)=>{let url;if(file.startsWith("https://"))url=file;else if(P._cdn)if(file.includes("/")){let v=file.split("/");url=`${P._cdn}${v[0]}/textures/${v[1]}`}else url=`${P._cdn}${getcat()}/textures/${file}`;else url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"textures",name:file,force:1});if(textureCache.has(url)){const tex=textureCache.get(url).clone();return tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,void resolve(tex)}_loadertex.load(url,(tex=>{textureCache.set(url,tex),tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,resolve(tex)}),void 0,(error=>{console.log(`Manca Texture ${file}!. questo rallenta molto il processo`),delete _textures[key],resolve(void 0)}))}))),_textures[key]},async get3ds(file,callback,ky=""){file.endsWith(".3ds")&&(file=file.slice(0,-4));const modifierKey=callback?hash(callback.toString()):"nomod",key=hash(`${getcat()}|${file}.3ds|${modifierKey}|${ky}`);return _meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{let url,urlt="";file.startsWith("https://")?(url=`${file}.3ds`,urlt=url):P._cdn?(url=`${P._cdn}${getcat()}/3d/${file}.3ds`,urlt=`${P._cdn}${getcat()}/3d/${file}/`):(url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:".3ds"}),urlt=url+"&tex="),_loader3DS.setResourcePath(urlt),_loader3DS.load(url,(object=>{callback&&object.traverse((child=>{child.isMesh&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))})),resolve(object)}),void 0,(error=>{delete _meshes[key],resolve(void 0)}))}))),_meshes[key]},async getglb(file,textures,callback=null,ky=""){const ext=".glb";file.endsWith(ext)&&(file=file.slice(0,-4)),file.startsWith("https://")||(file=file.replace(/\//g,"+"));let elemento=(file=file.split("+"))[1];file=file[0],Array.isArray(textures)||(textures=[]);const modifierKey=callback?hash(callback.toString()):"nomod",texturesKey=textures.map((tex=>tex?.uuid||"null")).join("|"),key=hash(`${getcat()}|${file}${ext}|${texturesKey}|${modifierKey}|${ky}`);_meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{let url;url=file.startsWith("https://")?`${file}.glb`:P._cdn?`${P._cdn}${getcat()}/3d/${file}.glb`:P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:ext}),_loaderGLTF.setPath(""),_loaderGLTF.setResourcePath((resource=>(console.log("risorsa",resource),`${url}&tex=${resource}`))),_loaderGLTF.load(url,(async gltf=>{gltf.scene.traverse((child=>{if(child.isMesh){child.frustumCulled=!0;(Array.isArray(child.material)?child.material:[child.material]).forEach((material=>{if(!material||!material.map)return;const originalTexName=material.map.source?.data?.src;if(!originalTexName)return;const match=originalTexName.match(/(\d{2})\.jpg$/);if(!match)return;const textureIndex=parseInt(match[1]);textures[textureIndex]&&(material.map=textures[textureIndex],material.needsUpdate=!0)})),callback&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))}})),resolve(gltf.scene)}),void 0,(error=>{console.log(error),delete _meshes[key],resolve(void 0)}))})));let tm=_meshes[key];if(elemento){let n=tm?.getObjectByName(elemento);n&&(tm=n)}return tm}}}const originalMaterials=new Map;
1098
+ async function clearmat(){for(const key in _textures)if(_textures[key]){const texture=await _textures[key];texture?.dispose()}for(const key in _smats)_smats[key]&&_smats[key]?.dispose();for(const[key,texOrPromise]of textureCache.entries()){const texture=texOrPromise instanceof Promise?await texOrPromise:texOrPromise;texture?.dispose&&texture.dispose()}textureCache.clear(),_textures={},_smats={}}return{clearmatricole:()=>{_gmatricole={}},islog:islog,clear:async function clear(){function destroymesh(mesh){function disposeMaterial(material){material.map&&material.map.dispose(),material.lightMap&&material.lightMap.dispose(),material.bumpMap&&material.bumpMap.dispose(),material.normalMap&&material.normalMap.dispose(),material.specularMap&&material.specularMap.dispose(),material.dispose()}mesh&&mesh.traverse((child=>{child.isMesh&&(child.geometry.dispose(),child.material&&(Array.isArray(child.material)?child.material.forEach(disposeMaterial):disposeMaterial(child.material)))}))}_gmatricole={},THREE.Cache.clear();for(const c in _geometries)_geometries[c]?.dispose();for(const key in _meshes)if(_meshes[key]){destroymesh(await _meshes[key])}await clearmat(),_movs={},_textures={},_meshes={},_geometries={},_smats={},_scripts={}},clearmat:clearmat,getScript:async function getScript(file){file.endsWith(".custom")?file=file.slice(-7):file.endsWith(".js")&&(file=file.slice(-3));let key=hash(`${getcat()}|${file}`);if(!_scripts[key]){let script;try{script=await P.fetch("mufiles/customfn",{id:getcat(),name:file,ispar:1})}catch(error){script=`log('undefined ${getcat()}/${file}: ${error.message}');`}_scripts[key]=script}return _scripts[key]},checkScripts:async function checkScripts(files){let cl=[];if(!files||!Array.isArray(files))return;let ct=getcat();for(let f of files){let key=hash(`${ct}|${f}`);_scripts[key]||cl.push(f)}if(cl?.length){let scripts=await P.fetch("mufiles/customfn",{id:ct,name:cl,ispar:1});if(scripts)for(let s of scripts){let key=hash(`${ct}|${s.n}`);_scripts[key]=s.v}}},get loaderGLTF(){return _loaderGLTF},get gmats(){return _gmatricole},scripts:()=>Object.keys(_scripts),get geo(){return _geometries},get movs(){return _movs},get textures(){return _textures},get smats(){return _smats},get meshes(){return _meshes},dump(){console.log(`SMATS:\n${Object.keys(_smats).join(" - ")};\nGEOMS:\n${Object.keys(_geometries).join(" - ")};\nTEX:\n${Object.keys(_textures).join(" - ")};\nMESH:\n${Object.keys(_meshes).join(" - ")};\n`)},get cat(){return getcat()},pushcat(cat){cats.push(cat)},popcat:()=>(cats.length>1&&cats.length--,getcat()),async tex(file,sx=1,sy,rot){sy||(sy=sx),rot||(rot=0);const key=hash(`${getcat()}|${file}|${sx}|${sy}|${rot}`);return _textures[key]||(_textures[key]=new Promise(((resolve,reject)=>{let url;if(file.startsWith("https://"))url=file;else if(P._cdn)if(file.includes("/")){let v=file.split("/");url=`${P._cdn}${v[0]}/textures/${v[1]}`}else url=`${P._cdn}${getcat()}/textures/${file}`;else url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"textures",name:file,force:1});if(textureCache.has(url)){const tex=textureCache.get(url).clone();return tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,void resolve(tex)}_loadertex.load(url,(tex=>{textureCache.set(url,tex),tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,resolve(tex)}),void 0,(error=>{console.log(`Manca Texture ${file}!. questo rallenta molto il processo`),delete _textures[key],resolve(void 0)}))}))),_textures[key]},async get3ds(file,callback,ky=""){file.endsWith(".3ds")&&(file=file.slice(0,-4));const modifierKey=callback?hash(callback.toString()):"nomod",key=hash(`${getcat()}|${file}.3ds|${modifierKey}|${ky}`);return _meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{let url,urlt="";file.startsWith("https://")?(url=`${file}.3ds`,urlt=url):P._cdn?(url=`${P._cdn}${getcat()}/3d/${file}.3ds`,urlt=`${P._cdn}${getcat()}/3d/${file}/`):(url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:".3ds"}),urlt=url+"&tex="),_loader3DS.setResourcePath(urlt),_loader3DS.load(url,(object=>{callback&&object.traverse((child=>{child.isMesh&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))})),resolve(object)}),void 0,(error=>{delete _meshes[key],resolve(void 0)}))}))),_meshes[key]},async getglb(file,textures,callback=null,ky=""){const ext=".glb";file.endsWith(ext)&&(file=file.slice(0,-4)),file.startsWith("https://")||(file=file.replace(/\//g,"+"));let elemento=(file=file.split("+"))[1];file=file[0],Array.isArray(textures)||(textures=[]);const modifierKey=callback?hash(callback.toString()):"nomod",texturesKey=textures.map((tex=>tex?.uuid||"null")).join("|"),key=hash(`${getcat()}|${file}${ext}|${texturesKey}|${modifierKey}|${ky}`);_meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{let url;url=file.startsWith("https://")?`${file}.glb`:P._cdn?`${P._cdn}${getcat()}/3d/${file}.glb`:P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:ext}),_loaderGLTF.setPath(""),_loaderGLTF.setResourcePath((resource=>(console.log("risorsa",resource),`${url}&tex=${resource}`))),_loaderGLTF.load(url,(async gltf=>{gltf.scene.traverse((child=>{if(child.isMesh){child.frustumCulled=!0;(Array.isArray(child.material)?child.material:[child.material]).forEach((material=>{if(!material||!material.map)return;const originalTexName=material.map.source?.data?.src;if(!originalTexName)return;const match=originalTexName.match(/(\d{2})\.jpg$/);if(!match)return;const textureIndex=parseInt(match[1]);textures[textureIndex]&&(material.map=textures[textureIndex],material.needsUpdate=!0)})),callback&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))}})),resolve(gltf.scene)}),void 0,(error=>{console.log(error),delete _meshes[key],resolve(void 0)}))})));let tm=_meshes[key];if(elemento){let n=tm?.getObjectByName(elemento);n&&(tm=n)}return tm}}}const originalMaterials=new Map;
1099
1099
  /**
1100
1100
  * Salva i materiali originali di tutti i mesh nel gruppo (solo layer <= 20)
1101
1101
  * @param {THREE.Object3D} gruppo
@@ -1115,4 +1115,4 @@ async function clearmat(){for(const key in _textures)if(_textures[key]){const te
1115
1115
  * @param {THREE.Object3D} gruppo - oggetto root
1116
1116
  * @param {Array<{ mats: string[], name?: string }>} matricole - elenco da evidenziare
1117
1117
  * @returns {Promise<File[]>}
1118
- */async function evidenziaColli(gruppo,matricole,callback){salvaMaterialiOriginali(gruppo);const SIDE=THREE.DoubleSide,mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE});let ii=0;try{for(let mts of matricole)ii++,mts.name||(mts.name=`collo_${ii}`),applicaEvidenziazione(gruppo,mts.mats,mwhite,mgreen),await callback(mts)}catch(err){console.error("Errore durante evidenzia:",err)}finally{ripristinaMaterialiOriginali()}}function TODEG(a,dec=1){let C=10**dec;return Math.round(180*a*C/Math.PI)/C}function TORAD(a,dec=3){let C=10**dec;return Math.round(a*PIF*C)/C}const blocked={window:void 0,self:void 0,globalThis:void 0,document:void 0,Function:void 0,eval:void 0,fetch:void 0,XMLHttpRequest:void 0};function getOggetto(obj,exclude=[]){if(Array.isArray(obj))return obj.map((item=>getOggetto(item,exclude)));if(obj&&"object"==typeof obj){const result={};for(const[key,value]of Object.entries(obj))"function"==typeof value||exclude&&exclude.includes(key)||(result[key]=getOggetto(value,exclude));return result}return obj}async function evalcustomfunction(amb,code,values,objects){try{values||(values={}),objects||(objects={});const params={GCAD:!1,...values,A:amb,V:amb.vari,amb:amb,log:function addlog(...pars){const sanitized=pars.map((p=>getOggetto(p)));console.log(...sanitized)},Math:Math,clean:clean,SP:SP,Punto2:Punto2,Linea2:Linea2,clamp:clamp,hash:hash,PIF:PIF,getshape:getshape,shapeclip:shapeclip,...objects},paramNames=[...Object.keys(params),...Object.keys(blocked)],paramValues=[...Object.values(params),...Object.values(blocked)],fn=new Function(...paramNames,`\n try {\n return (async () => {\n ${code}\n })();\n } catch (err) {\n err.stack = '[SCRIPT] ' + err.stack;\n throw err;\n }`);return await fn(...paramValues)}catch(error){throw console.error("Errore durante l'esecuzione:",error),error}}function setLineColorMode(white){white?(materialline1.color.set(16777215),materialline2.color.set(16777215)):(materialline1.color.set(3158064),materialline2.color.set(5263440)),materialline1.needsUpdate=!0,materialline2.needsUpdate=!0}export{Linea2,Matrix3D,PIF,Punto2,SIDE,SP,TODEG,TORAD,Vis2d,addmovpivot,angle2vec,angle3point,blocked,calcolatasks,clamp,clean,creategroup,deletegroup,dxfbulge,edgesfromgeometry,elaborapercorso,errorescript,estruso,estrusopat,evalcustomfunction,evidenziaColli,extractTextures,fondilinee,get3dshape,getOggetto,getbordi,getbox,getcilindro,getcyl,getdumpmacro,getemitter,getface,getfakeshadow,getfakeshadow2,getline,getlinesgeom,getmesh,getmovimento,getnodebyid,getpannello,getpoint,getprojectkeys,getptsoffset,getpunto,getquota,getreceiver,getriferimento,getshape,getsphere,getsprite,getsubrules,gettarghetta,groupfromgeometry,hash,infoestrudi,isfn,ismacro,mapvertices,materialline1,materialline2,mblack,mblue,mgray1,mgray2,mgreen,mred,mwhite,newgcad,normal2,posiziona,raccordabezier,randombasemat,revolve,ripristinaMaterialiOriginali,salvaMaterialiOriginali,scaleunit,setLineColorMode,shapeclip,smat,spritemat,svuotanodo,valutagrafica};
1118
+ */async function evidenziaColli(gruppo,matricole,callback){salvaMaterialiOriginali(gruppo);const SIDE=THREE.DoubleSide,mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE});let ii=0;try{for(let mts of matricole)ii++,mts.name||(mts.name=`collo_${ii}`),applicaEvidenziazione(gruppo,mts.mats,mwhite,mgreen),await callback(mts)}catch(err){console.error("Errore durante evidenzia:",err)}finally{ripristinaMaterialiOriginali()}}function TODEG(a,dec=1){let C=10**dec;return Math.round(180*a*C/Math.PI)/C}function TORAD(a,dec=3){let C=10**dec;return Math.round(a*PIF*C)/C}const blocked={window:void 0,self:void 0,globalThis:void 0,document:void 0,Function:void 0,eval:void 0,fetch:void 0,XMLHttpRequest:void 0};function getOggetto(obj,exclude=[]){if(Array.isArray(obj))return obj.map((item=>getOggetto(item,exclude)));if(obj&&"object"==typeof obj){const result={};for(const[key,value]of Object.entries(obj))"function"==typeof value||exclude&&exclude.includes(key)||(result[key]=getOggetto(value,exclude));return result}return obj}async function evalcustomfunction(amb,code,values,objects){try{values||(values={}),objects||(objects={});const params={GCAD:!1,...values,A:amb,V:amb.vari,amb:amb,log:function addlog(...pars){const sanitized=pars.map((p=>getOggetto(p)));console.log(...sanitized)},Math:Math,getcolonne:getcolonne,clean:clean,SP:SP,Punto2:Punto2,Linea2:Linea2,clamp:clamp,hash:hash,PIF:PIF,getshape:getshape,shapeclip:shapeclip,...objects},paramNames=[...Object.keys(params),...Object.keys(blocked)],paramValues=[...Object.values(params),...Object.values(blocked)],fn=new Function(...paramNames,`\n try {\n return (async () => {\n ${code}\n })();\n } catch (err) {\n err.stack = '[SCRIPT] ' + err.stack;\n throw err;\n }`);return await fn(...paramValues)}catch(error){throw console.error("Errore durante l'esecuzione:",error),error}}function setLineColorMode(white){white?(materialline1.color.set(16777215),materialline2.color.set(16777215)):(materialline1.color.set(3158064),materialline2.color.set(5263440)),materialline1.needsUpdate=!0,materialline2.needsUpdate=!0}export{Linea2,Matrix3D,PIF,Punto2,SIDE,SP,TODEG,TORAD,Vis2d,addmovpivot,angle2vec,angle3point,blocked,calcolatasks,clamp,clean,creategroup,deletegroup,dxfbulge,edgesfromgeometry,elaborapercorso,errorescript,estruso,estrusopat,evalcustomfunction,evidenziaColli,extractTextures,fondilinee,get3dshape,getOggetto,getbb,getbordi,getbox,getcilindro,getcyl,getdumpmacro,getemitter$1 as getemitter,getextrude,getface,getfakeshadow,getfakeshadow2,getline,getlinesgeom,getmesh,getmovimento,getnodebyid,getpannello,getpannello2,getpoint,getptsoffset,getpunto,getquota,getreceiver,getriferimento,getshape,getsphere,getsprite,getsubrules,gettarghetta,getthorus,groupfromgeometry,hash,infoestrudi,isfn,ismacro,mapvertices,materialline1,materialline2,mblack,mblue,mgray1,mgray2,mgreen,mred,mwhite,newgcad,normal2,posiziona,raccordabezier,randombasemat,revolve,ripristinaMaterialiOriginali,salvaMaterialiOriginali,scalaoggetto,scaleunit,setLineColorMode,setorigine,shapeclip,smat,spritemat,svuotanodo,valutagrafica};
package/bin/markuno.js CHANGED
@@ -234,7 +234,7 @@ this.amb=amb}
234
234
  * Trova la prima opzione valida tra quelle disponibili
235
235
  * @param {string} opz - Opzione da controllare per prima
236
236
  * @returns {string|undefined} Prima opzione valida trovata o undefined
237
- */firstvalid(opz){const i=opz.indexOf(",");if(i>0&&(opz=opz.slice(0,i).trim()),opz&&this.isvalidopz(opz))return opz;if(this.vdef&&this.vdef.length)for(const o of this.vdef)if(this.isvalidopz(o))return o;const tm=Object.keys(this.rows).sort();for(let i=0;i<tm.length;i++){const x=tm[i];if(!(i<tm.length-1&&tm[i+1].startsWith(x+"."))&&this.isvalidopz(x))return x}}
237
+ */firstvalid(opz,defs=void 0){const i=opz.indexOf(",");if(i>0&&(opz=opz.slice(0,i).trim()),opz&&this.isvalidopz(opz))return opz;if(defs&&defs.length)for(const o of defs)if(this.isvalidopz(o))return o;if(this.vdef&&this.vdef.length)for(const o of this.vdef)if(this.isvalidopz(o))return o;const tm=Object.keys(this.rows).sort();for(let i=0;i<tm.length;i++){const x=tm[i];if(!(i<tm.length-1&&tm[i+1].startsWith(x+"."))&&this.isvalidopz(x))return x}}
238
238
  /**
239
239
  * Resetta tutti i filtri applicati alla variante
240
240
  */resetfilter(){delete this._valids;for(const x in this.rows)this.rows[x].annulla=0}
@@ -251,9 +251,9 @@ this.amb=amb}
251
251
  * @param {Object|string} content - Contenuto da caricare, può essere un oggetto o una stringa
252
252
  * @returns {Promise<void>} Promise che si risolve al completamento del caricamento
253
253
  */async loadContentExtended(content){if("object"==typeof content){for(const x in content)["rows","des","h","alias","obbligo"].includes(x)&&(this[x]=content[x]);"string"==typeof content.def&&content.def.length&&(this.vdef=getcolonne(content.def.trim().toLowerCase())),content.filter&&content.filter.length&&(this.limits=parselimitifromdb(content.filter))}else await this._loadContent(muClComments(content,!1))}todata(){return{name:this.name,des:this.des,alias:this.alias,obbligo:this.obbligo,h:this.h,rows:this.rows,limits:this.limits,key:this.key}}}const _nofunc={};async function getcbfunc(tm,cmd,pars,vari,amb,output){if(cbFunc){if(_nofunc[cmd])return"";let a=await cbFunc(cmd,pars,vari,amb,output);return isObject(a)||(a=(a||"").trim(),"!"==a&&(_nofunc[cmd]=!0,a="")),a}return tm}async function intvaluta(amb,mac,str){return await amb.vari.valuta(str,(async(fun,pars)=>{if("dim"===fun){let dm=muCalc(pars[1]),vv=await dammivariante(amb,mac,pars[2]),col=parseInt(pars[3])||2;return vv&&vv.fromdim?vv.fromdim(dm,col):dm}return await getcbfunc(`**fun:${fun}**`,fun,pars,amb.vari,amb)}))}async function dammivariante(amb,macro,ky){let tm;return tm=macro&&macro?.localvar&&macro.localvar[ky]?macro.localvar[ky]:await amb.getvariante(ky),tm}async function impostavariante(amb,macro,a,b,head){let tm,ky=a;if((b=b||"")&&"string"==typeof b){const k=b.indexOf(":");k>=0&&(k>0&&(ky=clean(b.slice(0,k))),b=b.slice(k+1))}
254
- /** @type {Variante} */if(head&&head.alias&&(ky=head.alias),macro&&macro.paralias&&macro.paralias[a]&&(ky=macro.paralias[a]),tm=await dammivariante(amb,macro,ky),tm)if(head&&head.t){head.des||(head.des=tm.des);let x8=head?.filtra||"";if(x8.includes("$")&&(x8=await amb.vari.valuta(x8)),"m"===head.t){let col=2;if(b.includes(":")){const xx=b.split(":");col=parseInt(xx[1]),b=xx[0]}tm.limita(x8),b=tm.fromdim(parseFloat(b),col)}else{tm.limita(x8);const b1=tm.firstvalid(b);b=tm.tovar(b1)}}else tm.resetfilter(),b=tm.firstvalid(b),b=tm.tovar(b);else head&&head.t&&head.t;return amb.vari.add(a,b),b}async function pushpars(amb,macro,parsfunzione,parsinit){const fatti={},vals=[];if(parsfunzione)for(const x of parsfunzione){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}if(parsinit)for(const x of parsinit){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}return vals}function poppars(amb,tm){if(tm)for(const x of tm)amb.vari.add(x.v,x.o)}const outpush=(output,a)=>{null!=a&&null!=a&&("string"==typeof a&&a.startsWith("_ ")&&output.length>0&&"string"==typeof output[output.length-1]?output[output.length-1]+=a.slice(2):output.push(...a.split("\n")))};async function muEval(amb,mac,codice,options){if(!Array.isArray(codice))return errori.add("codice is not a valid parsed array"),[];options||(options={}),options.id||(options.id="_"),options._stackmacro||(options._stackmacro=0),options.limited||(options.limited=!1),amb||errori.add("amb deve essere definito");const vari=amb.vari;amb.maxdelays,amb.cat;const output=[];let macro,pars,xid;tk();for(let ii=0;ii<codice.length;){let riga=codice[ii];switch(riga.tipo){case"IFDEF":case"IFNDEF":case"IF":{const tm="IF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"IFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);riga.next?(codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)):errori.add("Troppo tempo",riga)}break;case"SELECT":riga.next?(codice[riga.next].t1=await intvaluta(amb,mac,riga.contenuto),ii=riga.next-1):errori.add("manca endselect",riga);break;case"CASE":case"CASES":case"DEFAULT":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{let vv,tm=1;const _getvv=async()=>{let vv=await intvaluta(amb,mac,riga.contenuto);return vv=vv.includes(":")&&!vv.includes(",")?vv.split(":").map((e=>(e||"").trim())):getcolonne(vv),vv};if("CASE"==riga.tipo){tm=0,vv=await _getvv();const tmx=muCalc(riga.t1||"");vv.find((v=>muCalc(v)==tmx))&&(tm=1)}else if("CASES"==riga.tipo){tm=0,vv=await _getvv();const tmx=riga.t1||"";vv.find((v=>v==tmx))&&(tm=1)}codice[riga.next].jlast=tm?1:0,codice[riga.next].t1=riga.t1,tm||(ii=riga.next-1)}else errori.add("manca select",riga);break;case"ELSEIF":case"ELSEIFDEF":case"ELSEIFNDEF":case"ELSE":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{const tm="ELSE"==riga.tipo?1:"ELSEIF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"ELSEIFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)}else errori.add("manca endif",riga);break;case"ENDIF":case"ENDSELECT":case"CACHE":case"CVAR":break;case"PUSH":vari.push();break;case"POP":vari.pop();break;case"INC":case"I":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else if(({macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{}),macro){options._inc=!0,options._stackmacro++;const saved={},parametri=macro.parametri?._;if(parametri&&parametri.length)for(const x of parametri){const x1=clean(x.split("=")[0]||"",!0);x1&&(saved[x1]=vari.dictionary[x1])}await macro.impostaparametri(parametri,pars);const rs1=await muEval(amb,macro,macro.codice,options);for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];output.push(...rs1),options._stackmacro--,options._inc=!1}break;case"MACRO":case"M":case"FUNC":case"F":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else{let{macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{};if(macro){const ismacro=!!options.grafica||["F","FUNC"].includes(riga.tipo),optid=options.id||"",parametri=macro.parametri?._,saved={};if(ismacro)vari.push();else{if(macro.head)for(const x of macro.head)saved[x.cod]=amb.vari.var(x.cod);if(parametri&&parametri.length)for(const x of parametri){const x1=(x.split("=")[0]||"").trim().toLowerCase();x1&&(saved[x1]=vari.dictionary[x1])}}if(macro.codice.length){if(options._stackmacro++,options.grafica&&"function"==typeof options.grafica){let f="",xid="";pars&&pars.length?(f=pars.find((e=>e.startsWith("#id"))),f?(f=await vari.valuta(f.slice(3)),options.id=hash(`${ii}${macro.name}${optid}${f}`),pars=pars.filter((e=>!e.startsWith("#id"))),xid=options.id):options.id=hash(`z${optid}${ii}`)):options.id=hash(`z${optid}${ii}`);let tm=amb.pick.key;amb.pick.key=options.id;const out=await options.grafica({tipo:riga.tipo,id:xid,pars:pars,parametri:parametri,macro:macro,options:options,vari:amb.vari,amb:amb});amb.pick.key=tm,output.push(out)}else{await macro.impostaparametri(parametri,pars);const rs1=await muEval(amb,macro,macro.codice,options);output.push(...rs1)}options._stackmacro--}if(ismacro)vari.pop();else for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];options.id=optid}else errori.add("Macro non trovata!",riga)}break;case"LET":case"LETS":{let i=riga.contenuto.indexOf("="),j=-1;if(i>=0&&(j=riga.contenuto.indexOf("=",i+1)),j<0){const v=riga.contenuto;if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i).trim());let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}else{const vv=getcolonne(riga.contenuto);for(const v of vv)if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i));let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}}break;case"LETT":{const i=riga.contenuto.indexOf("=");if(i>0){const a=await intvaluta(amb,mac,riga.contenuto.slice(0,i).trim()),b=await intvaluta(amb,mac,riga.contenuto.slice(i+1).trim());vari.add(a,b)}}break;case"LOOK":case"LOOKB":{const cc=getcolonne(await intvaluta(amb,mac,riga.contenuto)),base=muCalc(cc[1]),col=muCalc(cc[3]),ww=await dammivariante(amb,macro,cc[2]);if(ww&&ww.rows){const rr=Object.values(ww.rows).reduce(((t,e)=>{const val=parseInt(e.v[col?col-1:0]);return val&&("LOOKB"==riga.tipo?val<=base&&val>t.v&&(t.v=val,t.c=e.v[0]):val>=base&&val<t.v&&(t.v=val,t.c=e.v[0])),t}),{v:"LOOKB"==riga.tipo?0:1/0,c:""});rr&&rr.c&&(amb.vari.add(cc[0],ww.tovar(rr.c)),options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:cc[0],valore:ww.tovar(rr.c),riga:riga}))}else amb.vari.add(cc[0],`${base},no,no`)}break;case"LETV":case"LETM":case"DEF":{const tm=getcolonne(riga.contenuto);if(tm)for(const x of tm){let{v:v,o:o,fl:fl}=getcouple(x);if(fl){v=await vari.valuta(v),o=await intvaluta(amb,mac,o);const valore=await impostavariante(amb,mac,v.trim().toLowerCase(),o.trim().toLowerCase(),"LETM"==riga.tipo?{t:"m"}:{t:"v"});options._stackmacro<=0&&options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:v,valore:valore,riga:riga})}}}break;case"DO":{const valido=(riga.contenuto||"").trim();let fl=!0;valido&&!muCalc(await intvaluta(amb,mac,valido))&&(fl=!1),riga.next&&(fl||(ii=riga.next+1))}break;case"VARIANTE":case"FORVAR":case"FOR":{let vv,valido,elenco,v;if(options.oldstyle?(vv=riga.contenuto.split(","),v=vv[2]||"i",elenco=vv[0],valido=vv[1]):(vv=getcolonne(riga.contenuto||""),v=vv[0]||"",elenco=clean(vv[1],!0),valido=vv[2]||""),v=v.includes("$")?await intvaluta(amb,mac,v):v||"","FORVAR"==riga.tipo||"VARIANTE"==riga.tipo){const tm=await intvaluta(amb,mac,elenco),xx=tm?await dammivariante(amb,mac,tm):void 0;xx?elenco=xx.tovec():(elenco=[],errori.add("getvariante not found!",riga))}else{const txx=await intvaluta(amb,mac,elenco||"");elenco=elenco?getcolonne(txx):void 0}elenco=elenco||[];const nc=0;if(riga.next){codice[riga.next].for={v:v,elenco:elenco,nc:nc,valido:valido};let voce,fl=!0;v&&elenco.length>0?nc>=elenco.length?fl=!1:(voce=elenco[nc],vari.add(v,voce),valido&&(fl=!muCalc(await intvaluta(amb,mac,valido)))):fl=!1,fl||(ii=riga.next-1)}else errori.add("manca endfor/loop",riga)}break;case"LOOP":{let fl=!0;riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))&&(fl=!1),fl&&(ii=riga.prev-1);break}case"ENDFOR":if(!riga.contenuto||muCalc(await intvaluta(amb,mac,riga.contenuto)))if(riga.for){const{v:v,elenco:elenco,valido:valido}=riga.for;if(v&&elenco.length>0&&riga.for.nc<500)for(;;){if(riga.for.nc++,riga.for.nc<elenco.length){if(vari.add(v,elenco[riga.for.nc]),valido&&muCalc(await intvaluta(amb,mac,valido)))continue;ii=riga.prev;break}break}}else errori.add("manca istruzione for",riga);break;case"BREAK":case"EXIT":case"EXITFOR":riga.next?riga.contenuto.trim()?muCalc(await intvaluta(amb,mac,riga.contenuto))&&(ii=riga.next):ii=riga.next:errori.add("break outside loop",riga);break;case"CONTINUE":riga.next?riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))||(ii=riga.next-1):errori.add("continue outside loop",riga);break;case"MSG":case"LOG":{const tm99=await intvaluta(amb,mac,riga.contenuto);logga(tm99),errori.add(tm99)}break;default:{let tm;if(riga.contenuto.startsWith("!")){tm=await intvaluta(amb,mac,riga.contenuto);let a="";const rr=/^!(.\w+)[\s;,]\s*(.+)?$/gim.exec(tm);if(rr)if(rr[1].startsWith("."))await getcbfunc(tm,tm.slice(1),[],vari,amb),a="";else{const cmd=rr[1].toLowerCase(),pars=getcolonne(rr[2]||"");a=await getcbfunc(tm,cmd,pars,vari,amb)}a&&outpush(output,a)}else options.parsefnpunto&&"function"==typeof options.parsefnpunto&&riga.contenuto.startsWith(".")?await options.parsefnpunto({dati:riga.contenuto,output:output,id:options.id,vari:amb.vari,amb:amb}):(tm=await intvaluta(amb,mac,riga.contenuto),outpush(output,tm))}}ii++}return output}async function muGenerate(macro,amb,genera,callback,isTestmode=0){if(macro.isgenera&&callback){const output={counter:0,keys:{},isTestmode:isTestmode};if(genera){if(!macro.genera[genera])return!1;await muGenerate_0(macro,amb,genera,callback,output)}else for(const gg in macro.genera)await muGenerate_0(macro,amb,gg,callback,output);return!0}}async function muGenerate_0(mac,amb,genera,callback,output){const xgen=mac.genera[genera];if(xgen){output.counter2=0;const working_variant={};async function processavariante(liv){if(output.isTestmode&&output.counter>output.isTestmode)return;if(liv<xgen.vars.length){const xx=xgen.vars[liv];if(!working_variant[xx]){const xvar=await dammivariante(amb,mac,xx),keys=Object.keys(xvar.rows);if(keys&&keys.length>0){for(const k of keys)amb.vari.add(xvar.name,xvar.tovar(k)),working_variant[xx]=!0,await processavariante(liv+1),working_variant[xx]=!1;return}logga("manca la variante",xx)}}for(const x of xgen.calcola)mac.formula[x]&&await muEval(amb,mac,mac.formula[x],{limited:!0});for(const x of xgen.exclude)if(mac.formula[x]){const vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});if(vvv)for(const v of vvv){if(muCalc(v))return}}const out1=await muEval(amb,mac,xgen.codice,{limited:!0,localvar:mac.localvar}),bb={};for(const x of xgen.bom)if(mac.formula[x]){let vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});vvv=vvv.join("\n").split("\n");for(const v of vvv)if(v){const tm=getcolonne(v);bb[x]||(bb[x]=[]);const t={};for(let i=0;i<tm.length;i++)t[`c${i}`]=tm[i];bb[x].push(t)}}await async function docallback(callback,out1,bom,xgen,genera,output){let fl=!0;for(const x of out1){const tm=getcolonne(x);if(tm[0]&&!output[tm[0]]){output[tm[0]]=1,output.counter++,output.counter2++;const o={__id:output.counter};for(let i=0;i<tm.length;i++){let key=xgen.head[i]?xgen.head[i]:`c${i}`;"#"==key[0]?(key=key.substr(1),o[key]=muCalc(tm[i])):o[key]=tm[i]}await callback(genera,o,fl?bom:void 0,output.counter,output.counter2),fl=!1}}}(callback,out1,bb,xgen,genera,output)}await processavariante(0)}}const DIMS=["l","a","p"],rx1=/^\{(:?(var|valid|formula|genera|header|v|f|g|h))[\s|}]/im,tipifree=["s","g","h","p","q"],tipiheader=[{cod:"t",des:"Variante"},{cod:"q",des:"V.Query"},{cod:"f",des:"Valore Fisso"},{cod:"g",des:"Gruppo"},{cod:"s",des:"Libero"},{cod:"m",des:"Misura"},{cod:"c",des:"Check (no/si)"},{cod:"z",des:"Check (si/no)"},{cod:"h",des:"Hidden"},{cod:"d",des:"Splitter"},{cod:"p",des:"Programmato"}],tipicolonna=[{cod:"",des:"Libero"},{cod:"a",des:"Area"},{cod:"t",des:"Thumb",folder:"thumbs"},{cod:"i",des:"Image",folder:"textures"},{cod:"x",des:"3D file",folder:"3d"},{cod:"f",des:"Funzione",folder:"script"}];function valutaCondizioniTestata(vari,str){const vv=str.split("\n");for(const v of vv)if(v.trim()){if(muCalc(vari.valutasync(v)))return!0}return!1}class Macro{constructor(amb,_name){const{name:name,cat:cat}=checkmu(_name,amb.cat||"");this.name=name,this.cat=cat,
254
+ /** @type {Variante} */if(head&&head.alias&&(ky=head.alias),macro&&macro.paralias&&macro.paralias[a]&&(ky=macro.paralias[a]),tm=await dammivariante(amb,macro,ky),tm)if(head&&head.t){head.des||(head.des=tm.des);let x8=head?.filtra||"";if(x8.includes("$")&&(x8=await amb.vari.valuta(x8)),"m"===head.t){let col=2;if(b.includes(":")){const xx=b.split(":");col=parseInt(xx[1]),b=xx[0]}tm.limita(x8),b=tm.fromdim(parseFloat(b),col)}else{tm.limita(x8);const b1=tm.firstvalid(b,getcolonne(head.def));b=tm.tovar(b1)}}else tm.resetfilter(),b=tm.firstvalid(b),b=tm.tovar(b);else head&&head.t&&head.t;return amb.vari.add(a,b),b}async function pushpars(amb,macro,parsfunzione,parsinit){const fatti={},vals=[];if(parsfunzione)for(const x of parsfunzione){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}if(parsinit)for(const x of parsinit){const{v:v,o:o,fl:fl}=getcouple(x);fatti[v]||(fatti[v]=!0,vals.push({v:v,o:amb.vari.var[v]}),fl&&await impostavariante(amb,macro,v,o))}return vals}function poppars(amb,tm){if(tm)for(const x of tm)amb.vari.add(x.v,x.o)}const outpush=(output,a)=>{null!=a&&null!=a&&("object"==typeof a?output.push(JSON.stringify(a,null,2)):"string"==typeof a&&a.startsWith("_ ")&&output.length>0&&"string"==typeof output[output.length-1]?output[output.length-1]+=a.slice(2):output.push(...a.split("\n")))};async function muEval(amb,mac,codice,options){if(!Array.isArray(codice))return errori.add("codice is not a valid parsed array"),[];options||(options={}),options.id||(options.id="_"),options._stackmacro||(options._stackmacro=0),options.limited||(options.limited=!1),amb||errori.add("amb deve essere definito");const vari=amb.vari;amb.maxdelays,amb.cat;const output=[];let macro,pars,xid;tk();for(let ii=0;ii<codice.length;){let riga=codice[ii];switch(riga.tipo){case"IFDEF":case"IFNDEF":case"IF":{const tm="IF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"IFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);riga.next?(codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)):errori.add("Troppo tempo",riga)}break;case"SELECT":riga.next?(codice[riga.next].t1=await intvaluta(amb,mac,riga.contenuto),ii=riga.next-1):errori.add("manca endselect",riga);break;case"CASE":case"CASES":case"DEFAULT":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{let vv,tm=1;const _getvv=async()=>{let vv=await intvaluta(amb,mac,riga.contenuto);return vv=vv.includes(":")&&!vv.includes(",")?vv.split(":").map((e=>(e||"").trim())):getcolonne(vv),vv};if("CASE"==riga.tipo){tm=0,vv=await _getvv();const tmx=muCalc(riga.t1||"");vv.find((v=>muCalc(v)==tmx))&&(tm=1)}else if("CASES"==riga.tipo){tm=0,vv=await _getvv();const tmx=riga.t1||"";vv.find((v=>v==tmx))&&(tm=1)}codice[riga.next].jlast=tm?1:0,codice[riga.next].t1=riga.t1,tm||(ii=riga.next-1)}else errori.add("manca select",riga);break;case"ELSEIF":case"ELSEIFDEF":case"ELSEIFNDEF":case"ELSE":if(riga.next)if(riga.jlast)riga.jlast=0,ii=riga.last-1;else{const tm="ELSE"==riga.tipo?1:"ELSEIF"==riga.tipo?muCalc(await intvaluta(amb,mac,riga.contenuto)):"ELSEIFDEF"==riga.tipo?""!=await intvaluta(amb,mac,riga.contenuto):""==await intvaluta(amb,mac,riga.contenuto);codice[riga.next].jlast=tm?1:0,tm||(ii=riga.next-1)}else errori.add("manca endif",riga);break;case"ENDIF":case"ENDSELECT":case"CACHE":case"CVAR":break;case"PUSH":vari.push();break;case"POP":vari.pop();break;case"INC":case"I":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else if(({macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{}),macro){options._inc=!0,options._stackmacro++;const saved={},parametri=macro.parametri?._;if(parametri&&parametri.length)for(const x of parametri){const x1=clean(x.split("=")[0]||"",!0);x1&&(saved[x1]=vari.dictionary[x1])}await macro.impostaparametri(parametri,pars);const rs1=await muEval(amb,macro,macro.codice,options);for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];output.push(...rs1),options._stackmacro--,options._inc=!1}break;case"MACRO":case"M":case"FUNC":case"F":if(options._stackmacro>500)errori.add("stack chiamate macro troppo profondo!",riga);else{let{macro:macro,pars:pars,xid:xid}=await amb.getmacro(riga)||{};if(macro){const ismacro=!!options.grafica||["F","FUNC"].includes(riga.tipo),optid=options.id||"",parametri=macro.parametri?._,saved={};if(ismacro)vari.push();else{if(macro.head)for(const x of macro.head)saved[x.cod]=amb.vari.var(x.cod);if(parametri&&parametri.length)for(const x of parametri){const x1=(x.split("=")[0]||"").trim().toLowerCase();x1&&(saved[x1]=vari.dictionary[x1])}}if(macro.codice.length){if(options._stackmacro++,options.grafica&&"function"==typeof options.grafica){let f="",xid="";pars&&pars.length?(f=pars.find((e=>e.startsWith("#id"))),f?(f=await vari.valuta(f.slice(4)),f.startsWith("#")?options.id=f:options.id=hash(`${ii}${macro.name}${optid}${f}`),pars=pars.filter((e=>!e.startsWith("#id"))),xid=options.id):options.id=hash(`z${optid}${ii}`)):options.id=hash(`z${optid}${ii}`);let tm=amb.pick.key;amb.pick.key=options.id;const out=await options.grafica({tipo:riga.tipo,id:xid,pars:pars,parametri:parametri,macro:macro,options:options,vari:amb.vari,amb:amb});amb.pick.key=tm,output.push(out)}else{await macro.impostaparametri(parametri,pars);let tm=amb.vari.var("_rootnode");amb.vari.add("_rootnode","0");const rs1=await muEval(amb,macro,macro.codice,options);amb.vari.add("_rootnode",tm),output.push(...rs1)}options._stackmacro--}if(ismacro)vari.pop();else for(const v in saved)saved[v]?vari.dictionary[v]=saved[v]:delete vari.dictionary[v];options.id=optid}else errori.add("Macro non trovata!",riga)}break;case"LET":case"LETS":{let i=riga.contenuto.indexOf("="),j=-1;if(i>=0&&(j=riga.contenuto.indexOf("=",i+1)),j<0){const v=riga.contenuto;if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i).trim());let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}else{const vv=getcolonne(riga.contenuto);for(const v of vv)if(i=v.indexOf("="),i>0){const a=await intvaluta(amb,mac,v.slice(0,i));let b=v.slice(i+1).trim();b="LET"==riga.tipo?muCalc(await intvaluta(amb,mac,b))||"":await intvaluta(amb,mac,b),vari.add(a,b)}}}break;case"LETT":{const i=riga.contenuto.indexOf("=");if(i>0){const a=await intvaluta(amb,mac,riga.contenuto.slice(0,i).trim()),b=await intvaluta(amb,mac,riga.contenuto.slice(i+1).trim());vari.add(a,b)}}break;case"LOOK":case"LOOKB":{const cc=getcolonne(await intvaluta(amb,mac,riga.contenuto)),base=muCalc(cc[1]),col=muCalc(cc[3]),ww=await dammivariante(amb,macro,cc[2]);if(ww&&ww.rows){const rr=Object.values(ww.rows).reduce(((t,e)=>{const val=parseInt(e.v[col?col-1:0]);return val&&("LOOKB"==riga.tipo?val<=base&&val>t.v&&(t.v=val,t.c=e.v[0]):val>=base&&val<t.v&&(t.v=val,t.c=e.v[0])),t}),{v:"LOOKB"==riga.tipo?0:1/0,c:""});rr&&rr.c&&(amb.vari.add(cc[0],ww.tovar(rr.c)),options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:cc[0],valore:ww.tovar(rr.c),riga:riga}))}else amb.vari.add(cc[0],`${base},no,no`)}break;case"LETV":case"LETM":case"DEF":{const tm=getcolonne(riga.contenuto);if(tm)for(const x of tm){let{v:v,o:o,fl:fl}=getcouple(x);if(fl){v=await vari.valuta(v),o=await intvaluta(amb,mac,o);const valore=await impostavariante(amb,mac,v.trim().toLowerCase(),o.trim().toLowerCase(),"LETM"==riga.tipo?{t:"m"}:{t:"v"});options._stackmacro<=0&&options.checkheader&&"function"==typeof options.checkheader&&await options.checkheader({variante:v,valore:valore,riga:riga})}}}break;case"DO":{const valido=(riga.contenuto||"").trim();let fl=!0;valido&&!muCalc(await intvaluta(amb,mac,valido))&&(fl=!1),riga.next&&(fl||(ii=riga.next+1))}break;case"VARIANTE":case"FORVAR":case"FOR":{let vv,valido,elenco,v;if(options.oldstyle?(vv=riga.contenuto.split(","),v=vv[2]||"i",elenco=vv[0],valido=vv[1]):(vv=getcolonne(riga.contenuto||""),v=vv[0]||"",elenco=clean(vv[1],!0),valido=vv[2]||""),v=v.includes("$")?await intvaluta(amb,mac,v):v||"","FORVAR"==riga.tipo||"VARIANTE"==riga.tipo){const tm=await intvaluta(amb,mac,elenco),xx=tm?await dammivariante(amb,mac,tm):void 0;xx?elenco=xx.tovec():(elenco=[],errori.add("getvariante not found!",riga))}else{const txx=await intvaluta(amb,mac,elenco||"");elenco=elenco?getcolonne(txx):void 0}elenco=elenco||[];const nc=0;if(riga.next){codice[riga.next].for={v:v,elenco:elenco,nc:nc,valido:valido};let voce,fl=!0;v&&elenco.length>0?nc>=elenco.length?fl=!1:(voce=elenco[nc],vari.add(v,voce),valido&&(fl=!muCalc(await intvaluta(amb,mac,valido)))):fl=!1,fl||(ii=riga.next-1)}else errori.add("manca endfor/loop",riga)}break;case"LOOP":{let fl=!0;riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))&&(fl=!1),fl&&(ii=riga.prev-1);break}case"ENDFOR":if(!riga.contenuto||muCalc(await intvaluta(amb,mac,riga.contenuto)))if(riga.for){const{v:v,elenco:elenco,valido:valido}=riga.for;if(v&&elenco.length>0&&riga.for.nc<500)for(;;){if(riga.for.nc++,riga.for.nc<elenco.length){if(vari.add(v,elenco[riga.for.nc]),valido&&muCalc(await intvaluta(amb,mac,valido)))continue;ii=riga.prev;break}break}}else errori.add("manca istruzione for",riga);break;case"BREAK":case"EXIT":case"EXITFOR":riga.next?riga.contenuto.trim()?muCalc(await intvaluta(amb,mac,riga.contenuto))&&(ii=riga.next):ii=riga.next:errori.add("break outside loop",riga);break;case"CONTINUE":riga.next?riga.contenuto&&!muCalc(await intvaluta(amb,mac,riga.contenuto))||(ii=riga.next-1):errori.add("continue outside loop",riga);break;case"MSG":case"LOG":{const tm99=await intvaluta(amb,mac,riga.contenuto);logga(tm99),errori.add(tm99)}break;default:{let tm;if(riga.contenuto.startsWith("!")){tm=await intvaluta(amb,mac,riga.contenuto);let a="";const rr=/^!(.\w+)[\s;,]\s*(.+)?$/gim.exec(tm);if(rr)if(rr[1].startsWith("."))await getcbfunc(tm,tm.slice(1),[],vari,amb),a="";else{const cmd=rr[1].toLowerCase(),pars=getcolonne(rr[2]||"");a=await getcbfunc(tm,cmd,pars,vari,amb)}a&&outpush(output,a)}else options.parsefnpunto&&"function"==typeof options.parsefnpunto&&riga.contenuto.startsWith(".")?await options.parsefnpunto({dati:riga.contenuto,output:output,id:options.id,vari:amb.vari,amb:amb}):(tm=await intvaluta(amb,mac,riga.contenuto),outpush(output,tm))}}ii++}return output}async function muGenerate(macro,amb,genera,callback,isTestmode=0){if(macro.isgenera&&callback){const output={counter:0,keys:{},isTestmode:isTestmode};if(genera){if(!macro.genera[genera])return!1;await muGenerate_0(macro,amb,genera,callback,output)}else for(const gg in macro.genera)await muGenerate_0(macro,amb,gg,callback,output);return!0}}async function muGenerate_0(mac,amb,genera,callback,output){const xgen=mac.genera[genera];if(xgen){output.counter2=0;const working_variant={};async function processavariante(liv){if(output.isTestmode&&output.counter>output.isTestmode)return;if(liv<xgen.vars.length){const xx=xgen.vars[liv];if(!working_variant[xx]){const xvar=await dammivariante(amb,mac,xx),keys=Object.keys(xvar.rows);if(keys&&keys.length>0){for(const k of keys)amb.vari.add(xvar.name,xvar.tovar(k)),working_variant[xx]=!0,await processavariante(liv+1),working_variant[xx]=!1;return}logga("manca la variante",xx)}}for(const x of xgen.calcola)mac.formula[x]&&await muEval(amb,mac,mac.formula[x],{limited:!0});for(const x of xgen.exclude)if(mac.formula[x]){const vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});if(vvv)for(const v of vvv){if(muCalc(v))return}}const out1=await muEval(amb,mac,xgen.codice,{limited:!0,localvar:mac.localvar}),bb={};for(const x of xgen.bom)if(mac.formula[x]){let vvv=await muEval(amb,mac,mac.formula[x],{limited:!0});vvv=vvv.join("\n").split("\n");for(const v of vvv)if(v){const tm=getcolonne(v);bb[x]||(bb[x]=[]);const t={};for(let i=0;i<tm.length;i++)t[`c${i}`]=tm[i];bb[x].push(t)}}await async function docallback(callback,out1,bom,xgen,genera,output){let fl=!0;for(const x of out1){const tm=getcolonne(x);if(tm[0]&&!output[tm[0]]){output[tm[0]]=1,output.counter++,output.counter2++;const o={__id:output.counter};for(let i=0;i<tm.length;i++){let key=xgen.head[i]?xgen.head[i]:`c${i}`;"#"==key[0]?(key=key.substr(1),o[key]=muCalc(tm[i])):o[key]=tm[i]}await callback(genera,o,fl?bom:void 0,output.counter,output.counter2),fl=!1}}}(callback,out1,bb,xgen,genera,output)}await processavariante(0)}}const DIMS=["l","a","p"],rx1=/^\{(:?(var|valid|formula|genera|header|v|f|g|h))[\s|}]/im,tipifree=["s","g","h","p","q"],tipiheader=[{cod:"t",des:"Variante"},{cod:"q",des:"V.Query"},{cod:"f",des:"Valore Fisso"},{cod:"g",des:"Gruppo"},{cod:"s",des:"Libero"},{cod:"m",des:"Misura"},{cod:"c",des:"Check (no/si)"},{cod:"z",des:"Check (si/no)"},{cod:"h",des:"Hidden"},{cod:"p",des:"Programmato"}],tipicolonna=[{cod:"",des:"Libero"},{cod:"a",des:"Area"},{cod:"t",des:"Thumb",folder:"thumbs"},{cod:"i",des:"Image",folder:"textures"},{cod:"x",des:"3D file",folder:"3d"},{cod:"f",des:"Funzione",folder:"script"}];function valutaCondizioniTestata(vari,str){const vv=str.split("\n");for(const v of vv)if(v.trim()){if(muCalc(vari.valutasync(v)))return!0}return!1}class Macro{constructor(amb,_name){const{name:name,cat:cat}=checkmu(_name,amb.cat||"");this.name=name,this.cat=cat,
255
255
  /** @type {Ambiente} */
256
- this.amb=amb,this.azzera()}azzera(){this.key=`${this.cat}/${this.name}`,this.localvar={},this.head=[],this.frontend=!1,this.valid=[],this.parametri={},this.paralias={},this.formula={},this.settings={},this.errori=[],this.codice=[],this.genera={}}get isgenera(){return Object.keys(this.genera).length||0}get iscodice(){return this.codice.length||0}get isheader(){return this.head?.length||0}geterrori(){const cl=[];return this.errori.forEach((e=>cl.push({e:e}))),cl}getparametri(){const s={};if(this.dims&&DIMS.forEach((k=>{const t=muCalc(this.amb.vari.var(k));t&&(s[k]=String(t))})),this.head){for(const x of this.head)if(!x._h){let tm=this.amb.vari.var(x.cod);tipifree.includes(x.t)||"string"==typeof tm&&(tm=tm.split(",")[0]),s[x.cod]=tm}}else if(this.parametri?._)for(const x of this.parametri._){const x1=(x.split("=")[0]||"").trim().toLowerCase();let tm=this.amb.vari.var[x1];tm=(tm||"").split(",")[0],s[x1]=tm}return s}async setparametri(pars){const ff={},ruleset=this.amb.ruleset||{};pars||(pars={}),this.dims&&DIMS.forEach((e=>{let t=pars[e]||this.dims[e].val;t=parseFloat(t)||0,this.dims[e].visible&&(t<this.dims[e].min&&(t=this.dims[e].min),t>this.dims[e].max&&(t=this.dims[e].max)),pars[e]=String(t)}));for(const x of this.head){const tm=ruleset[x.cod];tm&&(tm.islock?(x.visible="0",pars[x.cod]=tm.opz,x._islock=!0):pars[x.cod]||(pars[x.cod]=tm.opz)),"g"!=x.t&&("z"!=x.t||pars[x.cod]||(pars[x.cod]="1"),x._v=pars[x.cod]||"",ff[x.cod]=!0)}for(const x in pars)ff[x]||(ff[x]=!0,await impostavariante(this.amb,this,x,pars[x]));return this.head?.length>0&&await this.setparametro(this.head[0].cod,pars[this.head[0].cod]||void 0,!0),this.getparametri()}async setparametro(name,value,propaga=!1){if(value&&"string"==typeof value&&value.includes("$")&&(value=await intvaluta(this.amb,this,value)),this.head){const _imposta=async(riga,vv,id)=>{const nn=riga?.cod;if(riga.valid&&!riga._h1){const t0=!valutaCondizioniTestata(this.amb.vari,riga.valid);if(riga._h!=t0&&(riga._h=t0,["g","g1","g2"].includes(riga.t)))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;tm1._h1=riga._h}}}if(riga._h||riga._h1)return this.amb.vari.add(nn,""),riga._v=void 0,"";{if(delete riga._h2,riga.visible){const t0=!valutaCondizioniTestata(this.amb.vari,riga.visible);if(t0&&(riga._h2=t0),["g","g1","g2"].includes(riga.t))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;riga._h2?tm1._h3=riga._h2:delete tm1._h3}}}let tx=this.amb.vari.var(nn)||"";if("string"==typeof tx&&(tx=tx.split(",")[0]),"z"!=riga.t||tx||(this.amb.vari.add(nn,"1"),tx="1"),"m"==riga.t&&riga.spars){const vspars=getcolonne(riga.spars);tx=parseFloat(tx||vspars[0])||0,vspars[1]&&parseFloat(tx)<vspars[1]&&(tx=parseFloat(vspars[1])||0),vspars[2]&&parseFloat(tx)>vspars[2]&&(tx=parseFloat(vspars[2])||0),tx=String(tx),this.amb.vari.add(nn,tx)}const tmimposta=await impostavariante(this.amb,this,nn,vv||riga._v||tx,riga);return riga._v=void 0,tx=this.amb.vari.var(nn)||"",this.amb&&this.amb.deriva&&this.amb.deriva.length>0&&this.amb.deriva.filter((e=>e.cod==nn&&((!e.item||e.item==this.amb.item)&&((!e.model||e.model==this.amb.model)&&((!e.rule||e.rule==this.amb.rule)&&(!e.opz||e.opz==vv)))))),tmimposta}};let tm,i0=-1;if("#dim"==name)propaga=1;else{if(i0=this.head.findIndex((e=>e.cod===name)),i0<0)return;const hh=this.head[i0];tm=await _imposta(hh,value,i0),delete hh._d}if(propaga)for(let i=i0+1;i<this.head.length;i++)await _imposta(this.head[i],void 0,i);return tm}return await impostavariante(this.amb,this,name,value)}async impostaparametri(parimposta,parcall,ismacro=!1){if(this.head){this.paralias||(this.paralias={}),Array.isArray(this.head)||(this.head=[]);for(const i of this.head)i._v="",delete i._h,delete i._h1,delete i._h2,i.alias&&(this.paralias[i.cod]=i.alias)}parimposta||(parimposta=[]),parcall||(parcall=[]);for(const x of[...parimposta,...parcall]){const i=x.indexOf("=");if(i>0){let a=clean(x.substr(0,i));a.includes("$")&&(a=await intvaluta(this.amb,this,a));let t,b=x.substr(i+1);b.includes("$")&&(b=await intvaluta(this.amb,this,b)),this.head&&(t=this.head.find((e=>e.cod==a)))?t._v=b:await impostavariante(this.amb,this,a,b)}}if(this.head){let fl=!0;for(const h of this.head){let fl2=await this.checkvalid(h.valid);ismacro&&(fl2=!0),["g","g1","g2"].includes(h.t)?fl=fl2:fl&&fl2&&await this.setparametro(h.cod,h._v)}}}async checkvalid(formula){if(!formula)return!0;return!!muCalc(await intvaluta(this.amb,this,formula))}getmacrostr(){return JSON.stringify(this.getmacro())}getmacro(){return getOggetto(this,["amb"])}setmacro(vv){if(setOggetto(this,fromjson(vv,{})),this.localvar)for(const x in this.localvar){const vv=new Variante;setOggetto(vv,this.localvar[x]),this.localvar[x]=vv}}async load(xname,xcat){let name,cat;try{let tm;if(({name:name,cat:cat}=checkmu(xname||this.name,xcat||this.cat||"")),this.name||(this.name=name),this.cat||(this.cat=cat),this.azzera(),cbGetMacro&&(tm=await cbGetMacro(cat,name),"string"==typeof tm&&(tm.startsWith("{")||tm.startsWith("["))&&(tm=fromjson(tm)),tm&&tm.head&&!Array.isArray(tm.head)&&(tm.head=[]),tm.head&&(tm.dims=getheaddims(tm.dims))),tm){if("string"==typeof tm)await this.parsedata(tm);else for(const x in tm)this[x]=tm[x];return!0}errori.add(`missing cbGetFile: ${cat}/${name}`)}catch(error){errori.add(geterrdes(error),`macro.load: ${name}/${cat}`)}}async loadAndCompile(file,_cat,acapo=!1){let res;const{name:name,cat:cat}=checkmu(file,this.cat||_cat);return this.azzera(),cbGetFile&&(res=await cbGetFile(cat,name)),res?(await this.parsedata(res,acapo),this.getmacro()):void errori.add(`missing cbGetFile: ${name}/${cat}`)}async#loadinclude(file,flin,stak,pp){let res;const{name:name,cat:cat}=checkmu(file,this.cat);if(cbGetFile&&(res=await cbGetFile(cat,name)),!res)return[];if(res.includes("$1")&&pp&&pp.length>0)for(let i=1;i<pp.length;i++)res=res.replaceAll(`$${i}`,pp[i]);let tm=muClComments(res);const t2=[];flin&&(tm=tm.filter((t=>!/^\{(:?(var|valid|formula|header|genera|v|f|h))[\s|}]/im.test(t))));for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]);if(!stak.includes(pp[0])){stak.push(pp[0]);const t3=await this.loadinclude(pp[0],flin,stak,pp);Array.isArray(t3)&&t2.push(...t3),stak.pop()}}else t2.push(t)}}return t2}async parsedata(res,acapo=!1){if(this.azzera(),!res)return;const t2=[];let tm=muClComments(res),flin=!1;const lochead=[];for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]),t3=await this.#loadinclude(pp[0],flin,[pp[0]],pp);Array.isArray(t3)&&t2.push(...t3)}else t2.push(t)}}flin=!1;let out=this.codice;for(const t of t2){const rr=rx1.exec(t);if(rr)if(rr[1].startsWith(":"))out=this.codice;else switch(rr[1]){case"genera":case"g":{let r2=/^\s*\{(genera|g)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(getcolonne(r2[2])[0]);this.genera[name]=[],out=this.genera[name]}else out=this.errori,out.push(t)}break;case"valid":out=this.valid;break;case"var":case"v":{const r2=/^\s*\{(var|v)\s+(.+)?\}/im.exec(t);if(r2){const nn=getcolonne(r2[2]),name=checkname(nn[0]);this.localvar[name]={name:name,des:nn[1]||"",rows:[]},out=this.localvar[name].rows}else out=this.errori,out.push(t)}break;case"formula":case"f":{const r2=/^\s*\{(formula|f)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(r2[2]);this.formula[name]=[],out=this.formula[name]}else out=this.errori,out.push(t)}break;case"h":case"header":out=lochead;break;default:this.errori.push(t),out=this.errori}else t.startsWith("{")&&(out=this.codice),out.push(t)}this.parametri={},this.codice=this.cleanfiltraparametri("_",this.codice,acapo);for(const f in this.formula)this.formula[f]=this.cleanfiltraparametri(f,this.formula[f],acapo);for(const f in this.localvar){const vv=new Variante,v=this.localvar[f];vv.setheader(f,this.cat),vv.rows={};for(const x of v.rows){const c=getcolonne(x),k=c[0].trim().toLowerCase();vv.rows[k]={annulla:0,v:c}}v.des&&(vv.des=v.des),this.localvar[f]=vv}tm=this.valid,this.valid=[];for(const t of tm){let p=getcouple(t,",");p={v:p.v,msg:p.o},p.v&&(p.v.startsWith("#")?this.formula[p.v.substring(1)]&&this.valid.push(p):this.valid.push(p))}tm=lochead;const head=[];for(const t of tm){const rr=/^\s*([\w\-_]+)+[;,\s]\s*(.*)?$/im.exec(t);if(rr){const pp=getcolonne(rr[2]),c=clean(rr[1]);let ht;if(c){ht=head.find((e=>e.cod==c)),ht||(ht={cod:c,t:"t"},head.push(ht));for(const tp of pp){const p=getcouple(tp);switch(p.v){case"t":ht.t=p.o;break;case"def":case"default":ht.def=p.o;break;case"valid":case"colonna":case"hidden":p.o.startsWith("#")?this.formula[p.o.substring(1)]&&(ht[p.v]=p.o):ht[p.v]=p.o;break;default:ht[p.v]=p.o}}}}}this.head=head,tm=this.genera;const genera={};for(const kk in tm)if(Array.isArray(tm[kk])){const gen={codice:[],head:"",calcola:[],bom:[],vars:[],exclude:[]},regx=/^\s*[!:]\s*(\w+)\s*(.*)$/i;for(const k2 of tm[kk]){const rr=regx.exec(clean(k2));if(rr)switch(rr[1]){case"calcola":case"c":gen.calcola=[...gen.calcola,...getcolonne(rr[2])];break;case"exclude":case"e":case"escludi":gen.exclude=[...gen.exclude,...getcolonne(rr[2])];break;case"bom":case"db":gen.bom=[...gen.bom,...getcolonne(rr[2])];break;case"vars":case"v":gen.vars=[...gen.vars,...getcolonne(rr[2])];break;case"head":case"h":gen.head=getcolonne(rr[2]);break;default:this.errori.push(`genera ${kk} => ${k2}`)}else gen.codice.push(k2)}gen.codice=muClean(gen.codice,!0),genera[kk]=gen}this.genera=genera}cleanfiltraparametri(key,codice,acapo){if(this.paralias||(this.paralias={}),codice&&codice.length){let fl=!1;const getparalias=dati=>{const cl=[],co=getcolonne(dati);for(const c of co)if(c.includes(":")){const v=c.split(":");this.paralias[v[0]]=v[1],cl.push(v[0])}else cl.push(c);return cl};for(let i=0;i<codice.length;i++){const rr=/^:p[;,\s]+(.*)?$/im.exec(codice[i]);if(rr)codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[1]);else{const rr=/^!(parametri|pars|p)[;,\s]+(.*)?$/im.exec(codice[i]);rr&&(codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[2]))}}fl&&(codice=codice.filter((e=>null!=e)))}return codice=muClean(codice,acapo)}}function parsevariabili(text){let fl=!1;const tk=[];for(;;){const m=/\$([{[(])/m.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}{fl=!0;const classe="["==m[1]?"inline":"variabile";m.index>0&&tk.push({class:"",text:text.substring(0,m.index)});const{i:i}=parsevar(text,m.index+2,m[1],null);if(!(i>m.index)){tk.push({class:classe,text:text.substring(m.index)});break}tk.push({class:classe,text:text.substring(m.index,i+1)}),text=text.substring(i+1)}}return{fl:fl,tk:tk}}function parseexp(text,exp,callback){if(!callback)throw new Error("missing callback");let fl=!1;const tk=[];for(;;){const m=exp.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}m.index>0&&tk.push({class:"",text:text.substring(0,m.index)}),tk.push(...callback(m)),fl=!0,text=text.substring(m.index+m[0].length)}return{fl:fl,tk:tk}}
256
+ this.amb=amb,this.azzera()}azzera(){this.key=`${this.cat}/${this.name}`,this.localvar={},this.head=[],this.frontend=!1,this.valid=[],this.parametri={},this.paralias={},this.formula={},this.settings={},this.errori=[],this.codice=[],this.genera={}}get isgenera(){return Object.keys(this.genera).length||0}get iscodice(){return this.codice.length||0}get isheader(){return this.head?.length||0}geterrori(){const cl=[];return this.errori.forEach((e=>cl.push({e:e}))),cl}getparametri(){const s={};if(this.dims&&DIMS.forEach((k=>{const t=muCalc(this.amb.vari.var(k));t&&(s[k]=String(t))})),this.head){for(const x of this.head)if(!x._h){let tm=this.amb.vari.var(x.cod);tipifree.includes(x.t)||"string"==typeof tm&&(tm=tm.split(",")[0]),s[x.cod]=tm}}else if(this.parametri?._)for(const x of this.parametri._){const x1=(x.split("=")[0]||"").trim().toLowerCase();let tm=this.amb.vari.var[x1];tm=(tm||"").split(",")[0],s[x1]=tm}return s}async setparametri(pars){const ff={},ruleset=this.amb.ruleset||{};pars||(pars={}),this.dims&&DIMS.forEach((e=>{let t=pars[e]||this.dims[e].val;t=parseFloat(t)||0,this.dims[e].visible&&(t<this.dims[e].min&&(t=this.dims[e].min),t>this.dims[e].max&&(t=this.dims[e].max)),pars[e]=String(t)}));for(const x of this.head){const tm=ruleset[x.cod];tm&&(tm.islock?(x.visible="0",pars[x.cod]=tm.opz,x._islock=!0):pars[x.cod]||(pars[x.cod]=tm.opz)),"g"!=x.t&&("z"!=x.t||pars[x.cod]||(pars[x.cod]="1"),x._v=pars[x.cod]||"",ff[x.cod]=!0)}for(const x in pars)ff[x]||(ff[x]=!0,await impostavariante(this.amb,this,x,pars[x]));return this.head?.length>0&&await this.setparametro(this.head[0].cod,pars[this.head[0].cod]||void 0,!0),this.getparametri()}async setparametro(name,value,propaga=!1){if(value&&"string"==typeof value&&value.includes("$")&&(value=await intvaluta(this.amb,this,value)),this.head){const _imposta=async(riga,vv,id,propaga)=>{const nn=riga?.cod;if(riga.valid&&!riga._h1){const t0=!valutaCondizioniTestata(this.amb.vari,riga.valid);if(riga._h!=t0&&(riga._h=t0,["g","g1","g2"].includes(riga.t)))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;tm1._h1=riga._h}}}if(riga._h||riga._h1)return this.amb.vari.add(nn,""),riga._v=void 0,"";{if(delete riga._h2,riga.visible){const t0=!valutaCondizioniTestata(this.amb.vari,riga.visible);if(t0&&(riga._h2=t0),["g","g1","g2"].includes(riga.t))for(let i=id+1;i<this.head.length;i++){const tm1=this.head[i];if(tm1){if(["g","g1","g2"].includes(tm1.t))break;riga._h2?tm1._h3=riga._h2:delete tm1._h3}}}let tx=this.amb.vari.var(nn)||"";"thlm".includes(riga.t)&&(tx=tx.split(",")[0]);let txold=tx;if("z"!=riga.t||tx||(this.amb.vari.add(nn,"1"),tx="1"),"m"==riga.t&&riga.spars){const vspars=getcolonne(riga.spars);tx=parseFloat(tx||vspars[0])||0,vspars[1]&&parseFloat(tx)<vspars[1]&&(tx=parseFloat(vspars[1])||0),vspars[2]&&parseFloat(tx)>vspars[2]&&(tx=parseFloat(vspars[2])||0),tx=String(tx),this.amb.vari.add(nn,tx)}const tmimposta=await impostavariante(this.amb,this,nn,vv||riga._v||tx,riga);if(riga._v=void 0,tx=this.amb.vari.var(nn)||"","thl".includes(riga.t)&&(tx=tx.split(",")[0],this.amb&&this.amb.deriva&&this.amb.deriva.length>0)){const t2=this.amb.deriva.filter((e=>e.cod==nn&&((!e.item||e.item==this.amb.item)&&((!e.model||e.model==this.amb.model)&&((!e.rule||e.rule==this.amb.rule)&&(!e.opz||e.opz==tx))))));t2.length&&t2.forEach((e=>{let t=this.head.find((h=>h.cod==e.tocod));if(t){let t1=this.amb.vari.var(t.cod);"string"==typeof t1&&(t1=t1.split(",")[0],t1&&t1!=txold||(t._v=e.toopz||tx,t._d=1))}}))}return tmimposta}};let tm,i0=-1;if("#dim"==name)propaga=1;else{if(i0=this.head.findIndex((e=>e.cod===name)),i0<0)return;const hh=this.head[i0];tm=await _imposta(hh,value,i0),propaga&&delete hh._d}if(propaga)for(let i=i0+1;i<this.head.length;i++)await _imposta(this.head[i],void 0,i);return tm}return await impostavariante(this.amb,this,name,value)}async impostaparametri(parimposta,parcall,ismacro=!1,progettokeys){if(this.head){this.paralias||(this.paralias={}),Array.isArray(this.head)||(this.head=[]);for(const i of this.head)i._v="",delete i._h,delete i._h1,delete i._h2,i.alias&&(this.paralias[i.cod]=i.alias)}progettokeys||(progettokeys={}),parimposta||(parimposta=[]),parcall||(parcall=[]);for(const x of[...parimposta,...parcall]){const i=x.indexOf("=");if(i>0){let a=clean(x.substr(0,i));a.includes("$")&&(a=await intvaluta(this.amb,this,a));let t,b=x.substr(i+1);b.includes("$")&&(b=await intvaluta(this.amb,this,b)),this.head&&(t=this.head.find((e=>e.cod==a)))?t._v=b:await impostavariante(this.amb,this,a,b)}}if(this.head){let fl=!0;for(const h of this.head){let fl2=await this.checkvalid(h.valid);ismacro&&(fl2=!0),["g","g1","g2"].includes(h.t)?fl=fl2:fl&&fl2&&await this.setparametro(h.cod,progettokeys[h.cod]||h._v)}}}async checkvalid(formula){if(!formula)return!0;return!!muCalc(await intvaluta(this.amb,this,formula))}getmacrostr(){return JSON.stringify(this.getmacro())}getmacro(){return getOggetto(this,["amb"])}setmacro(vv){if(setOggetto(this,fromjson(vv,{})),this.localvar)for(const x in this.localvar){const vv=new Variante;setOggetto(vv,this.localvar[x]),this.localvar[x]=vv}}async load(xname,xcat){let name,cat;try{let tm;if(({name:name,cat:cat}=checkmu(xname||this.name,xcat||this.cat||"")),this.name||(this.name=name),this.cat||(this.cat=cat),this.azzera(),cbGetMacro&&(tm=await cbGetMacro(cat,name),"string"==typeof tm&&(tm.startsWith("{")||tm.startsWith("["))&&(tm=fromjson(tm)),tm&&tm.head&&!Array.isArray(tm.head)&&(tm.head=[]),tm.head&&(tm.dims=getheaddims(tm.dims))),tm){if("string"==typeof tm)await this.parsedata(tm);else for(const x in tm)this[x]=tm[x];return!0}errori.add(`missing cbGetFile: ${cat}/${name}`)}catch(error){errori.add(geterrdes(error),`macro.load: ${name}/${cat}`)}}async loadAndCompile(file,_cat,acapo=!1){let res;const{name:name,cat:cat}=checkmu(file,this.cat||_cat);return this.azzera(),cbGetFile&&(res=await cbGetFile(cat,name)),res?(await this.parsedata(res,acapo),this.getmacro()):void errori.add(`missing cbGetFile: ${name}/${cat}`)}async#loadinclude(file,flin,stak,pp){let res;const{name:name,cat:cat}=checkmu(file,this.cat);if(cbGetFile&&(res=await cbGetFile(cat,name)),!res)return[];if(res.includes("$1")&&pp&&pp.length>0)for(let i=1;i<pp.length;i++)res=res.replaceAll(`$${i}`,pp[i]);let tm=muClComments(res);const t2=[];flin&&(tm=tm.filter((t=>!/^\{(:?(var|valid|formula|header|genera|v|f|h))[\s|}]/im.test(t))));for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]);if(!stak.includes(pp[0])){stak.push(pp[0]);const t3=await this.loadinclude(pp[0],flin,stak,pp);Array.isArray(t3)&&t2.push(...t3),stak.pop()}}else t2.push(t)}}return t2}async parsedata(res,acapo=!1){if(this.azzera(),!res)return;const t2=[];let tm=muClComments(res),flin=!1;const lochead=[];for(const t of tm){const rr=rx1.exec(t);if(rr)flin=!rr[1].startsWith(":"),t2.push(t);else{const r1=/^\s*\{i\s(.+)?\}/im.exec(t);if(r1){const pp=getcolonne(r1[1]),t3=await this.#loadinclude(pp[0],flin,[pp[0]],pp);Array.isArray(t3)&&t2.push(...t3)}else t2.push(t)}}flin=!1;let out=this.codice;for(const t of t2){const rr=rx1.exec(t);if(rr)if(rr[1].startsWith(":"))out=this.codice;else switch(rr[1]){case"genera":case"g":{let r2=/^\s*\{(genera|g)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(getcolonne(r2[2])[0]);this.genera[name]=[],out=this.genera[name]}else out=this.errori,out.push(t)}break;case"valid":out=this.valid;break;case"var":case"v":{const r2=/^\s*\{(var|v)\s+(.+)?\}/im.exec(t);if(r2){const nn=getcolonne(r2[2]),name=checkname(nn[0]);this.localvar[name]={name:name,des:nn[1]||"",rows:[]},out=this.localvar[name].rows}else out=this.errori,out.push(t)}break;case"formula":case"f":{const r2=/^\s*\{(formula|f)\s+(.+)?\}/im.exec(t);if(r2){const name=checkname(r2[2]);this.formula[name]=[],out=this.formula[name]}else out=this.errori,out.push(t)}break;case"h":case"header":out=lochead;break;default:this.errori.push(t),out=this.errori}else t.startsWith("{")&&(out=this.codice),out.push(t)}this.parametri={},this.codice=this.cleanfiltraparametri("_",this.codice,acapo);for(const f in this.formula)this.formula[f]=this.cleanfiltraparametri(f,this.formula[f],acapo);for(const f in this.localvar){const vv=new Variante,v=this.localvar[f];vv.setheader(f,this.cat),vv.rows={};for(const x of v.rows){const c=getcolonne(x),k=c[0].trim().toLowerCase();vv.rows[k]={annulla:0,v:c}}v.des&&(vv.des=v.des),this.localvar[f]=vv}tm=this.valid,this.valid=[];for(const t of tm){let p=getcouple(t,",");p={v:p.v,msg:p.o},p.v&&(p.v.startsWith("#")?this.formula[p.v.substring(1)]&&this.valid.push(p):this.valid.push(p))}tm=lochead;const head=[];for(const t of tm){const rr=/^\s*([\w\-_]+)+[;,\s]\s*(.*)?$/im.exec(t);if(rr){const pp=getcolonne(rr[2]),c=clean(rr[1]);let ht;if(c){ht=head.find((e=>e.cod==c)),ht||(ht={cod:c,t:"t"},head.push(ht));for(const tp of pp){const p=getcouple(tp);switch(p.v){case"t":ht.t=p.o;break;case"def":case"default":ht.def=p.o;break;case"valid":case"colonna":case"hidden":p.o.startsWith("#")?this.formula[p.o.substring(1)]&&(ht[p.v]=p.o):ht[p.v]=p.o;break;default:ht[p.v]=p.o}}}}}this.head=head,tm=this.genera;const genera={};for(const kk in tm)if(Array.isArray(tm[kk])){const gen={codice:[],head:"",calcola:[],bom:[],vars:[],exclude:[]},regx=/^\s*[!:]\s*(\w+)\s*(.*)$/i;for(const k2 of tm[kk]){const rr=regx.exec(clean(k2));if(rr)switch(rr[1]){case"calcola":case"c":gen.calcola=[...gen.calcola,...getcolonne(rr[2])];break;case"exclude":case"e":case"escludi":gen.exclude=[...gen.exclude,...getcolonne(rr[2])];break;case"bom":case"db":gen.bom=[...gen.bom,...getcolonne(rr[2])];break;case"vars":case"v":gen.vars=[...gen.vars,...getcolonne(rr[2])];break;case"head":case"h":gen.head=getcolonne(rr[2]);break;default:this.errori.push(`genera ${kk} => ${k2}`)}else gen.codice.push(k2)}gen.codice=muClean(gen.codice,!0),genera[kk]=gen}this.genera=genera}cleanfiltraparametri(key,codice,acapo){if(this.paralias||(this.paralias={}),codice&&codice.length){let fl=!1;const getparalias=dati=>{const cl=[],co=getcolonne(dati);for(const c of co)if(c.includes(":")){const v=c.split(":");this.paralias[v[0]]=v[1],cl.push(v[0])}else cl.push(c);return cl};for(let i=0;i<codice.length;i++){const rr=/^:p[;,\s]+(.*)?$/im.exec(codice[i]);if(rr)codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[1]);else{const rr=/^!(parametri|pars|p)[;,\s]+(.*)?$/im.exec(codice[i]);rr&&(codice[i]=null,fl=!0,this.parametri[key]=getparalias(rr[2]))}}fl&&(codice=codice.filter((e=>null!=e)))}return codice=muClean(codice,acapo)}}function parsevariabili(text){let fl=!1;const tk=[];for(;;){const m=/\$([{[(])/m.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}{fl=!0;const classe="["==m[1]?"inline":"variabile";m.index>0&&tk.push({class:"",text:text.substring(0,m.index)});const{i:i}=parsevar(text,m.index+2,m[1],null);if(!(i>m.index)){tk.push({class:classe,text:text.substring(m.index)});break}tk.push({class:classe,text:text.substring(m.index,i+1)}),text=text.substring(i+1)}}return{fl:fl,tk:tk}}function parseexp(text,exp,callback){if(!callback)throw new Error("missing callback");let fl=!1;const tk=[];for(;;){const m=exp.exec(text);if(!m){text&&fl&&tk.push({class:"",text:text});break}m.index>0&&tk.push({class:"",text:text.substring(0,m.index)}),tk.push(...callback(m)),fl=!0,text=text.substring(m.index+m[0].length)}return{fl:fl,tk:tk}}
257
257
  /**
258
258
  * Analizza il codice sorgente e restituisce un array di token con classi CSS
259
259
  * @param {string} tt - Il codice sorgente da analizzare
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markuno_lib",
3
- "version": "1.2.33",
3
+ "version": "1.2.35",
4
4
  "description": "Croswil Markuno Language Lib",
5
5
  "author": "Croswil SRL",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -364,6 +364,7 @@ export function extractTextures(root: any, baseName: any): Promise<any[]>;
364
364
  export function fondilinee(linee: any): any[][];
365
365
  export function get3dshape(punti: any, material: any, layer: any): any;
366
366
  export function getOggetto(obj: any, exclude?: any[]): any;
367
+ export function getbb(obj: any, force?: boolean): any;
367
368
  export function getbordi(oggetti: any, bordo: any): {
368
369
  bordi: any[];
369
370
  uguali: boolean;
@@ -387,16 +388,9 @@ export function getbox(gcad: any, x: any, y: any, z: any, mat: any, options: any
387
388
  export function getcilindro(gcad: any, ori: string, h: number, r1: number, r2: number, mats: THREE.Material | any[], options: any): Promise<THREE.Group>;
388
389
  export function getcyl(gcad: any, height: any, radius: any, mat: any, options: any): any;
389
390
  export function getdumpmacro(nodo: any): string;
390
- export function getemitter(data: any): any;
391
- /**
392
- * Crea un box 3D con linee di bordo opzionali
393
- * @param {number} x - Larghezza
394
- * @param {number} y - Altezza
395
- * @param {number} z - Profondità
396
- * @param {THREE.Material} mat - Materiale da applicare
397
- * @param {Object} options - Opzioni di configurazione
398
- * @returns {Promise<THREE.Group>} Gruppo contenente il box
399
- */ export function getface(gcad: any, x: number, y: number, mat: THREE.Material, op?: {}): Promise<THREE.Group>;
391
+ declare function getemitter$1(data: any): any;
392
+ export function getextrude(gcad: any, pts: any, h?: number, holes?: any[], mat?: any, op?: {}): any;
393
+ export function getface(gcad: any, x: any, y: any, mat: any, op?: {}): any;
400
394
  export function getfakeshadow(gcad: any, shape: any, alfa: any): any;
401
395
  export function getfakeshadow2(w: any, h: any, map: any): any;
402
396
  /**
@@ -434,6 +428,7 @@ export function getmesh(geom: any, material: any, layer?: number, clone?: boolea
434
428
  */ export function getmovimento(key: string, gtimeline?: Array<any>): any;
435
429
  export function getnodebyid(id: any, nodocorrente: any): any;
436
430
  export function getpannello(gcad: any, orientamento: any, x: any, y: any, z: any, mat1: any, mat2: any, options: any): any;
431
+ export function getpannello2(gcad: any, orientamento: any, l: any, a: any, p: any, mat: any, round?: number): Promise<any>;
437
432
  /**
438
433
  * Crea un punto 3D rappresentato da una sfera
439
434
  * @param {Object} p - Coordinate del punto
@@ -442,7 +437,6 @@ export function getpannello(gcad: any, orientamento: any, x: any, y: any, z: any
442
437
  * @param {number} [size=5] - Dimensione della sfera
443
438
  * @returns {THREE.Mesh} Punto 3D
444
439
  */ export function getpoint(p: any, id: string, mat?: THREE.Material, size?: number): THREE.Mesh;
445
- export function getprojectkeys(project: any): any;
446
440
  /**
447
441
  * Calcola i punti di offset tra due percorsi
448
442
  * Trova i punti del secondo percorso che corrispondono all'offset del primo
@@ -471,7 +465,7 @@ export function getpunto(gcad: any, x: any, y: any, z: any, color: string, optio
471
465
  * @param {number} sizetesto - Dimensione del testo
472
466
  * @param {Object} options - Opzioni aggiuntive
473
467
  * @returns {THREE.Group} Gruppo contenente la quota
474
- */ export function getquota(gcad: any, testo: string, x1: number, y1: number, x2: number, y2: number, altezza?: number, offset?: number, options?: any): THREE.Group;
468
+ */ export function getquota(gcad: any, testo: string, x1: number, y1: number, x2: number, y2: number, options?: any): THREE.Group;
475
469
  export function getreceiver(gcad: any, data: any): any;
476
470
  /**
477
471
  * Crea un punto di riferimento invisibile nell'albero 3D
@@ -525,6 +519,7 @@ export function getsubrules(nodocorrente: any): ({
525
519
  * @param {Object} options - Opzioni aggiuntive
526
520
  * @returns {THREE.Mesh} Mesh con la targhetta
527
521
  */ export function gettarghetta(gcad: any, testo: any[] | string, dim?: number, options?: any): THREE.Mesh;
522
+ export function getthorus(gcad: any, r: any, tuber: number, mat: any, options: any): any;
528
523
  export function groupfromgeometry(geometry: any, material: any, x: any, y: any, z: any, name: any, layer: any): any;
529
524
  export function hash(obj: any): string;
530
525
  export function infoestrudi(shape: any, hshape: any, pts: any, options: any, sh: any): {
@@ -572,6 +567,7 @@ export function newgcad(P: any, _cat: any, islog?: boolean): {
572
567
  readonly movs: {};
573
568
  readonly textures: {};
574
569
  readonly smats: {};
570
+ readonly meshes: {};
575
571
  dump(): void;
576
572
  readonly cat: any;
577
573
  pushcat(cat: any): void;
@@ -606,8 +602,10 @@ export function revolve(gcad: any, shape: any, orient: any, mat: any, options: a
606
602
  * Salva i materiali originali di tutti i mesh nel gruppo (solo layer <= 20)
607
603
  * @param {THREE.Object3D} gruppo
608
604
  */ export function salvaMaterialiOriginali(gruppo: THREE.Object3D): void;
605
+ export function scalaoggetto(gcad: any, originale: any, scale?: {}): any;
609
606
  export const scaleunit: 0.001;
610
607
  export function setLineColorMode(white: any): void;
608
+ export function setorigine(obj: any, x?: number, y?: number, z?: number): any;
611
609
  export function shapeclip(): {
612
610
  offset(shape: any, delta: any, full?: boolean): any;
613
611
  inflate: (shape: any, delta?: number, mantainorder?: boolean, isopen?: number) => any;
@@ -730,4 +728,4 @@ declare class GLTFLoader {
730
728
  parse(data: any, path: any, onLoad: any, onError: any): any;
731
729
  parseAsync(data: any, path: any): Promise<any>;
732
730
  }
733
- export {};
731
+ export { getemitter$1 as getemitter };
@@ -117,7 +117,7 @@ export class Macro {
117
117
  getparametri(): {};
118
118
  setparametri(pars: any): Promise<{}>;
119
119
  setparametro(name: any, value: any, propaga?: boolean): Promise<any>;
120
- impostaparametri(parimposta: any, parcall: any, ismacro?: boolean): Promise<void>;
120
+ impostaparametri(parimposta: any, parcall: any, ismacro: boolean, progettokeys: any): Promise<void>;
121
121
  checkvalid(formula: any): Promise<boolean>;
122
122
  getmacrostr(): string;
123
123
  getmacro(): any;
@@ -244,7 +244,7 @@ export class Variabile {
244
244
  * Trova la prima opzione valida tra quelle disponibili
245
245
  * @param {string} opz - Opzione da controllare per prima
246
246
  * @returns {string|undefined} Prima opzione valida trovata o undefined
247
- */ firstvalid(opz: string): string | undefined;
247
+ */ firstvalid(opz: string, defs?: any): string | undefined;
248
248
  /**
249
249
  * Resetta tutti i filtri applicati alla variante
250
250
  */ resetfilter(): void;