memoscan
← all memos

Memo 0x073d09cd…3b6c87 on Ethereum

= clamp(\n (step(lineDistance, alphaSoftLineSpread) * alphaSoftLineNoise) * maxLineHardness,\n 0., .7);\n }\n \n\n float lineAlpha = max(alphaSoftLine, alphaHardLine) * segmentDistanceAlphaMult;\n \n accumulationValue = clamp(accumulationValue + (1.0 - accumulationValue) * lineAlpha * 0.1, 0., 5.);\n \n alpha = clamp(1.0 - (1.0 - alpha) * (1.0 - lineAlpha * alphaIncrement), 0., 1.);\n color.x = clamp(\n 1.0 - (1.0 - localColor.x) * (1.0 - lineAlpha * lightnessIncrement), \n originalColor.x - accumulationClamp.x, \n originalColor.x + accumulationClamp.x\n );\n if(!uDisableSaturationShift) {\n color.y = clamp(1.0 - (1.0 - localColor.y) * (1.0 - lineAlpha * chromaIncrement), \n originalColor.y - accumulationClamp.y, \n originalColor.y + accumulationClamp.y\n );\n }\n \n \n }\n\n if(alpha <= 0.) {\n return vec4(frameBuffer, 1.);\n }\n\n\n float brightnessNoiseInfluence = smoothstep(-1., 1., fbm(uv + uNoiseOffset, 2, 50., 0.9)) + 0.4;\n float brightnessNoise = smoothstep(0.1, 0.31, fbm(uv + uNoiseOffset, 2, 1800., 0.5)) * brightnessNoiseInfluence * 0.002;\n color.x += brightnessNoise;\n\n float alphaNoise2 = smoothstep(-1., 1., fbm(uv, 1, 1000., 0.1)) * 0.02;\n float alphaNoise = smoothstep(-0.6, 1., fbm(uv, 2, 1200., 0.1)) * 0.12;\n alpha -= (alphaNoise + alphaNoise2);\n alpha = clamp(alpha, 0., 1.);\n\n \n float colorBrightWobble = fbm(uv + uNoiseOffset, 2, 20., 0.9) * 0.001;\n float colorEase = (\n easeOut(smoothstep(.02, .0, sdf + colorBrightWobble), 1.) \n * (0.01 + (accumulationValue * 0.02))\n );\n\n float colorBrightNoise = smoothstep(-0.4, 0.4, fbm(uv + uNoiseOffset, 2, 700., 0.9));\n float darkenEdge = easeOut(smoothstep(.0035, .0, sdf - (colorBrightWobble * 4.)), 1.) \n * (0.06 + (accumulationValue * 0.02)) * colorBrightNoise;\n\n colorEase += darkenEdge;\n \n color.x -= colorEase;\n color.y += (colorEase * 0.4);\n\n color.x = clamp(color.x, 0., .84);\n color.y = clamp(color.y, 0., .4); \n\n // LIGHTING\n vec3 lightDir = normalize(vec3(.6f, 1.6f, 1.6f));\n vec3 lightColor = vec3(1.0f) * 1.7f;\n \n vec3 paperTextureNormals = calculateNormals(screenSpaceUV + msaaOffset, 0.0002 * tileScaleFactor.x, 4.);\n vec3 diffuse = calculateDiffuse(paperTextureNormals, lightDir, lightColor);\n\n vec3 colorRGB = OKLCHtoP3LRGB(color) * diffuse;\n vec3 colorMult = (frameBuffer * colorRGB) * diffuse;\n\n colorRGB = mix(frameBuffer, mix(colorMult, colorRGB * diffuse, clamp(0.9, 1., alpha + 0.3)), alpha);\n\n return vec4(colorRGB, 1.0);\n }\n\n void main() {\n const vec2 H2 = vec2(0.5698402909980532f, 0.7548776662466927f);\n vec2 px = 1.f / resolution;\n px *= 1.25;\n vec2 uv = vUv;\n\n \n // Check if this fragment is within the SDF\n vec2 uvOffset = lookupWarpSample(uv).xy;\n float texCheck = (texture(tPolyEdgeDistance, uv + uvOffset).r - 0.5) * 2.0;\n if(texCheck < -0.1) {\n discard;\n }\n\n vec3 frameBuffer = texture(tScreenBuffer, vUv).rgb;\n\n\n const float samples = 4.f;\n \n vec4 sumColour;\n vec2 d0 = vec2(randomNonDet(uv), randomNonDet(uv + 1.f));\n\n \n for(float i = 0.f; i < samples; i++) {\n vec2 d = (fract(i * H2 + d0) - .5f);\n\n vec2 localCoord = vUv + d * px;\n vec2 screenCoord = uTileOffset + localCoord * uTileSize;\n vec2 globalUV = screenCoord / resolution;\n\n \n vec4 sampleColor = render(globalUV, vUv, d * px, frameBuffer);\n sumColour += sampleColor;\n }\n \n vec4 averageColor = clamp(sumColour / samples, 0., 1.);\n \n outColor = averageColor;\n }\n `});let n=t.isShading?nn:ln;n.updatePolylines(t.lines,t.closedPolyOrLine);let l=tn.uniforms;re(tn),It.material=tn,l.tScreenBuffer.value=Ft.getReadBuffer().texture;let i=t.lineColor;if(l.uLineColor.value=Qt(i),l.uDisableSaturationShift.value=t.disableSaturationShift||!1,l.uLineWeight.value=t.lineWeight,l.uLineHardness.value=t.linePressure,l.uMaterialHardness.value=t.materialHardness||1,l.uIsShading.value=t.isShading||!1,l.tWarpTex.value=t.canWarp?Ht.displacementMapWarped.target.texture:Ht.displacementMap.target.texture,l.uNoiseOffset.value=new ie(...t.noiseOffset),l.uFaceIndex.value=an++,l.uLineWeight.value=t.lineWeight,l.uTaperingFadeIn.value=t.lineTapering.fade.in.enabled?t.lineTapering.fade.in.length:0,l.uTaperingFadeOut.value=t.lineTapering.fade.out.enabled?t.lineTapering.fade.out.length:0,l.uTaperingScaleIn.value=t.lineTapering.scale.in.enabled?t.lineTapering.scale.in.length:0,l.uTaperingScaleOut.value=t.lineTapering.scale.out.enabled?t.lineTapering.scale.out.length:0,l.uBrightness.value=t.lineBrightness||1,l.uEdgeSharpness.value=t.edgeSharpness||1,l.uAccumulationStrength.value=t.accumulationStrength||1,t?.fadeAtLineSegment){let e=_t(t.fadeAtLineSegment.segment);const n=l.uFadeAtLineSegmentVertices.value;n[0]=e[0][0],n[1]=e[0][1],n[2]=e[1][0],n[3]=e[1][1],l.uFadeAtLineSegmentDistance.value=t.fadeAtLineSegment.distance,l.uFadeAtLineSegmentStrength.value=t.fadeAtLineSegment.strength,l.uEnableFadeAtLineSegment.value=!0,tn.needsUpdate=!0}else l.uEnableFadeAtLineSegment.value=!1;if(!sn||on!==n){const{cellsWide:e,cellsHigh:t,cellSize:i}=n,{segmentDataTexture:a,segmentMetaDataTexture:s,segmentIndexTexture:o}=n.getTextures();l.uSegmentDataTex.value=a,l.uSegmentMetaDataTex.value=s,l.uSegmentIndexTex.value=o,l.tPolyLineGrid.value={width:e*i,height:t*i,cellSize:i},sn=!0}l.uIsClosedPoly.value=t.closedPolyOrLine,X.setRenderTarget(Ft.getWriteBuffer()),It.render(),Ft.copyAndSwapBuffers(),on=n}let cn=new e.Vector4;class dn{minX=1/0;minY=1/0;maxX=-1/0;maxY=-1/0;constructor(){}get width(){return this.maxX-this.minX}get height(){return this.maxY-this.minY}get center(){return new Ut((this.minX+this.maxX)/2,(this.minY+this.maxY)/2)}get vertexList(){return[new Ut(this.minX,this.minY),new Ut(this.maxX,this.minY),new Ut(this.maxX,this.maxY),new Ut(this.minX,this.maxY)]}get area(){return this.width*this.height}reset(){this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0}expand(e){this.minX=Math.min(e.x,this.minX),this.minY=Math.min(e.y,this.minY),this.maxX=Math.max(e.x,this.maxX),this.maxY=Math.max(e.y,this.maxY)}expands(e){for(let t=0,n=e.length;t<n;t++)this.expand(e[t]);return this}expandByPoint(e){return this.minX=Math.min(e[0],this.minX),this.minY=Math.min(e[1],this.minY),this.maxX=Math.max(e[0],this.maxX),this.maxY=Math.max(e[1],this.maxY),this}expandsByPoint(e){for(let t=0,n=e.length;t<n;t++)this.expandByPoint(e[t])}intersects(e,t=g){return!(e.maxX<this.minX-t||e.minX>this.maxX+t||e.maxY<this.minY-t||e.minY>this.maxY+t)}expandByValue(e){return this.minX-=e,this.minY-=e,this.maxX+=e,this.maxY+=e,this}containsPoint(e){return e.x<=this.maxX+g&&e.x>=this.minX-g&&e.y<=this.maxY+g&&e.y>=this.minY-g}distanceToPoint(e){const t=r(this.minX-e.x,0,e.x-this.maxX),n=r(this.minY-e.y,0,e.y-this.maxY);return d(t*t+n*n)}containsBB(e){return e.minX>=this.minX-g&&e.maxX<=this.maxX+g&&e.minY>=this.minY-g&&e.maxY<=this.maxY+g}containsPoints(e){for(let t=0,n=e.length;t<n;t++)if(!this.containsPoint(e[t]))return!1;return!0}size(){return{width:this.maxX-this.minX,height:this.maxY-this.minY}}}let un,hn=[];var mn,pn;function bn(l){un=un||new e.ShaderMaterial({uniforms:{resolution:{value:new e.Vector2(Q,j)},tPositions:{value:new e.DataTexture},uPositionsCount:{value:0},...ce()},colorWrite:!0,depthWrite:!1,depthTest:!1,glslVersion:e.GLSL3,vertexShader:le,fragmentShader:`\n precision highp float;\n\t\t\tprecision highp int;\n \n uniform highp sampler2D tPositions;\n uniform vec2 resolution;\n uniform int uPositionsCount;\n uniform vec2 uTileOffset;\n uniform vec2 uTileSize;\n \n varying vec2 vUv;\n out vec4 outColor;\n\n ${ne}\n\n float pointLineSegSDF(vec2 p, vec2 a, vec2 b) {\n vec2 pa = p - a;\n vec2 ba = b - a;\n float t = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);\n return length(pa - ba * t);\n }\n \n bool isIntersecting(vec2 point, vec2 p1, vec2 p2) {\n if(p1.y == p2.y) {\n return false;\n }\n \n if(p1.y > point.y && p2.y > point.y) {\n return false;\n }\n \n if(p1.y < point.y && p2.y < point.y) {\n return false;\n }\n \n float intersectionX = p1.x + (point.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y);\n return intersectionX > point.x;\n }\n\n vec2 fetchVertex(int vertexIndex) {\n int textureWidth = textureSize(tPositions, 0).x;\n int x = vertexIndex % textureWidth;\n int y = vertexIndex / textureWidth;\n return texelFetch(tPositions, ivec2(x, y), 0).rg;\n }\n \n float polyDistanceSDF(vec2 uv) {\n float minDist = 1e20;\n int intersections = 0;\n \n for(int i = 0; i < uPositionsCount; i++) {\n vec2 vertex1 = fetchVertex(i) / resolution.xy;\n vec2 vertex2 = fetchVertex((i + 1) % uPositionsCount) / resolution.xy;\n \n minDist = min(minDist, pointLineSegSDF(uv, vertex1, vertex2));\n \n if(isIntersecting(uv, vertex1, vertex2)) {\n intersections++;\n }\n }\n return float(intersections % 2 == 1 ? minDist : -minDist);\n // return float(intersections % 2 == 1 ? minDist : 1.5);\n }\n \n vec4 render(vec2 uv) {\n float dist = polyDistanceSDF(uv);\n return vec4(dist) * 0.5 + .5;\n }\n \n\n void main() {\n // A pseudo-random distribution for multi-sample\n const vec2 H2 = vec2(0.56984029, 0.75487766);\n // We do sub-pixel offsets relative to tile size, \n // because each tile is scaled to fill the entire local canvas\n vec2 px = 1.0 / resolution.xy;\n px *= 1.25;\n\n // We'll accumulate color across multiple samples\n const float samples = 4.0;\n vec4 sumColour = vec4(0.0);\n \n // Vary the random offset per pixel\n vec2 d0 = vec2(randomNonDet(vUv), randomNonDet(vUv + 1.0));\n\n for (float i = 0.0; i < samples; i++) {\n vec2 d = fract(i * H2 + d0) - 0.5;\n // localCoord in [0..1] in the local canvas\n vec2 sampleCoord = vUv + d * px;\n\n // Now map that to the large “full” coordinate space \n // subregion given by uTileOffset..uTileOffset+uTileSize\n vec2 screenCoord = uTileOffset + sampleCoord * uTileSize;\n\n // Next convert to [0..1] over the entire original geometry\n vec2 globalUV = screenCoord / resolution;\n\n vec4 sampleColor = render(globalUV);\n sumColour += sampleColor;\n }\n\n vec4 finalColor = clamp(sumColour / samples, 0.0, 1.0);\n outColor = finalColor;\n }\n `});let i=_t(l.polygon);un.uniforms.uPositionsCount.value=i.length;let a=function(t){const l=t.flat(),i=l.length/2,a=o(C,i),s=n(i/C),r=new Float32Array(a*s*2);for(let e=0;e<i;e++){const t=2*e;r[t]=l[t]||0,r[t+1]=l[t+1]||0}let c=new e.DataTexture(r,a,s,e.RGFormat,e.FloatType);return c.needsUpdate=!0,{texture:c,width:a,height:s}}(i);un.uniforms.tPositions.value=a.texture,re(un),It.material=un,X.setRenderTarget(Ht.polyEdgeDistance.target),X.setClearColor(1,0),X.clear();let s=oe();var c;((e,l=5)=>{l/=D,X.setScissorTest(!0),X.setScissor(((e,l=5)=>{let i=l*D,a=o(...e.map((e=>e.x)))-i,s=r(...e.map((e=>e.x)))+i,c=o(...e.map((e=>e.y)))-i,d=r(...e.map((e=>e.y)))+i,u=s-a,h=d-c;return cn.set(Ze(t(a),0,Q),Ze(t(j-d),0,j),n(o(u,Q)),n(o(h,j))).divideScalar(U).round()})(e,l))})((c=l.polygon.map((e=>new ie(e.x,e.y))),c.map((e=>e.clone().multiplyScalar(D)))).map((e=>(e.x=t((e.x-s.xOff)*(Q/s.width)),e.y=n((e.y-s.yOff)*(j/s.height)),e))),n(10*D*(Q/s.width))),It.render(),X.setScissorTest(!1)}!function(e){e[e.constructionLine=0]="constructionLine",e[e.detail=1]="detail",e[e.foreground=2]="foreground",e[e.background=3]="background",e[e.shadow=4]="shadow",e[e.walker=5]="walker",e[e.overlay=6]="overlay",e[e.overlayOutline=7]="overlayOutline"}(mn||(mn={})),function(e){e[e.regular=0]="regular",e[e.warped=1]="warped"}(pn||(pn={}));const gn=4095,fn=e=>.5*(1-i(e*b));let xn;function Zn(e){xn=new Float32Array(4096);for(let e=0;e<4096;e++)xn[e]=J.dec()}let yn=(e,n,l=0,i=5,a=0,s=1)=>fe(function(e,n=0,l=0){xn||Zn(),e<0&&(e=-e),n<0&&(n=-n),l<0&&(l=-l);let i,a,s,o,r,c=t(e),d=t(n),u=t(l),h=e-c,m=n-d,p=l-u,b=0,g=.5;for(let e=0;e<3;e++){let e=c+(d<<4)+(u<<8);i=fn(h),a=fn(m),s=xn[e&gn],s+=i*(xn[e+1&gn]-s),o=xn[e+16&gn],o+=i*(xn[e+16+1&gn]-o),s+=a*(o-s),e+=256,o=xn[e&gn],o+=i*(xn[e+1&gn]-o),r=xn[e+16&gn],r+=i*(xn[e+16+1&gn]-r),o+=a*(r-o),s+=fn(p)*(o-s),b+=s*g,g*=.8,c<<=1,h*=2,d<<=1,m*=2,u<<=1,p*=2,h>=1&&(c++,h--),m>=1&&(d++,m--),p>=1&&(u++,p--)}return b}((e+100)/i,(n+100)/i,(l+100)/i),0,1,a,s);const Gn=g;var Wn;function vn(e,t,n=!1){if(0===t.length)return e;if(1===t.length)return t[0];let l,i=1/0,a=n?t.length:t.length-1;for(let n=0;n<a;n++){const a=t[n],s=t[(n+1)%t.length],o=Sn(e,a,s);o<i&&(i=o,l=[a,s])}return l?function(e,t,n){const[l,i]=t,[a,s]=n,[o,r]=e,c=a-l,d=s-i,u=c*c+d*d;if(u<Gn)return[l,i];let h=((o-l)*c+(r-i)*d)/u;return h<-1e-7?h=0:h>1+Gn&&(h=1),[l+h*c,i+h*d]}(e,...l):e}function Ln(e,t,n=!1){let l=1/0;const i=t.length,a=n?i:i-1;for(let n=0;n<a;n++){const a=Xn(e,t[n],n===i-1?t[0]:t[n+1]);if(a<Gn)return 0;l=Math.min(l,a)}return Math.sqrt(l)}function Sn(e,t,n){return d(Xn(e,t,n))}function Xn(e,t,n){const[l,i]=t,[a,s]=n,[o,r]=e,c=a-l,d=s-i,u=c*c+d*d;if(u<Gn){const e=o-l,t=r-i;return e*e+t*t}let h=((o-l)*c+(r-i)*d)/u;h<-1e-7?h=0:h>1+Gn&&(h=1);const m=o-(l+h*c),p=r-(i+h*d);return m*m+p*p}!function(e){e[e.intersecting=0]="intersecting",e[e.colinear=1]="colinear",e[e.parallel=2]="parallel"}(Wn||(Wn={}));let Cn=0;class Vn{v1;v2;id=Cn++;origin;angle;length;twin=null;nexthedge=null;prevhedge=null;face=null;constructor(e,t){this.v1=e,this.v2=t,this.id=Cn++,this.origin=t,this.angle=function(e,t){let n=t.x-e.x,l=t.y-e.y;const i=d(n*n+l*l);return l>0?u(n/i):2*b-u(n/i)}(e,t),this.length=d(a(t.x-e.x,2)+a(t.y-e.y,2))}dispose(){this.origin=null,this.twin=null,this.nexthedge=null,this.prevhedge=null,this.face=null}getAABB(){let e=new dn;return e.expands([this.origin,this.twin.origin]),e}intersectWithLineSegment([e,t]){return function(e,t,n,l){const{x:i,y:a}=e,{x:s,y:o}=t,{x:r,y:c}=n,{x:d,y:u}=l,h=(u-c)*(s-i)-(d-r)*(o-a),m=(d-r)*(a-c)-(u-c)*(i-r),p=(s-i)*(a-c)-(o-a)*(i-r);if(Math.abs(h)<Gn)return Math.abs(m)<Gn&&Math.abs(p)<Gn?{type:Wn.colinear,point:null,ua:0,ub:0}:{type:Wn.parallel,point:null,ua:0,ub:0};const b=m/h,g=p/h;return b>=-1e-7&&b<=1+Gn&&g>=-1e-7&&g<=1+Gn?{type:Wn.intersecting,point:new Ut(i+b*(s-i),a+b*(o-a)),ua:b,ub:g}:{type:null,point:null,ua:b,ub:g}}(this.origin,this.twin.origin,e,t)}}const Kn=g;class wn{tolerance;vertices=[];hedges=[];faces=[];vertexMap=new Map;constructor(e,t,n=Kn){this.tolerance=n,e&&t&&this.setDatas(e,t)}getVertexKey(e,t){const n=e/this.tolerance,l=t/this.tolerance;return`${Z(n,this.tolerance)},${Z(l,this.tolerance)}`}addVertex(e,t){const n=this.getVertexKey(e,t);let l=this.vertexMap.get(n);l||(l=[],this.vertexMap.set(n,l));for(const n of l)if(this.isClose(n.x,e)&&this.isClose(n.y,t))return n;const i=new Ut(e,t);return this.vertices.push(i),l.push(i),i}deleteVertex(e){const t=this.getVertexKey(e.x,e.y),n=this.vertexMap.get(t);if(n){const l=n.indexOf(e);l>-1&&(n.splice(l,1),0===n.length&&this.vertexMap.delete(t))}const l=this.vertices.indexOf(e);l>-1&&this.vertices.splice(l,1),e.dispose()}findVertex(e,t){const n=this.getVertexKey(e,t),l=this.vertexMap.get(n);if(l)for(const n of l)if(this.isClose(n.x,e)&&this.isClose(n.y,t))return n;return null}verticesInPoly(e){let t=e.map((e=>(new Ut).fromArray(e))),n=new dn;n.expands(t);let l=[],i=this.verticesInBB(n);for(let e of i)In(t,e)&&l.push(e);return l}verticesInBB(e){const t=[];for(let n of this.vertices)e.containsPoint(n)&&t.push(n);return t}setDatas(e,t){const{vertices:n,hedges:l,faces:i}=this;for(let t=0,n=e.length;t<n;t++){const n=e[t];this.addVertex(n[0],n[1])}for(let e=0,i=t.length;e<i;e++){const i=t[e],a=new Vn(n[i[0]],n[i[1]]),s=new Vn(n[i[1]],n[i[0]]);a.twin=s,s.twin=a,n[i[1]].hedgelist.push(a),n[i[0]].hedgelist.push(s),l.push(s),l.push(a)}for(let e=0,t=n.length;e<t;e++){const t=n[e];t.sortincident();const l=t.hedgelist.length;if(0!=l)if(l<2)t.hedgelist[0].prevhedge=t.hedgelist[0].twin,t.hedgelist[0].twin.nexthedge=t.hedgelist[0];else{for(let e=0;e<l-1;e++)t.hedgelist[e].twin.nexthedge=t.hedgelist[e+1],t.hedgelist[e+1].prevhedge=t.hedgelist[e].twin;t.hedgelist[l-1].twin.nexthedge=t.hedgelist[0],t.hedgelist[0].prevhedge=t.hedgelist[l-1].twin}}const a=l.slice(0);let s=l.length;for(;s>0;){let e=a.pop();if(s-=1,null==e.face){const t=new Fn(this);for(t.wedge=e,t.wedge.face=t;e.nexthedge!==t.wedge;)e=e.nexthedge,e.face=t;i.push(t)}}}internalFaces(){const e=[],t=this.faces;for(let n=0,l=t.length;n<l;n++){const l=t[n];l.internal&&e.push(l)}return e}externalFaces(){const e=[],t=this.faces;for(let n=0,l=t.length;n<l;n++){const l=t[n];l.external&&e.push(l)}return e}dispose(){const{vertices:e,hedges:t,faces:n}=this;for(let t=0,n=e.length;t<n;t++)e[t].dispose();for(let e=0,n=t.length;e<n;e++)t[e].dispose();for(let e=0,t=n.length;e<t;e++)n[e].dispose();e.length=0,t.length=0,n.length=0}isClose=(e,t)=>s(e-t)<this.tolerance;findHedge(e,t,n,l){const{isClose:i}=this,a=this.findVertex(e,t);if(a)for(const e of a.hedgelist){const t=e.twin.origin;if(i(t.x,n)&&i(t.y,l))return e}const s=this.findVertex(n,l);if(s)for(const n of s.hedgelist){const l=n.twin.origin;if(i(l.x,e)&&i(l.y,t))return n}return null}addEdge(e,t,n,l){const{vertices:i,hedges:a,faces:s}=this;let o=!1,r=!1,c=!1,d=this.findVertex(e,t);d||(d=this.addVertex(e,t),o=!0);let u=this.findVertex(n,l);u||(u=this.addVertex(n,l),r=!0);const h=new Vn(u,d);a.push(h),d.hedgelist.push(h),d.sortincident();const m=new Vn(d,u);if(a.push(m),u.hedgelist.push(m),u.sortincident(),h.twin=m,m.twin=h,o)h.prevhedge=m,m.nexthedge=h;else{const e=d.hedgelist.indexOf(h);let t,n;0===e?(t=d.hedgelist[d.hedgelist.length-1],n=d.hedgelist[(e+1)%d.hedgelist.length]):(t=d.hedgelist[e-1],n=d.hedgelist[(e+1)%d.hedgelist.length]),h.prevhedge=t.twin,t.twin.nexthedge=h,m.nexthedge=n,n.prevhedge=m}if(r)m.prevhedge=h,h.nexthedge=m;else{const e=u.hedgelist.indexOf(m);let t,n;0===e?(t=u.hedgelist[u.hedgelist.length-1],n=u.hedgelist[(e+1)%u.hedgelist.length]):(t=u.hedgelist[e-1],n=u.hedgelist[(e+1)%u.hedgelist.length]),m.prevhedge=t.twin,t.twin.nexthedge=m,h.nexthedge=n,n.prevhedge=h}const p=h.nexthedge,b=m.nexthedge;if(p.face){const e=s.indexOf(p.face);e>-1&&s.splice(e,1),p.face.dispose(),p.face.area<=this.tolerance&&(c=!0)}if(b.face){const e=s.indexOf(b.face);e>-1&&s.splice(e,1),b.face.dispose(),b.face.area<=this.tolerance&&(c=!0)}const g=new Fn(this);g.wedge=p;let f=new Fn(this);if(f.wedge=b,g.equals(f)&&(f.dispose(),f=null),g){let e=g.wedge;for(e.face=g;e.nexthedge!==g.wedge;)e=e.nexthedge,e.face=g;g.area<=this.tolerance&&(c=!0),s.push(g)}if(f){let e=f.wedge;for(e.face=f;e.nexthedge!==f.wedge;)e=e.nexthedge,e.face=f;f.area<=this.tolerance&&(c=!0),s.push(f)}if(c)for(let e=0,t=s.length;e<t;e++)s[e]._holesDirty=!0}removeEdge(e,t,n,l){const{vertices:i,hedges:a,faces:s}=this,o=this.findHedge(e,t,n,l);if(!o)return;const r=o.twin,c=o.nexthedge,d=r.nexthedge;let u,h=!0,m=!0,p=!1;if(u=a.indexOf(o),a.splice(u,1),u=a.indexOf(r),a.splice(u,1),u=s.indexOf(o.face),u>-1&&s.splice(u,1),o.face.dispose(),o.face.area<=this.tolerance&&(p=!0),u=s.indexOf(r.face),u>-1&&s.splice(u,1),r.face.dispose(),r.face.area<=this.tolerance&&(p=!0),u=o.origin.hedgelist.indexOf(o),o.origin.hedgelist.splice(u,1),o.origin.hedgelist.length>0){let e,t;0===u?(e=o.origin.hedgelist[o.origin.hedgelist.length-1],t=o.origin.hedgelist[u]):(e=o.origin.hedgelist[u-1],t=o.origin.hedgelist[u%o.origin.hedgelist.length]),t.prevhedge=e.twin,e.twin.nexthedge=t}else this.deleteVertex(o.origin),m=!1;if(u=r.origin.hedgelist.indexOf(r),r.origin.hedgelist.splice(u,1),r.origin.hedgelist.length>0){let e,t;0===u?(e=r.origin.hedgelist[r.origin.hedgelist.length-1],t=r.origin.hedgelist[u]):(e=r.origin.hedgelist[u-1],t=r.origin.hedgelist[u%r.origin.hedgelist.length]),t.prevhedge=e.twin,e.twin.nexthedge=t}else this.deleteVertex(r.origin),h=!1;o.dispose(),r.dispose();const b=h?new Fn(this):null;b&&(b.wedge=c);let g=m?new Fn(this):null;if(g&&(g.wedge=d),b&&g)try{b.equals(g)&&(g.dispose(),g=null)}catch{g=null}if(b){let e=b.wedge;for(e.face=b;e.nexthedge!==b.wedge;){if(e=e.nexthedge,!e.face)return;e.face=b}b.area<=this.tolerance&&(p=!0),s.push(b)}if(g){let e=g.wedge;for(e.face=g;e.nexthedge!==g.wedge;)e=e.nexthedge,e.face=g;g.area<=this.tolerance&&(p=!0),s.push(g)}if(p)for(let e=0,t=s.length;e<t;e++)s[e]._holesDirty=!0}splitEdge(e,t,n,l,i,a){const{vertices:s,hedges:o}=this;let r=this.findVertex(i,a),c=this.findHedge(e,t,n,l);if(!c)return!1;if(r)return!0;const d=c.twin;let u;const h=this.addVertex(i,a),m=new Vn(h,c.origin),p=new Vn(d.origin,h);o.push(m),o.push(p);const b=new Vn(h,d.origin),g=new Vn(c.origin,h);return o.push(b),o.push(g),c.face.wedge===c&&(c.face.wedge=m),c.face._vertexlistDirty=!0,m.face=c.face,p.face=c.face,d.face.wedge===d&&(d.face.wedge=b),d.face._vertexlistDirty=!0,b.face=d.face,g.face=d.face,m.nexthedge=p,p.prevhedge=m,b.nexthedge=g,g.prevhedge=b,m.prevhedge=c.prevhedge!==d?c.prevhedge:g,m.prevhedge.nexthedge=m,p.nexthedge=c.nexthedge!==d?c.nexthedge:b,p.nexthedge.prevhedge=p,b.prevhedge=d.prevhedge!==c?d.prevhedge:p,b.prevhedge.nexthedge=b,g.nexthedge=d.nexthedge!==c?d.nexthedge:m,g.nexthedge.prevhedge=g,m.twin=g,p.twin=b,b.twin=p,g.twin=m,h.hedgelist.push(p,g),u=c.origin.hedgelist.indexOf(c),c.origin.hedgelist.splice(u,1,m),u=d.origin.hedgelist.indexOf(d),d.origin.hedgelist.splice(u,1,b),c.dispose(),d.dispose(),u=o.indexOf(c),o.splice(u,1),u=o.indexOf(d),o.splice(u,1),{h1:m,h2:p}}intersectFaceWithPolyLine(e,t,n=!1,l=!1){let i=[],a=l?t.length:t.length-1;for(let l=0;l<a;l++){let a=[t[l],t[(l+1)%t.length]];if(i.push(...e.intersectWithLineSeg(a.map((e=>(new Ut).fromArray(e))))),n&&i.length>=2)break}return i}getFacesAtPoint(e){let t=[],n=new Ut(...e);for(let e of this.faces)e.aabb.containsPoint(n)&&e.containsPoint(n)&&t.push(e);return t}getFacesIntersectingPoly(e){let t=e.map((e=>(new Ut