GcodeToolpathViewer-D4M17KI8.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,l as r,w as i}from"./client-BdOyoZJz.js";import{t as a}from"./createLucideIcon-Yo2YoYjm.js";import{t as o}from"./loader-circle-CB4leTZa.js";import{A as s,O as c,_ as l,a as u,i as d,l as f,m as p,p as m,r as h,t as g,w as _}from"./OrbitControls-Bbqf07B-.js";var v=a(`file-exclamation-point`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),y=e(n(),1),b={travel:0,wall:1,sparseInfill:2,solidInfill:3,skirt:4,support:5,raft:6,gapFill:7,thinWall:8,bridge:9,ironing:10,primeTower:11},x={"outer wall":b.wall,"inner wall":b.wall,perimeter:b.wall,"external perimeter":b.wall,"overhang wall":b.bridge,"overhang perimeter":b.bridge,"sparse infill":b.sparseInfill,"internal infill":b.sparseInfill,"solid infill":b.solidInfill,"internal solid infill":b.solidInfill,"top surface":b.solidInfill,"top solid infill":b.solidInfill,"bottom surface":b.solidInfill,skirt:b.skirt,"skirt/brim":b.skirt,brim:b.skirt,support:b.support,"support material":b.support,"support interface":b.support,"support material interface":b.support,"support transition":b.support,raft:b.raft,"gap fill":b.gapFill,"gap infill":b.gapFill,"thin wall":b.thinWall,"floating vertical shell":b.solidInfill,"internal bridge":b.bridge,"bottom shell":b.solidInfill,bridge:b.bridge,"bridge infill":b.bridge,"internal bridge infill":b.bridge,ironing:b.ironing,"prime tower":b.primeTower,"wipe tower":b.primeTower,custom:b.wall},S=8,C=Math.PI*2,w=.02,T=256,E=15,D=class{data=new Float32Array(1024*S);count=0;widths=[];push(e,t,n,r,i,a,o,s,c){if((this.count+1)*S>this.data.length){let e=new Float32Array(this.data.length*2);e.set(this.data),this.data=e}let l=this.count*S;this.data[l]=e,this.data[l+1]=t,this.data[l+2]=n,this.data[l+3]=r,this.data[l+4]=i,this.data[l+5]=a,this.data[l+6]=o,this.data[l+7]=c,this.count+=1,this.widths.push(s)}get length(){return this.count}toFloat32Array(){return this.data.slice(0,this.count*S)}};function O(e){let t,n=0;for(let[r,i]of e)i>n&&(t=r,n=i);return t}function k(e,t){let n=e.indexOf(t);if(n<0)return;let r=Number.parseFloat(e.slice(n+1));return Number.isFinite(r)?r:void 0}function A(e){let t=[],n=0,r=0,i=0,a=0,o=!1,s=b.wall,c=0,l=new Map,u=0,d=0,f=new D,p=0,m=!1,h=null,g=!1,_=0,v=!1,y=1/0,S=1/0,A=1/0,j=-1/0,M=-1/0,N=-1/0,P=()=>{f.length!==0&&(t.push({z:p,paths:f.toFloat32Array(),widths:f.widths}),f=new D,g=!1,h!==null&&(p=h,h=null))},F=(e,t,a,o)=>{if(o){if(!m&&g&&a!==p&&P(),g||(p=a,h=null),g=!0,!v){v=!0,n=e,r=t,i=a;return}f.push(n,r,i,s,e,t,a,c,_),u+=1,e<y&&(y=e),t<S&&(S=t),a<A&&(A=a),e>j&&(j=e),t>M&&(M=t),a>N&&(N=a)}else v&&(f.push(n,r,i,b.travel,e,t,a,0,_),d+=1);n=e,r=t,i=a,v=!0};for(let t of e.split(`
  2. `)){let e=t.trim();if(e.length===0)continue;if(e.charCodeAt(0)===59){let t=e.slice(1).trimStart(),n=t.indexOf(`:`),r=(n>=0?t.slice(0,n):t).trim().toUpperCase(),i=n>=0?t.slice(n+1).trim():``;if(r===`FEATURE`||r===`TYPE`)s=x[i.toLowerCase()]??b.wall;else if(r===`LINE_WIDTH`||r===`WIDTH`){let e=Number.parseFloat(i);Number.isFinite(e)&&e>0&&(c=e,l.set(e,(l.get(e)??0)+1))}else if(r===`CHANGE_LAYER`||r===`LAYER_CHANGE`)m=!0,P();else if(r===`Z_HEIGHT`||r===`Z`){let e=Number.parseFloat(i);Number.isFinite(e)&&(h=e)}continue}if(e.startsWith(`M83`)){o=!0;continue}if(e.startsWith(`M82`)){o=!1;continue}if(e.startsWith(`G92`)){let t=k(e,`E`);t!==void 0&&(a=t);continue}if(e.charCodeAt(0)===84){let t=Number.parseInt(e.slice(1),10);Number.isFinite(t)&&t>=0&&t<=E&&(_=t);continue}let u=e.startsWith(`G2 `)||e.startsWith(`G3 `)||e.startsWith(`G2`)||e.startsWith(`G3`),d=e.startsWith(`G1`)||e.startsWith(`G0`);if(!d&&!u||u&&!/^G[23](\s|$)/.test(e)||d&&!/^G[01](\s|$)/.test(e))continue;let f=k(e,`X`)??n,p=k(e,`Y`)??r,g=k(e,`Z`)??i,v=k(e,`E`),y=0;v!==void 0&&(y=o?v:v-a,a=v);let S=y>0;if(u){let t=k(e,`I`)??0,a=k(e,`J`)??0,o=n+t,s=r+a,c=Math.hypot(t,a);if(c>0){let t=Math.atan2(r-s,n-o),a=Math.atan2(p-s,f-o),l=e.charCodeAt(1)===50,u=a-t;if(l){for(;u>=0;)u-=C;for(;u<-C;)u+=C}else{for(;u<=0;)u+=C;for(;u>C;)u-=C}if(f===n&&p===r){let t=Math.max(1,Math.round(k(e,`P`)??1));u=(l?-C:C)*t}let d=2*Math.acos(Math.max(-1,Math.min(1,1-w/c))),m=Math.max(1,Math.min(T,Math.ceil(Math.abs(u)/Math.max(d,.001))));for(let e=1;e<=m;e+=1){let n=e/m,r=t+u*n;F(o+c*Math.cos(r),s+c*Math.sin(r),i+(g-i)*n,S)}continue}}(f!==n||p!==r||g!==i)&&F(f,p,g,S)}return P(),{layers:t,segmentCount:u,travelCount:d,defaultWidth:O(l)??.42,bounds:u>0?{min:[y,S,A],max:[j,M,N]}:null}}function j(e){return e.map(e=>{let t=e.paths.slice();for(let e=0;e<t.length;e+=S)t[e+3]!==b.travel&&(t[e+3]=Math.min(t[e+7]+1,E));return{...e,paths:t}})}function M(e,t){if(t.size===0)return e;let n=[];for(let r of e){let e=new D;for(let n=0;n<r.paths.length;n+=S){let i=r.paths[n+3];t.has(i)||e.push(r.paths[n],r.paths[n+1],r.paths[n+2],i,r.paths[n+4],r.paths[n+5],r.paths[n+6],r.widths[n/S]??0,r.paths[n+7])}n.push({...r,paths:e.toFloat32Array(),widths:e.widths})}return n}var N=[0,1,2,0,2,3,0,3,4,0,4,5,0,5,6,0,6,1,5,4,7,5,7,6],P={0:[.42,.45,.5],1:[.85,.51,.17],2:[.21,.45,.76],3:[.35,.75,.85],4:[.16,.68,.4],5:[.66,.42,.85],6:[.55,.45,.35],7:[.95,.85,.25],8:[.9,.35,.65],9:[.9,.25,.25],10:[.6,.82,.55],11:[.3,.72,.7]};function F(e){let t=Math.round(e[0]*255),n=Math.round(e[1]*255),r=Math.round(e[2]*255);return t<<16|n<<8|r}function I(e,t){let n=e.length,r=t>0?t:.42,i=Array(n);for(let t=0;t<n;t++){let n=e[t].z;i[t]=Math.max(.02,t===0?n:n-e[t-1].z)}let a=[],o=[],s=[],c=[],l=[],u=[],d=[],f=[],p=[],m=[],h=new Float64Array(16),g=[],_=[],v=-1,y=0,b=0,x=0,S=-1,C=0,w=1e-4,T=(e,t,n,r,i,p)=>(a.push(e),o.push(t),s.push(n),u.push(r),c.push(i),l.push(p),d.push(C),f.push(!1),a.length-1);for(let t=0;t<n;t++){let n=e[t].paths,a=e[t].widths,o=i[t];if(C=t,n)for(let e=0;e<n.length;e+=8){let i=n[e+3],s=n[e],c=n[e+1],l=n[e+2],u=n[e+4],d=n[e+5],C=n[e+6];if(i===0){g.push(s,c,l,u,d,C),_.push(t);continue}let E=a&&a[e/8]>0?a[e/8]:r;i<16&&(h[i]+=Math.hypot(u-s,d-c));let D;v>=0&&S===i&&Math.abs(y-s)<w&&Math.abs(b-c)<w&&Math.abs(x-l)<w?(D=v,T(u,d,C,i,o,E)):(D=T(s,c,l,i,o,E),T(u,d,C,i,o,E)),f[D]=!0,v=D+1,y=u,b=d,x=C,S=i,p.push(D),m.push(t)}}let E=a.length,D=p.length,O=new Float32Array(E*4),k=new Float32Array(E*4),A=0,j=!1,M=1/0,N=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<E;e++){let t=c[e],n=a[e],r=o[e],i=s[e]-.5*t;O[e*4]=n,O[e*4+1]=r,O[e*4+2]=i;let d=e>0&&f[e-1],p=f[e],m=0;if(d||p){let t=d?a[e]-a[e-1]:0,n=d?o[e]-o[e-1]:0,r=d?s[e]-s[e-1]:0,i=p?a[e+1]-a[e]:0,c=p?o[e+1]-o[e]:0,l=p?s[e+1]-s[e]:0;m=Math.atan2(t*c-n*i,t*i+n*c+r*l)}k[e*4]=t,k[e*4+1]=l[e],k[e*4+2]=m,k[e*4+3]=F(P[u[e]]||P[1]),(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(m))&&(j=!0),A=Math.max(A,Math.abs(n),Math.abs(r),Math.abs(i)),n<M&&(M=n),n>L&&(L=n),r<N&&(N=r),r>R&&(R=r),i<I&&(I=i),i>z&&(z=i)}let B=new Uint32Array(D*4);for(let e=0;e<D;e++)B[e*4]=p[e],B[e*4+1]=m[e];let V={vType:new Uint8Array(E),vWidth:new Float32Array(E),vHeight:new Float32Array(E),vLayer:new Int32Array(E)};for(let e=0;e<E;e++)V.vType[e]=u[e],V.vWidth[e]=l[e],V.vHeight[e]=c[e],V.vLayer[e]=d[e];let H=new Int32Array(n+1);{let e=0;for(let t=0;t<n;t++){for(;e<D&&m[e]===t;)e++;H[t+1]=e}}let U=_.length,W=new Float32Array(U*6);for(let e=0;e<W.length;e++)W[e]=g[e];for(let e=0;e<W.length;e+=3){let t=W[e],n=W[e+1],r=W[e+2];t<M&&(M=t),t>L&&(L=t),n<N&&(N=n),n>R&&(R=n),r<I&&(I=r),r>z&&(z=r)}let G=new Int32Array(n+1);{let e=0;for(let t=0;t<n;t++){for(;e<U&&_[e]===t;)e++;G[t+1]=e}}let ee=E+U>0?{min:[M,N,I],max:[L,R,z]}:null;return{position:O,hwa:k,segIndex:B,nV:E,nSeg:D,layerSegPrefix:H,travelPos:W,travelPrefix:G,nTrav:U,layerCount:n,maxAbs:A,hasNaN:j,meta:V,typeLengths:h,bbox:ee}}var L=[[11,44,122],[19,89,133],[28,136,145],[4,214,15],[170,242,0],[252,249,3],[245,206,10],[227,136,32],[209,104,48],[194,82,60],[148,38,22]].map(e=>[e[0]/255,e[1]/255,e[2]/255]);function R(e,t,n,r){let i=r.length;if(!(n>t))return r[0];let a=(n-t)/(i-1),o=(e-t)/a,s=Math.max(0,Math.min(i-1,Math.floor(o))),c=Math.max(0,Math.min(i-1,s+1)),l=o-s,u=r[s],d=r[c];return[u[0]+(d[0]-u[0])*l,u[1]+(d[1]-u[1])*l,u[2]+(d[2]-u[2])*l]}var z=[{key:`feature`,label:`Feature type`,cont:!1,unit:``},{key:`speed`,label:`Speed`,cont:!0,unit:`mm/s`},{key:`height`,label:`Layer Height`,cont:!0,unit:`mm`},{key:`width`,label:`Line Width`,cont:!0,unit:`mm`},{key:`fan`,label:`Fan Speed`,cont:!0,unit:`%`},{key:`temp`,label:`Temperature`,cont:!0,unit:`°C`}];function B(e,t,n,r){let i=t.vType[n],a=t.vLayer[n],o=a===0;switch(e){case`height`:return t.vHeight[n];case`width`:return t.vWidth[n];case`speed`:return o?r.firstLayerSpeed:r.speedByType[i]??r.speedByType[1];case`fan`:return a<r.closeFanLayers?0:i===9?100:r.fanNormal;case`temp`:return o?r.tempFirst:r.tempNormal;default:return 0}}function V(e,t,n){let{meta:r,nV:i}=e,a=new Float32Array(i*4),o=z.find(e=>e.key===t)||z[0];if(!o.cont){for(let e=0;e<i;e++)a[e*4]=F(P[r.vType[e]]||P[1]);return{color:a,min:0,max:0,viewType:t,label:o.label,unit:o.unit,cont:!1}}let s=1/0,c=-1/0,l=new Float32Array(i);for(let e=0;e<i;e++){let i=B(t,r,e,n);l[e]=i,i<s&&(s=i),i>c&&(c=i)}Number.isFinite(s)||(s=0,c=1);for(let e=0;e<i;e++){let t=R(l[e],s,c,L);a[e*4]=F(t)}return{color:a,min:s,max:c,viewType:t,label:o.label,unit:o.unit,cont:!0}}var H=`
  3. precision highp float;
  4. precision highp int;
  5. precision highp sampler2D;
  6. precision highp usampler2D;
  7. #define POINTY_CAPS
  8. #define FIX_TWISTING
  9. const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);
  10. const float light_top_diffuse = 0.6 * 0.8;
  11. const float light_top_specular = 0.6 * 0.125;
  12. const float light_top_shininess = 20.0;
  13. const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);
  14. const float light_front_diffuse = 0.6 * 0.3;
  15. const float ambient = 0.3;
  16. const float emission = 0.15;
  17. const vec3 UP = vec3(0, 0, 1);
  18. uniform mat4 view_matrix;
  19. uniform mat4 projection_matrix;
  20. uniform vec3 camera_position;
  21. uniform sampler2D position_tex;
  22. uniform sampler2D height_width_angle_tex;
  23. uniform int layer_lo; // 25단계: 이중 슬라이더 하한(레이어). 범위 밖 세그먼트는 셰이더가 O(1) 클립.
  24. uniform int layer_hi; // 상한은 instanceCount 로 컷(레이어 순 정렬).
  25. in float vertex_id_float;
  26. in uint seg_id_a_u; // 인스턴스 어트리뷰트(구 segment_index_tex.r) — 어트리뷰트 fetch 가 texelFetch 보다 쌈
  27. in uint seg_layer_u; // 인스턴스 어트리뷰트(구 segment_index_tex.g)
  28. out vec3 color;
  29. vec3 decode_color(float col) {
  30. int c = int(round(col));
  31. int r = (c >> 16) & 0xFF;
  32. int g = (c >> 8) & 0xFF;
  33. int b = (c >> 0) & 0xFF;
  34. float f = 1.0 / 255.0;
  35. return f * vec3(r, g, b);
  36. }
  37. float lighting(vec3 eye_position, vec3 eye_normal) {
  38. float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);
  39. float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);
  40. float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);
  41. return ambient + top_diffuse + front_diffuse + top_specular + emission;
  42. }
  43. ivec2 tex_coord(sampler2D sampler, int id) {
  44. ivec2 tex_size = textureSize(sampler, 0);
  45. return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);
  46. }
  47. void main() {
  48. int vertex_id = int(vertex_id_float);
  49. int seg_layer = int(seg_layer_u);
  50. if (seg_layer < layer_lo || seg_layer > layer_hi) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; } // 범위 밖 → 클립
  51. int id_a = int(seg_id_a_u);
  52. int id_b = id_a + 1;
  53. vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;
  54. vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_b), 0).xyz;
  55. vec3 line = pos_b - pos_a;
  56. float line_len = length(line);
  57. vec3 line_dir;
  58. if (line_len < 1e-4)
  59. line_dir = vec3(1.0, 0.0, 0.0);
  60. else
  61. line_dir = line / line_len;
  62. vec3 line_right_dir;
  63. if (abs(dot(line_dir, UP)) > 0.9) {
  64. line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));
  65. }
  66. else
  67. line_right_dir = normalize(cross(line_dir, UP));
  68. vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));
  69. const vec2 horizontal_vertical_view_signs_array[16] = vec2[](
  70. vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, 0.0), vec2(0.0, -1.0),
  71. vec2(0.0, -1.0), vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, 0.0),
  72. vec2(0.0, 1.0), vec2(-1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 0.0),
  73. vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(-1.0, 0.0), vec2(0.0, 0.0)
  74. );
  75. int id = vertex_id < 4 ? id_a : id_b;
  76. vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;
  77. vec4 hwa_color = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0); // .xyz=h/w/angle, .w=packed color
  78. vec3 height_width_angle = hwa_color.xyz;
  79. #ifdef FIX_TWISTING
  80. int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;
  81. vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;
  82. vec3 camera_view_dir = normalize(closer_pos - camera_position);
  83. vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, closer_id), 0).xyz;
  84. vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);
  85. #else
  86. vec3 camera_view_dir = normalize(endpoint_pos - camera_position);
  87. vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);
  88. #endif
  89. bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >
  90. abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));
  91. vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];
  92. #ifndef POINTY_CAPS
  93. if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];
  94. #endif
  95. float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));
  96. float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));
  97. float half_height = 0.5 * height_width_angle.x;
  98. float half_width = 0.5 * height_width_angle.y;
  99. vec3 horizontal_dir = half_width * line_right_dir;
  100. vec3 vertical_dir = half_height * line_up_dir;
  101. float horizontal_sign = signs.x * view_right_sign;
  102. float vertical_sign = signs.y * view_top_sign;
  103. vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;
  104. if (vertex_id == 2 || vertex_id == 7) {
  105. float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;
  106. if (height_width_angle.z == 0.0) {
  107. #ifdef POINTY_CAPS
  108. pos += line_dir_sign * line_dir * half_width;
  109. #endif
  110. }
  111. else {
  112. pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);
  113. pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);
  114. }
  115. }
  116. vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;
  117. vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;
  118. vec3 color_base = decode_color(hwa_color.w);
  119. color = color_base * lighting(eye_position, eye_normal);
  120. gl_Position = projection_matrix * vec4(eye_position, 1.0);
  121. }
  122. `,U=`
  123. precision highp float;
  124. in vec3 color;
  125. out vec4 fragment_color;
  126. void main() {
  127. fragment_color = vec4(color, 1.0);
  128. }
  129. `;function W(e,t){let n=(t,n)=>{let r=Math.min(2048,Math.max(1,n)),i=Math.max(1,Math.ceil(n/r)),a=new Float32Array(r*i*4);a.set(t.subarray(0,Math.min(t.length,r*i*4)));let o=new e.DataTexture(a,r,i,e.RGBAFormat,e.FloatType);return o.minFilter=o.magFilter=e.NearestFilter,o.generateMipmaps=!1,o.needsUpdate=!0,o},r=n(t.position,t.nV),i=n(t.hwa,t.nV),a=new e.InstancedBufferGeometry;a.setIndex(N),a.setAttribute(`position`,new e.BufferAttribute(new Float32Array(24),3)),a.setAttribute(`vertex_id_float`,new e.BufferAttribute(new Float32Array([0,1,2,3,4,5,6,7]),1));let o=new e.InstancedInterleavedBuffer(t.segIndex,4);a.setAttribute(`seg_id_a_u`,new e.InterleavedBufferAttribute(o,1,0)),a.setAttribute(`seg_layer_u`,new e.InterleavedBufferAttribute(o,1,1)),a.instanceCount=0;let s=new e.RawShaderMaterial({glslVersion:e.GLSL3,uniforms:{view_matrix:{value:new e.Matrix4},projection_matrix:{value:new e.Matrix4},camera_position:{value:new e.Vector3},position_tex:{value:r},height_width_angle_tex:{value:i},layer_lo:{value:0},layer_hi:{value:t.layerCount}},vertexShader:H,fragmentShader:U,side:e.DoubleSide}),c=new e.Mesh(a,s),l=null;if(t.bbox){let{min:n,max:r}=t.bbox,i=new e.Vector3((n[0]+r[0])/2,(n[1]+r[1])/2,(n[2]+r[2])/2),a=Math.hypot(r[0]-n[0],r[1]-n[1],r[2]-n[2])/2+2;l=new e.Sphere(i,a)}c.frustumCulled=!!l,l&&(a.boundingSphere=l);let u=new e.Matrix4,d=new e.Vector3;c.onBeforeRender=(e,t,n)=>{s.uniforms.projection_matrix.value.copy(n.projectionMatrix),s.uniforms.view_matrix.value.multiplyMatrices(n.matrixWorldInverse,c.matrixWorld),u.copy(c.matrixWorld).invert(),n.getWorldPosition(d).applyMatrix4(u),s.uniforms.camera_position.value.copy(d)};let f=new e.BufferGeometry;f.setAttribute(`position`,new e.BufferAttribute(t.travelPos,3)),f.setDrawRange(0,0);let p=new e.LineSegments(f,new e.LineBasicMaterial({color:7041658}));p.frustumCulled=!!l,p.visible=!1,l&&(f.boundingSphere=l);let m=!1,h=0,g=t.layerCount-1,_=()=>{let e=t.travelPrefix[h],n=t.travelPrefix[g+1];f.setDrawRange(m?e*2:0,m?(n-e)*2:0)},v=(e,n)=>{let r=t.layerCount;h=Math.max(0,Math.min(r-1,e|0)),g=Math.max(h,Math.min(r-1,n|0)),s.uniforms.layer_lo.value=h,s.uniforms.layer_hi.value=g,a.instanceCount=t.layerSegPrefix[g+1],_()};return{mesh:c,travLines:p,setVisibleLayers:e=>v(0,(e|0)-1),setLayerRange:v,setTravelVisible:e=>{m=!!e,p.visible=m,_()},setColors:e=>{let t=i.image.data,n=Math.min(e.length,t.length)/4;for(let r=0;r<n;r++)t[r*4+3]=e[r*4];i.needsUpdate=!0},dispose:()=>{a.dispose(),s.dispose(),r.dispose(),i.dispose(),f.dispose(),p.material.dispose()},nSeg:t.nSeg,layerCount:t.layerCount}}var G=t(),ee=[`filament`,`feature`,`height`,`width`],te=[{type:b.wall,key:`gcodeViewer.feature.wall`,fallback:`Walls`},{type:b.sparseInfill,key:`gcodeViewer.feature.sparseInfill`,fallback:`Sparse infill`},{type:b.solidInfill,key:`gcodeViewer.feature.solidInfill`,fallback:`Solid infill`},{type:b.bridge,key:`gcodeViewer.feature.bridge`,fallback:`Bridge / overhang`},{type:b.support,key:`gcodeViewer.feature.support`,fallback:`Support`},{type:b.skirt,key:`gcodeViewer.feature.skirt`,fallback:`Skirt / brim`},{type:b.gapFill,key:`gcodeViewer.feature.gapFill`,fallback:`Gap fill`},{type:b.ironing,key:`gcodeViewer.feature.ironing`,fallback:`Ironing`},{type:b.primeTower,key:`gcodeViewer.feature.primeTower`,fallback:`Prime tower`}];function ne(e){let t=e.replace(`#`,``),n=t.length===3?t.split(``).map(e=>e+e).join(``):t,r=Number.parseInt(n.slice(0,6),16);return Number.isFinite(r)?r:44610}var re=e=>e?`rgb(${e.map(e=>Math.round(e*255)).join(`,`)})`:`transparent`;function ie(){let e=L;return e.map((t,n)=>`${re(t)} ${(n/(e.length-1)*100).toFixed(0)}%`).join(`, `)}function ae(e){return Number.isFinite(e)?Math.abs(e)<10?e.toFixed(2):e.toFixed(0):`-`}function oe({gcodeUrl:e,buildVolume:t={x:256,y:256,z:256},filamentColors:n,className:a=``}){let{t:b}=i(),x=(0,y.useRef)(null),[S,C]=(0,y.useState)(!0),[w,T]=(0,y.useState)(null),[E,D]=(0,y.useState)(!1),[O,k]=(0,y.useState)(null),N=(n?.length??0)>0,[F,L]=(0,y.useState)(N?`filament`:`feature`),R=(0,y.useRef)(!1);(0,y.useEffect)(()=>{N&&!R.current&&L(`filament`)},[N]);let[z,B]=(0,y.useState)([0,0]),[H,U]=(0,y.useState)(new Set),[oe,se]=(0,y.useState)(new Set),K=F===`filament`,q=K?oe:H,ce=[...q].sort((e,t)=>e-t).join(`,`),le=e=>{let t=t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n};K?se(t):U(t)},[J,ue]=(0,y.useState)(!1),Y=(0,y.useRef)(null),X=(0,y.useRef)(null),de=(0,y.useRef)(null),Z=(0,y.useRef)(null),fe=(0,y.useRef)(null),[pe,me]=(0,y.useState)(0),he=(0,y.useRef)(J),ge=(0,y.useRef)(z);he.current=J,ge.current=z;let _e=(0,y.useRef)(!1),Q=(0,y.useMemo)(()=>({x:t.x,y:t.y,z:t.z}),[`${t.x}x${t.y}x${t.z}`]);(0,y.useEffect)(()=>{let t=!1;C(!0),T(null),D(!1),k(null);let n={},i=r();return i&&(n.Authorization=`Bearer ${i}`),fetch(e,{headers:n}).then(async e=>{if(!e.ok){if(e.status===404){let t=await e.json().catch(()=>({}));if(typeof t.detail==`string`&&t.detail.includes(`sliced`))throw D(!0),Error(`not_sliced`)}throw Error(`Failed to load G-code`)}return e.text()}).then(e=>{if(t)return;_e.current=!1;let n=A(e);k(n),B([0,Math.max(0,n.layers.length-1)]),C(!1)}).catch(e=>{t||(e.message!==`not_sliced`&&T(e.message),C(!1))}),()=>{t=!0}},[e]),(0,y.useEffect)(()=>{let e=x.current;if(!e)return;let t=e.clientWidth||1,n=e.clientHeight||1,r=new c;r.background=new f(1710618),Y.current=r;let i=new _(45,t/n,.1,1e4);X.current=i;let a=new h({antialias:!0});a.setSize(t,n),a.setPixelRatio(Math.min(window.devicePixelRatio,2)),a.domElement.style.display=`block`,a.domElement.style.position=`absolute`,a.domElement.style.inset=`0`,e.appendChild(a.domElement);let o=new g(i,a.domElement);o.enableDamping=!0,o.dampingFactor=.05,de.current=o;let s=new m(Math.max(Q.x,Q.y),Math.ceil(Math.max(Q.x,Q.y)/16),4473924,3355443);s.position.set(Q.x/2,0,-Q.y/2),r.add(s);let l=0,u=()=>{l=requestAnimationFrame(u),o.update(),a.render(r,i)};u();let d=()=>{let t=e.clientWidth||1,n=e.clientHeight||1;i.aspect=t/n,i.updateProjectionMatrix(),a.setSize(t,n)},p=new ResizeObserver(d);return p.observe(e),window.addEventListener(`resize`,d),()=>{window.removeEventListener(`resize`,d),p.disconnect(),cancelAnimationFrame(l),o.dispose(),s.geometry.dispose(),s.material.dispose(),a.dispose(),e.removeChild(a.domElement),Y.current=null,X.current=null,de.current=null}},[Q]),(0,y.useEffect)(()=>{let e=Y.current,t=X.current,n=de.current;if(!e||!t||!n||!O||O.layers.length===0)return;let r=I(M(K?j(O.layers):O.layers,q),O.defaultWidth),i=W(d,r);fe.current=r,Z.current=i;let a=new p;if(a.rotation.x=-Math.PI/2,a.add(i.mesh),a.add(i.travLines),e.add(a),i.setTravelVisible(he.current),i.setLayerRange(ge.current[0],ge.current[1]),me(e=>e+1),!_e.current){_e.current=!0;let e=O.bounds,r=e?new u(new s(e.min[0],e.min[2],-e.max[1]),new s(e.max[0],e.max[2],-e.min[1])):new u(new s(0,0,0),new s(Q.x,1,-Q.y)),i=r.getCenter(new s),a=Math.max(r.getSize(new s).length()/2,.001),o=l.degToRad(t.fov),c=2*Math.atan(Math.tan(o/2)*t.aspect),d=1.15*Math.max(a/Math.sin(o/2),a/Math.sin(c/2));t.position.copy(i).addScaledVector(new s(.7,.5,.7).normalize(),d),t.near=Math.max(d/1e3,.01),t.far=d+a*4,t.updateProjectionMatrix(),n.target.copy(i),n.update()}return()=>{e.remove(a),i.dispose(),Z.current=null,fe.current=null}},[O,K,Q,ce]),(0,y.useEffect)(()=>{Z.current?.setLayerRange(z[0],z[1])},[z]),(0,y.useEffect)(()=>{Z.current?.setTravelVisible(J)},[J]);let $=(0,y.useMemo)(()=>{let e=fe.current;if(!e||!O)return null;if(K){let t=new Float32Array(e.nV*4);for(let r=0;r<e.nV;r+=1){let i=Math.max(0,e.meta.vType[r]-1),a=n?.[i]??n?.[0]??`#00ae42`;t[r*4]=ne(a)}return{color:t,min:0,max:0,unit:``,cont:!1}}return V(e,F,{})},[F,O,K,n,pe]);(0,y.useEffect)(()=>{$&&Z.current?.setColors($.color)},[$]);let ve=O?.layers.length??0;return E?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 text-bambu-gray ${a}`,children:[(0,G.jsx)(v,{className:`w-8 h-8`}),b(`gcodeViewer.notSliced`,`This file has not been sliced yet.`)]}):w?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 text-bambu-gray ${a}`,children:[(0,G.jsx)(v,{className:`w-8 h-8`}),b(`gcodeViewer.loadFailed`,`Could not load the G-code for this file.`)]}):(0,G.jsxs)(`div`,{className:`relative ${a}`,children:[(0,G.jsx)(`div`,{ref:x,className:`absolute inset-0`}),S&&(0,G.jsxs)(`div`,{className:`absolute inset-0 flex items-center justify-center gap-2 bg-bambu-dark/60 text-sm text-bambu-gray`,children:[(0,G.jsx)(o,{className:`w-4 h-4 animate-spin`}),b(`gcodeViewer.loading`,`Reading toolpath...`)]}),!S&&ve>0&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`absolute left-3 top-3 flex flex-col gap-2 rounded border border-bambu-dark-tertiary bg-bambu-dark/85 p-2`,children:[(0,G.jsx)(`div`,{className:`flex overflow-hidden rounded border border-bambu-dark-tertiary`,children:ee.filter(e=>e!==`filament`||N).map(e=>(0,G.jsx)(`button`,{type:`button`,onClick:()=>{R.current=!0,L(e)},className:`px-2 py-1 text-xs transition-colors ${F===e?`bg-bambu-green text-white`:`text-bambu-gray hover:text-white`}`,children:b(`gcodeViewer.view.${e}`,e)},e))}),(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-xs text-bambu-gray`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:J,onChange:e=>ue(e.target.checked),className:`cursor-pointer`}),b(`gcodeViewer.showTravel`,`Travel moves`)]}),K?(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:(n??[]).map((e,t)=>{let n=t+1,r=q.has(n);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,onClick:()=>le(n),"aria-pressed":!r,className:`flex w-full items-center gap-1.5 text-left text-[0.7rem] transition-opacity hover:text-white ${r?`text-bambu-gray/40`:`text-bambu-gray`}`,children:[(0,G.jsx)(`span`,{className:`inline-block h-2.5 w-2.5 shrink-0 rounded-sm border border-white/20 ${r?`opacity-25`:``}`,style:{backgroundColor:e},"aria-hidden":!0}),(0,G.jsx)(`span`,{className:r?`line-through`:``,children:b(`gcodeViewer.filamentSlot`,`Filament {{n}}`,{n:t+1})})]})},t)})}):F===`feature`?(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:te.map(e=>{let t=q.has(e.type);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,onClick:()=>le(e.type),"aria-pressed":!t,className:`flex w-full items-center gap-1.5 text-left text-[0.7rem] transition-opacity hover:text-white ${t?`text-bambu-gray/40`:`text-bambu-gray`}`,children:[(0,G.jsx)(`span`,{className:`inline-block h-2.5 w-2.5 shrink-0 rounded-sm ${t?`opacity-25`:``}`,style:{backgroundColor:re(P[e.type])},"aria-hidden":!0}),(0,G.jsx)(`span`,{className:t?`line-through`:``,children:b(e.key,e.fallback)})]})},e.type)})}):$&&(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`div`,{className:`h-2.5 w-full rounded-sm border border-white/10`,style:{background:`linear-gradient(to right, ${ie()})`},"aria-hidden":!0}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-[0.7rem] tabular-nums text-bambu-gray`,children:[(0,G.jsx)(`span`,{children:ae($.min)}),(0,G.jsx)(`span`,{className:`text-bambu-gray/70`,children:$.unit}),(0,G.jsx)(`span`,{children:ae($.max)})]})]})]}),(0,G.jsxs)(`div`,{className:`absolute right-3 top-3 flex flex-col items-center gap-1 rounded border border-bambu-dark-tertiary bg-bambu-dark/85 p-2`,children:[(0,G.jsx)(`span`,{className:`text-[0.65rem] tabular-nums text-bambu-gray`,children:z[1]+1}),(0,G.jsx)(`input`,{type:`range`,min:0,max:Math.max(0,ve-1),value:z[1],onChange:e=>{let t=Number(e.target.value);B(([e])=>[Math.min(e,t),t])},"aria-label":b(`gcodeViewer.topLayer`,`Top layer`),className:`h-40 w-4 cursor-pointer`,style:{writingMode:`vertical-lr`,direction:`rtl`}}),(0,G.jsx)(`input`,{type:`range`,min:0,max:Math.max(0,ve-1),value:z[0],onChange:e=>{let t=Number(e.target.value);B(([,e])=>[t,Math.max(t,e)])},"aria-label":b(`gcodeViewer.bottomLayer`,`Bottom layer`),className:`h-40 w-4 cursor-pointer`,style:{writingMode:`vertical-lr`,direction:`rtl`}}),(0,G.jsx)(`span`,{className:`text-[0.65rem] tabular-nums text-bambu-gray`,children:z[0]+1})]})]})]})}export{oe as t};