markuno_lib 1.2.29 → 1.2.31

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/bus_utils.js CHANGED
@@ -37,13 +37,13 @@ let uniqid=1e3;function myuuid(){return uniqid++,uniqid}function getdim(l,a,p,al
37
37
  * @param {string|Array} x - Stringa con valori delimitati da \n ; o ,
38
38
  * @returns {Array<{cod: string, des: string}>} Array di oggetti con codice e descrizione
39
39
  */
40
- function listfromstring(x){if(Array.isArray(x))return x;var cl=[],fl={};if(x){var vv=x.split(/[\n;,]/);for(var v of vv){var c,d,i=v.search(/[:=#]/);i<0?c=d=v.trim():(c=v.slice(0,i),d=v.slice(i+1)),(c=c.toLowerCase())&&!fl[c]&&(fl[c]=1,cl.push({cod:c,des:d}))}}return cl}
40
+ function listfromstring(x){if(Array.isArray(x))return x;let cl=[],fl={};if(x){let vv=x.split(/[\n;,]/);for(let v of vv){let c,d,i=v.search(/[:=#]/);i<0?c=d=v.trim():(c=v.slice(0,i),d=v.slice(i+1)),c=c.toLowerCase(),c&&!fl[c]&&(fl[c]=1,cl.push({cod:c,des:d}))}}return cl}
41
41
  /**
42
42
  * Converte una stringa in numero con opzionale arrotondamento decimale
43
43
  * @param {string|number} s - Valore da convertire
44
44
  * @param {number} dec - Numero di decimali (-1 per nessun arrotondamento)
45
45
  * @returns {number} Il numero convertito
46
- */bus.messaggio=msg=>bus.emit("messaggio",msg),bus.warning=msg=>bus.emit("warning",msg),bus.errore=msg=>bus.emit("error",msg),bus.salvato=msg=>bus.emit("messaggio","dati memorizzati!"),bus.wait=modo=>bus.emit("wait",modo);var tonum=(s,dec=-1)=>{if(!s)return 0;if("number"==typeof s)return s||0;let n=0;if("string"==typeof s){let x=(s=s.replaceAll(",",".")).match(/^-?[0-9.]+$/g);x&&x.length>0?n=Number(x[0]):/^\s*-?\s*[0-9]+(\.[0-9]+)?\s*$/gi.test(s)?n=parseFloat(s):/[\s\d()-+/*^.]+/gi.test(s)&&(n=0)}if(dec>=0){const factor=Math.pow(10,dec);n=Math.round(n*factor)/factor}return n||0},toEuro=(n,gratis,des="")=>0==n?gratis||"":new Intl.NumberFormat("it-IT",{style:"currency",currency:"EUR"}).format(tonum(n))+des;
46
+ */bus.messaggio=msg=>bus.emit("messaggio",msg),bus.warning=msg=>bus.emit("warning",msg),bus.errore=msg=>bus.emit("error",msg),bus.salvato=msg=>bus.emit("messaggio","dati memorizzati!"),bus.wait=modo=>bus.emit("wait",modo);const tonum=(s,dec=-1)=>{if(!s)return 0;if("number"==typeof s)return s||0;let n=0;if("string"==typeof s){let x=(s=s.replaceAll(",",".")).match(/^-?[0-9.]+$/g);x&&x.length>0?n=Number(x[0]):/^\s*-?\s*[0-9]+(\.[0-9]+)?\s*$/gi.test(s)?n=parseFloat(s):/[\s\d()-+/*^.]+/gi.test(s)&&(n=0)}if(dec>=0){const factor=Math.pow(10,dec);n=Math.round(n*factor)/factor}return n||0},toEuro=(n,gratis,des="")=>0==n?gratis||"":new Intl.NumberFormat("it-IT",{style:"currency",currency:"EUR"}).format(tonum(n))+des;
47
47
  /**
48
48
  * Formatta un numero in valuta Euro
49
49
  * @param {number} n - Numero da formattare
@@ -73,4 +73,4 @@ function listfromstring(x){if(Array.isArray(x))return x;var cl=[],fl={};if(x){va
73
73
  * - 'mese': nome mese
74
74
  * @returns {string} Data formattata secondo il formato richiesto
75
75
  */
76
- let __formati={};var strDate=(date,formato)=>{Date.prototype.getWeek||(Date.prototype.getWeek=function(){var onejan=new Date(this.getFullYear(),0,1);return Math.ceil(((this-onejan)/864e5+onejan.getDay()+1)/7)});if("object"!=typeof date){if(!(date=parseFloat(date||0)))return"";date=date.toDate()}if("week"==formato)return"w"+date.getWeek();if(!__formati[formato])switch(formato){case"giorni":{let x=date.toInt();var gg=x.diffgiorni((new Date).toInt());return 0==gg?"Oggi":-1==gg?"Domani":1==gg?"Ieri":Math.abs(gg)<6?new Intl.DateTimeFormat("it",{weekday:"long"}).format(date).trim():strDate(x,"ggmmm")}case"date":case"shortdate":__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"short",day:"numeric",month:"short",year:"numeric"});break;case"ggmmaa":case"ggmmyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"2-digit"});break;case"datetime":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"numeric",hour12:!1,hour:"numeric",minute:"2-digit"});break;case"yyyy":case"anno":__formati[formato]=new Intl.DateTimeFormat("it",{year:"numeric"});break;case"ggmmaaaa":case"ggmmyyyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"numeric"});break;case"ggmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit"});break;case"giorno":case"gg":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit"});break;case"ggmmmaaaa":case"ggmmmyyyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short",year:"numeric"});break;case"ggmmmaa":case"ggmmmyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short",year:"2-digit"});break;case"ggmmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short"});break;case"ggmmmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"long"});break;case"mmmyy":case"mmmaa":case"mmmyyyy":case"mmmaaaa":__formati[formato]=new Intl.DateTimeFormat("it",{month:"short",year:"numeric"});break;case"weekday":__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"long"});break;case"hhmm":__formati[formato]=new Intl.DateTimeFormat("it",{hour12:!1,hour:"numeric",minute:"2-digit"});break;case"hhmmss":__formati[formato]=new Intl.DateTimeFormat("it",{hour12:!1,hour:"numeric",minute:"2-digit",second:"2-digit"});break;case"mese":__formati[formato]=new Intl.DateTimeFormat("it",{month:"long"});break;default:__formati[formato="."]||(__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"long",day:"numeric",month:"long",year:"numeric",hour12:!1,hour:"numeric",minute:"2-digit"}))}return __formati[formato].format(date).trim()};export{bus,formatDate,getdim,listfromstring,myuuid,strDate,toDateStr,toEuro,tonum};
76
+ let __formati={};const strDate=(date,formato)=>{Date.prototype.getWeek||(Date.prototype.getWeek=function(){let onejan=new Date(this.getFullYear(),0,1);return Math.ceil(((this-onejan)/864e5+onejan.getDay()+1)/7)});if("object"!=typeof date){if(!(date=parseFloat(date||0)))return"";date=date.toDate()}if("week"==formato)return"w"+date.getWeek();if(!__formati[formato])switch(formato){case"giorni":{let x=date.toInt(),gg=x.diffgiorni((new Date).toInt());if(0==gg)return"Oggi";if(-1==gg)return"Domani";if(1==gg)return"Ieri";if(Math.abs(gg)<6){return new Intl.DateTimeFormat("it",{weekday:"long"}).format(date).trim()}return strDate(x,"ggmmm")}case"date":case"shortdate":__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"short",day:"numeric",month:"short",year:"numeric"});break;case"ggmmaa":case"ggmmyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"2-digit"});break;case"datetime":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"numeric",hour12:!1,hour:"numeric",minute:"2-digit"});break;case"yyyy":case"anno":__formati[formato]=new Intl.DateTimeFormat("it",{year:"numeric"});break;case"ggmmaaaa":case"ggmmyyyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit",year:"numeric"});break;case"ggmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"2-digit"});break;case"giorno":case"gg":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit"});break;case"ggmmmaaaa":case"ggmmmyyyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short",year:"numeric"});break;case"ggmmmaa":case"ggmmmyy":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short",year:"2-digit"});break;case"ggmmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"short"});break;case"ggmmmm":__formati[formato]=new Intl.DateTimeFormat("it",{day:"2-digit",month:"long"});break;case"mmmyy":case"mmmaa":case"mmmyyyy":case"mmmaaaa":__formati[formato]=new Intl.DateTimeFormat("it",{month:"short",year:"numeric"});break;case"weekday":__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"long"});break;case"hhmm":__formati[formato]=new Intl.DateTimeFormat("it",{hour12:!1,hour:"numeric",minute:"2-digit"});break;case"hhmmss":__formati[formato]=new Intl.DateTimeFormat("it",{hour12:!1,hour:"numeric",minute:"2-digit",second:"2-digit"});break;case"mese":__formati[formato]=new Intl.DateTimeFormat("it",{month:"long"});break;default:__formati[formato="."]||(__formati[formato]=new Intl.DateTimeFormat("it",{weekday:"long",day:"numeric",month:"long",year:"numeric",hour12:!1,hour:"numeric",minute:"2-digit"}))}return __formati[formato].format(date).trim()};export{bus,formatDate,getdim,listfromstring,myuuid,strDate,toDateStr,toEuro,tonum};
package/bin/markcad.js CHANGED
@@ -145,13 +145,13 @@ constructor(p1,p2,x2=null,y2=null){"number"==typeof p1&&"number"==typeof p2&&nul
145
145
  * @param {Array<{x:number,y:number}>} pt2 - Array di punti del secondo percorso
146
146
  * @param {number} delta - Distanza di offset
147
147
  * @returns {Array<{x:number,y:number}>} Array di punti del percorso offset
148
- */function getptsoffset(pt,pt2,delta){let k1,k2,a1,a2,i1=-1,i2=-1,n=pt.length,np=pt2.length,offpt=[],l1a=new Linea2(pt[0],pt[1]),l2a=new Linea2(pt[n-2],pt[n-1]),l1=l1a.offset(delta),l2=l2a.offset(delta);for(var i=0;i<np;i++){let l=new Linea2(pt2[i%np],pt2[(i+1)%np]);l1.isparallela(l)&&l1.isCollineare(l,!0)&&(i1=i),l2.isparallela(l)&&l2.isCollineare(l,!0)&&(i2=i)}if(i1>=0&&i2>=0){i1>i2?(k1=i1-i2+2,k2=i2+np-i1+2,k1<k2?(a1=i2,a2=i1+1):(a1=i1,a2=i2+np+1)):(k1=i2-i1+2,k2=i1+np-i2+2,k1<k2?(a1=i1,a2=i2+1):(a1=i2,a2=i1+np+1));for(let i=a1;i<=a2;i++)offpt.push(pt2[i%np])}return offpt}const PIF=Math.PI/180;function clean(k,locase=!1){return locase?(k||"").trim().toLowerCase():(k||"").trim()}
148
+ */function getptsoffset(pt,pt2,delta){let k1,k2,a1,a2,i1=-1,i2=-1,n=pt.length,np=pt2.length,offpt=[],l1a=new Linea2(pt[0],pt[1]),l2a=new Linea2(pt[n-2],pt[n-1]),l1=l1a.offset(delta),l2=l2a.offset(delta);for(let i=0;i<np;i++){let l=new Linea2(pt2[i%np],pt2[(i+1)%np]);l1.isparallela(l)&&l1.isCollineare(l,!0)&&(i1=i),l2.isparallela(l)&&l2.isCollineare(l,!0)&&(i2=i)}if(i1>=0&&i2>=0){i1>i2?(k1=i1-i2+2,k2=i2+np-i1+2,k1<k2?(a1=i2,a2=i1+1):(a1=i1,a2=i2+np+1)):(k1=i2-i1+2,k2=i1+np-i2+2,k1<k2?(a1=i1,a2=i2+1):(a1=i2,a2=i1+np+1));for(let i=a1;i<=a2;i++)offpt.push(pt2[i%np])}return offpt}const PIF=Math.PI/180;function clean(k,locase=!1){return locase?(k||"").trim().toLowerCase():(k||"").trim()}
149
149
  /**
150
150
  * Rimuove i commenti dal codice sorgente mantenendo la struttura del codice
151
151
  * @param {string} codice - Il codice sorgente da processare
152
152
  * @param {boolean} tienivuoti - Se true mantiene le righe vuote
153
153
  * @returns {string[]} Array di righe di codice senza commenti
154
- */function getcolonne(value,keepquote=!1){value=String(value||"");const pp=/^(\d+)\.\.(\d+)$/.exec(value);if(pp){var n1=parseInt(pp[1]),n2=parseInt(pp[2]),cl=[];n1>n2&&([n1,n2]=[n2,n1]);for(var i=n1;i<=n2;i++)cl.push(i+"");return cl}if(!/["({[]/.test(value))return value.split(/[,;]/).map((e=>e.trim()));const risultato=[];let buffer="",livelloParentesi=0,inVirgolette=!1;for(let i=0;i<value.length;i++){const char=value[i];if(0===livelloParentesi&&'"'===char&&(0!==i&&"\\"===value[i-1]||(inVirgolette=!inVirgolette)),inVirgolette||("("===char||"["===char||"{"===char?livelloParentesi++:")"!==char&&"]"!==char&&"}"!==char||(livelloParentesi=Math.max(0,livelloParentesi-1))),","!==char&&";"!==char||0!==livelloParentesi||inVirgolette)buffer+=char;else{const trimmed=buffer.trim();risultato.push(trimmed),buffer=""}}const trimmed=buffer.trim();return trimmed&&risultato.push(trimmed),risultato.map((e=>(e=e.trim(),!keepquote&&(e.startsWith('"')&&e.endsWith('"')||e.startsWith("(")&&e.endsWith(")"))?e.slice(1,-1):e)))}function hash(obj){let str="";if("string"==typeof obj||"number"==typeof obj)str=obj+"";else if("object"==typeof obj&&obj){const chiaviOrdinati=Object.keys(obj).sort(),separatore="\0";str=chiaviOrdinati.map((key=>`${key}${separatore}${String(obj[key])}`)).join(separatore)}let h1=2166136261,h2=2218511855;for(let i=0;i<str.length;i++){const char=str.charCodeAt(i);h1^=char,h1+=h1<<5^2779096485,h2^=h1,h2=((h2<<3)+char^2134516169)>>>0}return h1>>>=0,h1.toString(16)+h2.toString(16)}function clamp(n,min=-1/0,max=1/0){return(n=Number(n)||0)<min&&(n=min),n>max&&(n=max),n}function getSqSegDist(p,p1,p2){var x=p1.x,y=p1.y,dx=p2.x-x,dy=p2.y-y;if(0!==dx||0!==dy){var t=((p.x-x)*dx+(p.y-y)*dy)/(dx*dx+dy*dy);t>1?(x=p2.x,y=p2.y):t>0&&(x+=dx*t,y+=dy*t)}return(dx=p.x-x)*dx+(dy=p.y-y)*dy}function simplifyDPStep(points,first,last,sqTolerance,simplified){for(var index,maxSqDist=sqTolerance,i=first+1;i<last;i++){var sqDist=getSqSegDist(points[i],points[first],points[last]);sqDist>maxSqDist&&(index=i,maxSqDist=sqDist)}maxSqDist>sqTolerance&&(index-first>1&&simplifyDPStep(points,first,index,sqTolerance,simplified),simplified.push(points[index]),last-index>1&&simplifyDPStep(points,index,last,sqTolerance,simplified))}function simplifyDouglasPeucker(points,sqTolerance){var last=points.length-1,simplified=[points[0]];return simplifyDPStep(points,0,last,sqTolerance,simplified),simplified.push(points[last]),simplified}
154
+ */function getcolonne(value,keepquote=!1){value=String(value||"");const pp=/^(\d+)\.\.(\d+)$/.exec(value);if(pp){let n1=parseInt(pp[1]),n2=parseInt(pp[2]),cl=[];n1>n2&&([n1,n2]=[n2,n1]);for(let i=n1;i<=n2;i++)cl.push(i+"");return cl}if(!/["({[]/.test(value))return value.split(/[,;]/).map((e=>e.trim()));const risultato=[];let buffer="",livelloParentesi=0,inVirgolette=!1;for(let i=0;i<value.length;i++){const char=value[i];if(0===livelloParentesi&&'"'===char&&(0!==i&&"\\"===value[i-1]||(inVirgolette=!inVirgolette)),inVirgolette||("("===char||"["===char||"{"===char?livelloParentesi++:")"!==char&&"]"!==char&&"}"!==char||(livelloParentesi=Math.max(0,livelloParentesi-1))),","!==char&&";"!==char||0!==livelloParentesi||inVirgolette)buffer+=char;else{const trimmed=buffer.trim();risultato.push(trimmed),buffer=""}}const trimmed=buffer.trim();return trimmed&&risultato.push(trimmed),risultato.map((e=>(e=e.trim(),!keepquote&&(e.startsWith('"')&&e.endsWith('"')||e.startsWith("(")&&e.endsWith(")"))?e.slice(1,-1):e)))}function hash(obj){let str="";if("string"==typeof obj||"number"==typeof obj)str=obj+"";else if("object"==typeof obj&&obj){const chiaviOrdinati=Object.keys(obj).sort(),separatore="\0";str=chiaviOrdinati.map((key=>`${key}${separatore}${String(obj[key])}`)).join(separatore)}let h1=2166136261,h2=2218511855;for(let i=0;i<str.length;i++){const char=str.charCodeAt(i);h1^=char,h1+=h1<<5^2779096485,h2^=h1,h2=((h2<<3)+char^2134516169)>>>0}return h1>>>=0,h1.toString(16)+h2.toString(16)}function clamp(n,min=-1/0,max=1/0){return(n=Number(n)||0)<min&&(n=min),n>max&&(n=max),n}function getSqDist(p1,p2){let dx=p1.x-p2.x,dy=p1.y-p2.y;return dx*dx+dy*dy}function getSqSegDist(p,p1,p2){let x=p1.x,y=p1.y,dx=p2.x-x,dy=p2.y-y;if(0!==dx||0!==dy){let t=((p.x-x)*dx+(p.y-y)*dy)/(dx*dx+dy*dy);t>1?(x=p2.x,y=p2.y):t>0&&(x+=dx*t,y+=dy*t)}return dx=p.x-x,dy=p.y-y,dx*dx+dy*dy}function simplifyDPStep(points,first,last,sqTolerance,simplified){let index,maxSqDist=sqTolerance;for(let i=first+1;i<last;i++){let sqDist=getSqSegDist(points[i],points[first],points[last]);sqDist>maxSqDist&&(index=i,maxSqDist=sqDist)}maxSqDist>sqTolerance&&(index-first>1&&simplifyDPStep(points,first,index,sqTolerance,simplified),simplified.push(points[index]),last-index>1&&simplifyDPStep(points,index,last,sqTolerance,simplified))}function simplifyDouglasPeucker(points,sqTolerance){let last=points.length-1,simplified=[points[0]];return simplifyDPStep(points,0,last,sqTolerance,simplified),simplified.push(points[last]),simplified}
155
155
  /**
156
156
  * Esegue la semplificazione di un poligono (array di punti) combinando
157
157
  * l’algoritmo di distanza radiale e l’algoritmo di Ramer–Douglas–Peucker.
@@ -163,7 +163,7 @@ constructor(p1,p2,x2=null,y2=null){"number"==typeof p1&&"number"==typeof p2&&nul
163
163
  * @param {boolean} [highestQuality=false] - Se `true`, salta il passaggio di
164
164
  * semplificazione radiale e usa solo Douglas–Peucker per massima qualità.
165
165
  * @returns {Array<{x:number,y:number}>} Nuovo array di punti semplificato.
166
- */function mapvertices(pat1,pat2){const dist2=(a,b)=>(a.x-b.x)**2+(a.y-b.y)**2;let n1=pat1.length,n2=pat2.length;if(n1<2||n2<2)return[];let map=[[0,0]];if(n1===n2){for(let i=1;i<n1;i++)map.push([i,i]);return map}if(n1>n2)for(let i=1,j=0;i<n1-1;i++){if(j+1<n2){const p=pat1[i],d1=dist2(p,pat2[j]);dist2(p,pat2[j+1])<=d1&&j++}map.push([i,j])}else for(let i=1,j=0;i<n2-1;i++){if(j+1<n1){const p=pat2[i],d1=dist2(p,pat1[j]);dist2(p,pat1[j+1])<=d1&&j++}map.push([j,i])}return map.push([n1-1,n2-1]),map}
166
+ */function simplify(points,tolerance,highestQuality){if(points.length<=2)return points;let sqTolerance=void 0!==tolerance?tolerance*tolerance:1;return points=highestQuality?points:function simplifyRadialDist(points,sqTolerance){let point,prevPoint=points[0],newPoints=[prevPoint];for(let i=1,len=points.length;i<len;i++)point=points[i],getSqDist(point,prevPoint)>sqTolerance&&(newPoints.push(point),prevPoint=point);return prevPoint!==point&&newPoints.push(point),newPoints}(points,sqTolerance),points=simplifyDouglasPeucker(points,sqTolerance)}function mapvertices(pat1,pat2){const dist2=(a,b)=>(a.x-b.x)**2+(a.y-b.y)**2;let n1=pat1.length,n2=pat2.length;if(n1<2||n2<2)return[];let map=[[0,0]];if(n1===n2){for(let i=1;i<n1;i++)map.push([i,i]);return map}if(n1>n2)for(let i=1,j=0;i<n1-1;i++){if(j+1<n2){const p=pat1[i],d1=dist2(p,pat2[j]);dist2(p,pat2[j+1])<=d1&&j++}map.push([i,j])}else for(let i=1,j=0;i<n2-1;i++){if(j+1<n1){const p=pat2[i],d1=dist2(p,pat1[j]);dist2(p,pat1[j+1])<=d1&&j++}map.push([j,i])}return map.push([n1-1,n2-1]),map}
167
167
  /**
168
168
  * Calcola i punti di un arco DXF dato p1, p2, bulge e n punti intermedi.
169
169
  * p1, p2: oggetti {x, y}
@@ -286,7 +286,7 @@ function sharpCorners(path,thresholdDeg=45){const result=[],n=path.length;if(n<3
286
286
  * @param {number} thresholdDeg - Angolo in gradi.
287
287
  * @returns {Array<{ index: number, point: {x:number,y:number}, angle: number }>}
288
288
  */
289
- segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=function simplify(points,tolerance,highestQuality){if(points.length<=2)return points;var sqTolerance=void 0!==tolerance?tolerance*tolerance:1;return simplifyDouglasPeucker(points=highestQuality?points:function simplifyRadialDist(points,sqTolerance){for(var point,p1,p2,dx,dy,prevPoint=points[0],newPoints=[prevPoint],i=1,len=points.length;i<len;i++)p2=prevPoint,dx=void 0,dy=void 0,(dx=(p1=point=points[i]).x-p2.x)*dx+(dy=p1.y-p2.y)*dy>sqTolerance&&(newPoints.push(point),prevPoint=point);return prevPoint!==point&&newPoints.push(point),newPoints}(points,sqTolerance),sqTolerance)}(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},sliceony(stag){let yvalues=stag.pt.map((e=>e.y)).slice(1,-1);const res=[],n=pt.length;let imin=0,yMin=pt[0].y;for(let i=1;i<n;i++)pt[i].y<yMin&&(yMin=pt[i].y,imin=i);const pts=[...pt.slice(imin),...pt.slice(0,imin)],m=pts.length,ymap=new Map;for(let i=0;i<m;i++)for(let y of yvalues)Math.abs(pts[i].y-y)<1e-5&&(ymap.has(y)?ymap.get(y).i2=i:ymap.set(y,{i1:i,i2:i}));const pairs=yvalues.map((y=>ymap.get(y))).filter((p=>p&&p.i1>=0&&p.i2>=0));pairs.length>0&&pairs[0].i1>0&&res.push([...pts.slice(0,pairs[0].i1+1),...pts.slice(pairs[0].i2,pairs[0].length)]);for(let i=0;i<pairs.length-1;i++){const a=pairs[i],b=pairs[i+1];res.push([...pts.slice(a.i1,b.i1+1),...pts.slice(b.i2,a.i2+1)])}const last=pairs[pairs.length-1];last.i2>last.i1&&res.push(pts.slice(last.i1,last.i2+1));return res.filter((arr=>arr.length>0))},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrrect(w,h,r=10,sx=0,sy=0){return(r>=w/2||r>=h/2&&r<=0)&&(r=Math.round(Math.min(w/3,h/3))),fromstr(`0,0,r${r},${w},0,r${r},${w},${h},r${r},0,${h},r${r}`),(sx||sy)&&move(sx,sy),this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},truncatebefore:function truncatebefore(linea){let s=new Linea2(pt[0],pt[1]),p=linea.interseca(s);if(p){let a=pt[0],b=pt[1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den<=1)return pt[0]=p,this}}for(let i=1;i<pt.length-1;i++){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(i),pt[0]=p,this}return this},truncateafter:function truncateafter(linea){let np=pt.length,s=new Linea2(pt[np-2],pt[np-1]),p=linea.interseca(s);if(p){let a=pt[np-2],b=pt[np-1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den>=0)return pt[np-1]=p,this}}for(let i=np-3;i>=0;i--){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(0,i+1),pt.push(p),this}return this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
289
+ segment(i,inverse=!1){let n=pt.length;return i<0&&(i+=n),new Linea2(pt[i%n],pt[(i+(inverse?-1:1))%n])},lineoffset(i1,i2,offset){if((i1=(i1||0)%pt.length)!=(i2=(i2||0)%pt.length)){let l2=new Linea2(pt[i1],pt[i2]);if(l2){return l2=l2.offsetline(-offset),this.intersectline(l2)}}},orientasplitter(){-1!=orientation()&&pt.reverse();let np=pt.length;for(let i=0;i<np;i++){let lt=new Linea2(pt[(np+i-1)%np],pt[i]);if(Math.abs(Math.abs(lt.angle)-Math.PI)<.001){i&&selezionaprimo(i);break}}return this},mirrorx(value=0){for(let p of pt)p.x=2*value-p.x;return this},mirrory(value=0){for(let p of pt)p.y=2*value-p.y;return this},simplify(tolerance,hq){return pt=simplify(pt,tolerance,hq),this},fromclip(vv){pt=[];for(let p of vv)pt.push({x:p.x/1e3,y:p.y/1e3});return this},infosegmento(i,open=!1){const n=pt.length;function clampIndex(idx){return(idx+n)%n}function angle(p1,p2){return Math.atan2(p2.y-p1.y,p2.x-p1.x)}function angleDiff(a,b){let diff=a-b;for(;diff>Math.PI;)diff-=2*Math.PI;for(;diff<-Math.PI;)diff+=2*Math.PI;return diff}const p1=pt[i];let p0,p2,p3;if(open)if(0===i){const dx=pt[1].x-pt[0].x,dy=pt[1].y-pt[0].y;p0={x:pt[0].x-dx,y:pt[0].y-dy},p2=pt[1],p3=pt[2]}else if(i===n-1){const dx=pt[n-1].x-pt[n-2].x,dy=pt[n-1].y-pt[n-2].y;p0=pt[n-2],p2={x:pt[n-1].x+dx,y:pt[n-1].y+dy},p3={x:p2.x+dx,y:p2.y+dy}}else p0=pt[i-1],p2=pt[i+1],p3=i+2<n?pt[i+2]:{x:pt[i+1].x+(pt[i+1].x-pt[i].x),y:pt[i+1].y+(pt[i+1].y-pt[i].y)};else{const i0=clampIndex(i-1),i2=clampIndex(i+1),i3=clampIndex(i+2);p0=pt[i0],p2=pt[i2],p3=pt[i3]}const ang12=angle(p1,p2),ang01=angle(p0,p1),ang23=angle(p2,p3);return{x:p1.x,y:p1.y,l:function length(p1,p2){const dx=p2.x-p1.x,dy=p2.y-p1.y;return Math.sqrt(dx*dx+dy*dy)}(p1,p2),ang:ang12/PIF,a1:angleDiff(ang12,ang01)/PIF,a2:angleDiff(ang23,ang12)/PIF}},swapxy(){for(let i=0;i<pt.length;i++){let q=pt[i].x;pt[i].x=-pt[i].y,pt[i].y=-q}return this},fromvec(aa){return pt=[],_addvec(aa),this},addvec(vec){return _addvec(vec),this},frompt(pts){return pt=[...pts],pt=removeduplicate(pt),this},fromdxfvec(verts){let points=[];if(verts&&verts.length)for(let i=0;i<verts.length;i++){let{x:x,y:y,bulge:bulge}=verts[i];if(points.push({x:x,y:y}),bulge){const step=1;let p1={x:x,y:y},p2=verts[(i+1)%verts.length],dx=p2.x-p1.x,dy=p2.y-p1.y,dist=Math.hypot(dx,dy);dist>step&&points.push(...dxfbulge(p1,p2,bulge,Math.floor((dist-step)/step)+1))}}return pt=points.map((e=>({x:Math.round(10*e.x)/10,y:Math.round(10*e.y)/10}))),pt=removeduplicate(pt),this},monotona(){let dxd=dims(pt),pp=pt.map((e=>({x:e.x-dxd.p2.x,y:e.y}))),xp=[];xp.push(pp[0]);let lastv=pp[0].y;for(let i=1;i<pp.length;i++)if(pp[i].y>lastv+1e-4||i==pp.length-1)xp.push(pp[i]),lastv=pp[i].y;else{const newv=lastv+1e-4;xp.push({x:pp[i].x,y:newv}),lastv=newv}return{sh:getshape().frompt(xp),...dxd}},sliceony(stag){let yvalues=stag.pt.map((e=>e.y)).slice(1,-1);const res=[],n=pt.length;let imin=0,yMin=pt[0].y;for(let i=1;i<n;i++)pt[i].y<yMin&&(yMin=pt[i].y,imin=i);const pts=[...pt.slice(imin),...pt.slice(0,imin)],m=pts.length,ymap=new Map;for(let i=0;i<m;i++)for(let y of yvalues)Math.abs(pts[i].y-y)<1e-5&&(ymap.has(y)?ymap.get(y).i2=i:ymap.set(y,{i1:i,i2:i}));const pairs=yvalues.map((y=>ymap.get(y))).filter((p=>p&&p.i1>=0&&p.i2>=0));pairs.length>0&&pairs[0].i1>0&&res.push([...pts.slice(0,pairs[0].i1+1),...pts.slice(pairs[0].i2,pairs[0].length)]);for(let i=0;i<pairs.length-1;i++){const a=pairs[i],b=pairs[i+1];res.push([...pts.slice(a.i1,b.i1+1),...pts.slice(b.i2,a.i2+1)])}const last=pairs[pairs.length-1];last.i2>last.i1&&res.push(pts.slice(last.i1,last.i2+1));return res.filter((arr=>arr.length>0))},splitshape(p,verticale=!0){const p1=verticale?{x:p.x,y:p.y-100}:{x:p.x-100,y:p.y},p2=verticale?{x:p.x,y:p.y+100}:{x:p.x+100,y:p.y},linea=this.intersectline(new Linea2(p1,p2));if(!linea)return null;const pstart=linea.p1,pend=linea.p2,findIndex=pt=>this.pt.findIndex(((v,i)=>new Linea2(v,this.pt[(i+1)%this.pt.length]).onsegment(pt))),i1=findIndex(pstart),i2=findIndex(pend);if(i1<0||i2<0)return null;const n=this.pt.length,loop=(a,b,p0,p1)=>{const res=[];for(let i=a;i!==b;i=(i+1)%n)res.push(this.pt[(i+1)%n]);return res},dx=getshape().frompt(loop(i1,i2));return{sx:getshape().frompt(loop(i2,i1)),dx:dx,linea:linea}},xfromy(y,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.y<=y&&p2.y>=y||p2.y<=y&&p1.y>=y){const dy=p2.y-p1.y,t=dy?(y-p1.y)/dy:0,x=p1.x+t*(p2.x-p1.x);res.push(x)}else p1.y===y&&p2.y===y&&res.push(maggiore?Math.max(p1.x,p2.x):Math.min(p1.x,p2.x))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},yfromx(x,valore0=0,maggiore=!0){const res=[],n=this.pt.length;for(let i=0;i<n-1;i++){const p1=this.pt[i],p2=this.pt[i+1];if(p1.x<=x&&p2.x>=x||p2.x<=x&&p1.x>=x){const dx=p2.x-p1.x,t=dx?(x-p1.x)/dx:0,y=p1.y+t*(p2.y-p1.y);res.push(y)}else p1.x===x&&p2.x===x&&res.push(maggiore?Math.max(p1.y,p2.y):Math.min(p1.y,p2.y))}return res.length?maggiore?Math.max(...res):Math.min(...res):valore0},forcevalues(shape,verticale=!0,delta=1e-6){const sorted=[...new Set(shape.pt.map((e=>verticale?e.y:e.x)))].sort(((a,b)=>a-b)),newpt=[],n=pt.length;for(let i=0;i<n;i++){const p1=pt[i],p2=pt[(i+1)%n];newpt.push({...p1});let v1=verticale?p1.y:p1.x,v2=verticale?p2.y:p2.x;if(v1===v2)continue;const range=v2>v1?sorted.filter((v=>v>v1+delta&&v<v2-delta)):sorted.filter((v=>v<v1-delta&&v>v2+delta)).reverse();for(const v of range){const t=(v-v1)/(v2-v1),q={x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};newpt.push(q)}}return pt=newpt,this},fromrrect(w,h,r=10,sx=0,sy=0){return(r>=w/2||r>=h/2&&r<=0)&&(r=Math.round(Math.min(w/3,h/3))),fromstr(`0,0,r${r},${w},0,r${r},${w},${h},r${r},0,${h},r${r}`),(sx||sy)&&move(sx,sy),this},fromrect(w,h,sx,sy,bordo){w||(w=10),h||(h=10),bordo||(bordo=0),bordo=Math.min(Math.abs(bordo),Math.abs(.4*w),Math.abs(.4*h));let b1=w>0?bordo:-bordo,b2=h>0?bordo:-bordo;return pt=bordo?[{x:b1,y:0},{x:w-b1,y:0},{x:w,y:b2},{x:w,y:h-b2},{x:w-b1,y:h},{x:b1,y:h},{x:0,y:h-b2},{x:0,y:b2}]:[{x:0,y:0},{x:w,y:0},{x:w,y:h},{x:0,y:h}],this},intersectline:l=>function _intersectline(shape,p3,p4){let n=shape.length,l=new Linea2(p3,p4);const intersezioni=[];for(let i=0;i<shape.length;i++){let l2=new Linea2(shape[i],shape[(i+1)%n]),p=l2.interseca(l);p&&l2.onsegment(p)&&intersezioni.push(p)}if(intersezioni.length<2)return null;const{dx:dx,dy:dy}=l;intersezioni.sort(((a,b)=>(a.x-p3.x)*dx+(a.y-p3.y)*dy-((b.x-p3.x)*dx+(b.y-p3.y)*dy)));let pstart=new Punto2(intersezioni[0].x,intersezioni[0].y),pend=new Punto2(intersezioni[intersezioni.length-1].x,intersezioni[intersezioni.length-1].y);const vx1=pend.x-pstart.x,vy1=pend.y-pstart.y;return vx1*dx+vy1*dy<0&&([pstart,pend]=[pend,pstart]),new Linea2(pstart,pend)}(pt,l.p1,l.p2),tostr(dec=2){let dd=10**dec,pstr=x=>String(Math.round(x*dd)/dd),cl=pt.map((e=>`${pstr(e.x)};${pstr(e.y)};`)).join("");return cl&&cl.length?cl.slice(0,-1).match(/.{1,80}(;|$)/g).map((s=>s.trim())).join("\n"):""},addpt(pts){return pts?(Array.isArray(pts)||(pts=[pts]),pt=removeduplicate([...pt,...pts]),this):this},addracc(v1,v2,suddivisioni=2,addv1v2=!0){if(Array.isArray(v1)&&(v2={x:v1[2]||0,y:v1[3]||0},v1={x:v1[0]||0,y:v1[1]||0}),pt.length>=2){let tm=raccordabezier(pt[pt.length-2],pt[pt.length-1],v1,v2,suddivisioni);pt=[...pt,...tm],addv1v2&&(pt.push(v1),pt.push(v2))}return pt=removeduplicate(pt),this},setorient(mode){let p=orientation();return(1==p&&-1==mode||-1==p&&1==mode)&&pt.reverse(),this},reverse(){return pt.reverse(),this},pointinshape:p=>function isPointInPolygon(P){let x=P.x,y=P.y,inside=!1;for(let i=0,j=pt.length-1;i<pt.length;j=i++){let xi=pt[i].x,yi=pt[i].y,xj=pt[j].x,yj=pt[j].y;yi>y!=yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}(p),azzera(){return pt=[],this},truncatebefore:function truncatebefore(linea){let s=new Linea2(pt[0],pt[1]),p=linea.interseca(s);if(p){let a=pt[0],b=pt[1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den<=1)return pt[0]=p,this}}for(let i=1;i<pt.length-1;i++){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(i),pt[0]=p,this}return this},truncateafter:function truncateafter(linea){let np=pt.length,s=new Linea2(pt[np-2],pt[np-1]),p=linea.interseca(s);if(p){let a=pt[np-2],b=pt[np-1],dx=b.x-a.x,dy=b.y-a.y,den=dx*dx+dy*dy;if(den){if(((p.x-a.x)*dx+(p.y-a.y)*dy)/den>=0)return pt[np-1]=p,this}}for(let i=np-3;i>=0;i--){let s=new Linea2(pt[i],pt[i+1]),p=linea.interseca(s);if(p&&s.onsegment(p))return pt=pt.slice(0,i+1),pt.push(p),this}return this},removeduplicate(delta=.005){return pt=removeduplicate(pt,delta),this},to3d(u0,alt=0,coeffa=0,coeffb=0,open=!1,sh=null,invert=!1){let tm=function to3dcoor(path,options){let{currentU:currentU=0,c:c=0,a:a=0,b:b=0,anglemin:anglemin=30,open:open=!1,sh:sh=null,invert:invert=!1}=options;const pointsWithNormals=[],n=path.length;for(let i=0;i<n;i++){const prev=path[(i-1+n)%n],current=path[i],next=path[(i+1)%n],vPrev={x:current.x-prev.x,y:current.y-prev.y},vNext={x:next.x-current.x,y:next.y-current.y},normalPrev=normal2(prev,current),normalNext=normal2(current,next),angle=angle2vec(vPrev,vNext);let z=a*current.x+b*current.y+c;if(sh){let t=sh.xfromy(current.y,0,!0);invert?z+=t:z-=t}Math.abs(angle-180)<=anglemin?(normalPrev.nx,normalNext.nx,normalPrev.ny,normalNext.ny,pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z})):(pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}),pointsWithNormals.push({x:current.x,y:-current.y,z:z,u:currentU,v:z}));const dx=next.x-current.x,dy=next.y-current.y;currentU+=Math.sqrt(dx*dx+dy*dy)}if(!open){let p=pointsWithNormals[0],pf=pointsWithNormals[pointsWithNormals.length-1];p.x==pf.x&&p.y==pf.y||pointsWithNormals.push({x:p.x,y:p.y,z:p.z,nx:p.nx,ny:p.ny,nz:p.nz,u:currentU,v:p.z})}return pointsWithNormals}(pt,{open:open,currentU:u0,c:alt,a:coeffa,b:coeffb,anglemin:30,sh:sh,invert:invert});return tm},getboundbox:()=>pt.length?pt.reduce(((box,p)=>(box.p1.x=Math.min(box.p1.x,p.x),box.p1.y=Math.min(box.p1.y,p.y),box.p2.x=Math.max(box.p2.x,p.x),box.p2.y=Math.max(box.p2.y,p.y),box)),{p1:new Punto2(1/0,1/0),p2:new Punto2(-1/0,-1/0)}):{p1:new Punto2(0,0),p2:new Punto2(0,0)},fittobox(p1,p2){if(!pt.length)return this;const currentBox=this.getboundbox(),currentWidth=currentBox.p2.x-currentBox.p1.x,currentHeight=currentBox.p2.y-currentBox.p1.y,targetWidth=p2.x-p1.x,targetHeight=p2.y-p1.y,scale=Math.min(targetWidth/(currentWidth||1),targetHeight/(currentHeight||1));for(let p of pt)p.x=(p.x-currentBox.p1.x)*scale,p.y=(p.y-currentBox.p1.y)*scale,p.x+=p1.x,p.y+=p1.y;return this}}}
290
290
  /**
291
291
  * Calcola i punti di un arco passante per tre punti
292
292
  * @param {number} segments - Numero di segmenti (punti-1)
@@ -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={i:"inclinato",a:"arco",d:"diagonali",s:"smussato",x:"normale"},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))}for(var h of(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)}))})),h1)){let cuts=[...h.cuts],pv1=[...pv];for(var 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(),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());let k=findareacod(areacodes,p1.x,p1.y),cod=ff.aree[k]||ff.area||"",c2=checkoggetto(oggetti,"a",cod);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(var 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={i:"inclinato",a:"arco",d:"diagonali",s:"smussato",x:"normale"},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(),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());let k=findareacod(areacodes,p1.x,p1.y),cod=ff.aree[k]||ff.area||"",c2=checkoggetto(oggetti,"a",cod);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,tipoalign:tipoalign,tipocut:tipocut});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(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"].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){var 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}=pos;if(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,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(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"].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}
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=!0,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 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}}
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)
@@ -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,scaled=!1){let ky=hash(`f:${x}|${y}|${scaled?1:0}`);if(!gcad.geo[ky]){const geometry=new THREE.PlaneGeometry(x,y),uvs=geometry.attributes.uv;if(!scaled)for(let i=0;i<uvs.count;i++)uvs.setXY(i,uvs.getX(i)*x,uvs.getY(i)*y);gcad.geo[ky]=geometry}const plane=new THREE.Mesh(gcad.geo[ky],mat);return plane.position.set(x/2,y/2,0),mat?.transparent&&plane.layers.set(2),plane}function getcyl(gcad,height,radius,mat,options){options||(options={});let{center:center=!1,nolines:nolines=!1,segments:segments=16,radiusBottom:radiusBottom=-1}=options;radiusBottom<0&&(radiusBottom=radius);let grp=new THREE.Group;const cylinder=new THREE.CylinderGeometry(radius,radiusBottom,height,segments);if(grp.position.set(0,center?0:height/2,0),!nolines){let segments=edgesfromgeometry(cylinder);grp.add(segments)}return grp.add(getmesh(cylinder,mat||mwhite)),grp}function getbox(gcad,x,y,z,mat,options){options||(options={});let{center:center=!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 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}
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)
@@ -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 g1=bottomgeomfromshape(gcad,!1,shape,open||nobottomholes?[]:holes,p0,coeffbase1,coeffbase2,shapebase);options.nolines||grp.add(edgesfromgeometry(g1)),grp.add(getmesh(g1,mats[0]||mwhite))}if(!options.notop){let g3=bottomgeomfromshape(gcad,!0,shape,open||notopholes?[]:holes,p1,coefftop1,coefftop2,shapetop);grp.add(getmesh(g3,mats[1]||mats[0]||mwhite)),options.nolines||grp.add(edgesfromgeometry(g3))}if(!options.nosides){let pat1=shape.to3d(0,p0,coeffbase1,-coeffbase2,open,shapebase,!opinvert),pat2=shape.to3d(1,p1,coefftop1,-coefftop2,open,shapetop,opinvert),ky=`${shape.key}${opinvert?1:0}|${p0}|${p1}|${coeffbase1}|${coeffbase2||shb}|${coefftop1}|${coefftop2||sht}|${open}`,geo1=sidegeomfromshapes(gcad,ky,pat1,pat2,!1);if(options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),holes&&!open&&!nobottomholes&&!notopholes)for(var h of holes){pat1=h.to3d(0,p0,coeffbase1,coeffbase2),pat2=h.to3d(0,p1,coefftop1,coefftop2),ky=`${h.key}|${p0}|${p1}|${coeffbase1}|${coeffbase2}|${coefftop1}|${coefftop2}`;let geo2=sidegeomfromshapes(gcad,ky,pat1,pat2,!0);options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo2)),grp.add(getmesh(geo2,mats[3]||mats[0]||mwhite))}}return estrusorotate(orient,grp,hshape)}return grp}function revolve(gcad,shape,orient,mat,options){options||(options={});let segmenti=options.segmenti??12,ky=hash(`rev|${shape.key}|${orient}|${segmenti}`),geometria=gcad.geo[ky],grp=new THREE.Group;if(!geometria){const punti3D=shape.pt.map((p=>new THREE.Vector3(p.x,p.y,0)));geometria=new THREE.LatheGeometry(punti3D,segmenti,0,2*Math.PI),gcad.geo[ky]=geometria}const mesh=new THREE.Mesh(geometria,mat);return grp.add(mesh),options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geometria)),grp}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 g1=bottomgeomfromshape(gcad,!1,shape,open||nobottomholes?[]:holes,p0,coeffbase1,coeffbase2,shapebase);options.nolines||grp.add(edgesfromgeometry(g1)),grp.add(getmesh(g1,mats[0]||mwhite))}if(!options.notop){let g3=bottomgeomfromshape(gcad,!0,shape,open||notopholes?[]:holes,p1,coefftop1,coefftop2,shapetop);grp.add(getmesh(g3,mats[1]||mats[0]||mwhite)),options.nolines||grp.add(edgesfromgeometry(g3))}if(!options.nosides){let pat1=shape.to3d(0,p0,coeffbase1,-coeffbase2,open,shapebase,!opinvert),pat2=shape.to3d(1,p1,coefftop1,-coefftop2,open,shapetop,opinvert),ky=`${shape.key}${opinvert?1:0}|${p0}|${p1}|${coeffbase1}|${coeffbase2||shb}|${coefftop1}|${coefftop2||sht}|${open}`,geo1=sidegeomfromshapes(gcad,ky,pat1,pat2,!1);if(options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),holes&&!open&&!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={}}}}
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"};
@@ -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,estruso,estrusopat,evalcustomfunction,evidenziaColli,extractTextures,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,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,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};