rm-graphical-computing 1.0.0 → 1.0.2

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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`three`);c=s(c);function l(e,t=!1){let n=e[0].index!==null,r=new Set(Object.keys(e[0].attributes)),i=new Set(Object.keys(e[0].morphAttributes)),a={},o={},s=e[0].morphTargetsRelative,l=new c.BufferGeometry,d=0;for(let c=0;c<e.length;++c){let u=e[c],f=0;if(n!==(u.index!==null))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.`),null;for(let e in u.attributes){if(!r.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. All geometries must have compatible attributes; make sure "`+e+`" attribute exists among all geometries, or in none of them.`),null;a[e]===void 0&&(a[e]=[]),a[e].push(u.attributes[e]),f++}if(f!==r.size)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. Make sure all geometries have the same number of attributes.`),null;if(s!==u.morphTargetsRelative)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. .morphTargetsRelative must be consistent throughout all geometries.`),null;for(let e in u.morphAttributes){if(!i.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. .morphAttributes must be consistent throughout all geometries.`),null;o[e]===void 0&&(o[e]=[]),o[e].push(u.morphAttributes[e])}if(t){let e;if(n)e=u.index.count;else if(u.attributes.position!==void 0)e=u.attributes.position.count;else return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. The geometry must have either an index or a position attribute`),null;l.addGroup(d,e,c),d+=e}}if(n){let t=0,n=[];for(let r=0;r<e.length;++r){let i=e[r].index;for(let e=0;e<i.count;++e)n.push(i.getX(e)+t);t+=e[r].attributes.position.count}l.setIndex(n)}for(let e in a){let t=u(a[e]);if(!t)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` attribute.`),null;l.setAttribute(e,t)}for(let e in o){let t=o[e][0].length;if(t===0)break;l.morphAttributes=l.morphAttributes||{},l.morphAttributes[e]=[];for(let n=0;n<t;++n){let t=[];for(let r=0;r<o[e].length;++r)t.push(o[e][r][n]);let r=u(t);if(!r)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` morphAttribute.`),null;l.morphAttributes[e].push(r)}}return l}function u(e){let t,n,r,i=-1,a=0;for(let o=0;o<e.length;++o){let s=e[o];if(t===void 0&&(t=s.array.constructor),t!==s.array.constructor)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.`),null;if(n===void 0&&(n=s.itemSize),n!==s.itemSize)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.`),null;if(r===void 0&&(r=s.normalized),r!==s.normalized)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.`),null;if(i===-1&&(i=s.gpuType),i!==s.gpuType)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.`),null;a+=s.count*n}let o=new t(a),s=new c.BufferAttribute(o,n,r),l=0;for(let t=0;t<e.length;++t){let r=e[t];if(r.isInterleavedBufferAttribute){let e=l/n;for(let t=0,i=r.count;t<i;t++)for(let i=0;i<n;i++){let n=r.getComponent(t,i);s.setComponent(t+e,i,n)}}else o.set(r.array,l);l+=r.count*n}return i!==void 0&&(s.gpuType=i),s}var d=class extends c.Object3D{constructor(e=document.createElement(`div`)){super(),this.isCSS2DObject=!0,this.element=e,this.element.style.position=`absolute`,this.element.style.userSelect=`none`,this.element.setAttribute(`draggable`,!1),this.center=new c.Vector2(.5,.5),this.addEventListener(`removed`,function(){this.traverse(function(e){e.element&&e.element instanceof e.element.ownerDocument.defaultView.Element&&e.element.parentNode!==null&&e.element.remove()})})}copy(e,t){return super.copy(e,t),this.element=e.element.cloneNode(!0),this.center=e.center,this}};new c.Vector3,new c.Matrix4,new c.Matrix4,new c.Vector3,new c.Vector3;var f=(e,t,n,r,i=1e-8)=>{let a=t.x-e.x,o=t.y-e.y,s=r.x-n.x,l=r.y-n.y,u=a*l-o*s;if(Math.abs(u)<i)return null;let d=((n.x-e.x)*l-(n.y-e.y)*s)/u,f=((n.x-e.x)*o-(n.y-e.y)*a)/u;return d<-i||d>1+i||f<-i||f>1+i?null:{point:new c.Vector3(e.x+d*a,e.y+d*o,e.z)}},p=(e,t,n={})=>{let{fontSize:r=36,fontFamily:i=`sans-serif`,backgroundColor:a=`rgba(0,0,0,0)`,textColor:o=`#ffffff`,padding:s=10,maxWidth:l=256}=n,u=document.createElement(`canvas`).getContext(`2d`);u.font=`bold ${r}px ${i}`;let d=u.measureText(e).width,f=Math.min(d+s*2,l),p=r+s*2,h=document.createElement(`canvas`);h.width=f,h.height=p;let g=h.getContext(`2d`);g.fillStyle=a,g.fillRect(0,0,f,p),g.fillStyle=o,g.font=`bold ${r}px ${i}`,g.textAlign=`center`,g.textBaseline=`middle`,d>l-s*2?m(g,e,f/2,p/2,l,r):g.fillText(e,f/2,p/2);let _=new c.CanvasTexture(h),v=new c.SpriteMaterial({map:_,depthTest:!1,transparent:!0}),y=new c.Sprite(v);y.position.set(t.x,t.y,t.z);let b=.005;return y.scale.set(f*b,p*b,1),y};function m(e,t,n,r,i,a){let o=t.split(``),s=``,c=a*1.2,l=r;for(let t=0;t<o.length;t++){let r=s+o[t];e.measureText(r).width>i&&t>0?(e.fillText(s,n,l),s=o[t],l+=c):s=r}e.fillText(s,n,l)}var h=(e,t,n=.01)=>{let r=Math.sqrt(e.x*e.x+e.y*e.y+e.z*e.z),i=Math.sqrt(t.x*t.x+t.y*t.y+t.z*t.z);if(r<1e-10||i<1e-10)return{parallel:!1,sameDirection:null,angle:NaN};let a={x:e.x/r,y:e.y/r,z:e.z/r},o={x:t.x/i,y:t.y/i,z:t.z/i},s=a.x*o.x+a.y*o.y+a.z*o.z;s=Math.max(-1,Math.min(1,s));let c=Math.acos(Math.abs(s)),l=c<=n;return{parallel:l,sameDirection:l?s>0:null,angle:c}};function g(e,t){let n=new c.BufferGeometry,r=[],i=[];e.forEach(e=>r.push(e.x,e.y,e.z)),t.forEach(e=>r.push(e.x,e.y,e.z)),i.push(0,2,1,0,3,2),i.push(4,5,6,4,6,7),i.push(0,1,5,0,5,4),i.push(1,2,6,1,6,5),i.push(2,3,7,2,7,6),i.push(3,0,4,3,4,7),n.setAttribute(`position`,new c.Float32BufferAttribute(r,3)),n.setIndex(i),n.computeVertexNormals();let a=new c.MeshBasicMaterial({color:`green`,transparent:!0,opacity:.5,side:c.DoubleSide});return new c.Mesh(n,a)}var _=class{constructor(e={}){this.config={value:e.value||`0.0000m`,position:e.position||new c.Vector3(0,0,0),style:{fontFamily:e.style?.fontFamily||`Arial, sans-serif`,fontSize:e.style?.fontSize||`16px`,fontWeight:e.style?.fontWeight||`normal`,fontStyle:e.style?.fontStyle||`normal`},backgroundOpacity:e.backgroundOpacity||.7},this.label=null,this.labelElement=null,this.createLabel()}createLabel(){return this.labelElement=document.createElement(`div`),this.labelElement.textContent=this.config.value,this.applyBlackWhiteStyle(),this.label=new d(this.labelElement),this.label.position.copy(this.config.position),this.label}applyBlackWhiteStyle(){let e=this.labelElement.style,t=this.config;e.fontFamily=t.style.fontFamily,e.fontSize=t.style.fontSize,e.fontWeight=t.style.fontWeight,e.fontStyle=t.style.fontStyle,e.color=`#FFFFFF`,e.textShadow=`0 1px 2px rgba(0, 0, 0, 0.5)`,e.backgroundColor=`rgba(0, 0, 0, ${t.backgroundOpacity})`,e.padding=`6px 12px`,e.borderRadius=`4px`,e.position=`absolute`,e.whiteSpace=`nowrap`,e.userSelect=`none`,e.pointerEvents=`none`,e.zIndex=`1000`,e.textAlign=`center`,e.lineHeight=`1.2`}updateValue(e){this.labelElement&&(this.labelElement.textContent=e)}updatePosition(e){this.label&&this.label.position.copy(e)}updateFontStyle(e){if(this.labelElement){let t=this.labelElement.style;e.fontFamily&&(t.fontFamily=e.fontFamily),e.fontSize&&(t.fontSize=e.fontSize),e.fontWeight&&(t.fontWeight=e.fontWeight),e.fontStyle&&(t.fontStyle=e.fontStyle)}}getLabel(){return this.label}getLabelElement(){return this.labelElement}dispose(){this.labelElement&&this.labelElement.parentNode&&this.labelElement.parentNode.removeChild(this.labelElement),this.label=null,this.labelElement=null}},v=e=>{let t=new c.Group;if(e&&e.length){let n=`green.red.pink.white.azure.yellow.bisque.grey.blanchedalmond.blue.blueviolet.brown.burlywood.cadetblue.chartreuse.chocolate.coral.cornflowerblue.cornsilk.crimson.cyan.darkblue.darkcyan.darkgoldenrod.darkgray.darkgreen.darkgrey.darkkhaki.darkmagenta.darkolivegreen.darkorange.darkorchid.darkred.darksalmon.darkseagreen.darkslateblue.darkslategray.darkslategrey.darkturquoise.darkviolet.deeppink.deepskyblue.dimgray.dimgrey.dodgerblue.firebrick.floralwhite.forestgreen.fuchsia.gainsboro.ghostwhite.gold.goldenrod.gray.aliceblue.greenyellow.black.honeydew.hotpink.indianred.indigo.ivory.khaki.lavender.lavenderblush.lawngreen.lemonchiffon.lightblue.lightcoral.lightcyan.lightgoldenrodyellow.lightgray.lightgreen.lightgrey.lightpink.lightsalmon.lightseagreen.lightskyblue.lightslategray.lightslategrey.lightsteelblue.lightyellow.lime.limegreen.linen.magenta.maroon.mediumaquamarine.mediumblue.mediumorchid.mediumpurple.mediumseagreen.mediumslateblue.mediumspringgreen.mediumturquoise.mediumvioletred.midnightblue.mintcream.mistyrose.moccasin.navajowhite.navy.oldlace.olive.olivedrab.orange.orangered.orchid.palegoldenrod.palegreen.paleturquoise.palevioletred.papayawhip.peachpuff.peru.pink.plum.powderblue.purple.rebeccapurple.yellow.rosybrown.royalblue.saddlebrown.salmon.sandybrown.seagreen.seashell.sienna.silver.skyblue.slateblue.slategray.slategrey.snow.springgreen.steelblue.tan.teal.thistle.tomato.turquoise.violet.wheat.white.whitesmoke.yellow.yellowgreen`.split(`.`);e.forEach((e,r)=>{let i=n[r],a=new c.Group,{pcdPoints:o,category:s,name:l,center:u,box:d,obbBox:f,contour:p,nline:m,coordinatesByWidth:h,coordinatesByArea:v}=e,y=o.length;if(s!=`door`)return;s===`balcony railing`&&console.log(`pcdObj`,e);let b=new c.Box3(new c.Vector3(d.min.x,d.min.y,d.min.z),new c.Vector3(d.max.x,d.max.y,d.max.z)),x=new c.Box3Helper(b,i);a.add(x);let S=new _({value:l,position:new c.Vector3(u.x,u.y,u.z)}).getLabel();a.add(S);let C=new c.InstancedMesh(new c.SphereGeometry(.007,8,8),new c.MeshBasicMaterial({color:i}),y);a.add(C);let w=new c.Matrix4,T=0;if(o.forEach(e=>{w.setPosition(e.x,e.y,e.z),C.setMatrixAt(T,w),T++}),C.instanceMatrix.needsUpdate=!0,m){let e=new c.BufferGeometry;e.setFromPoints([new c.Vector3(m.start.x,m.start.y,m.start.z),new c.Vector3(m.end.x,m.end.y,m.end.z)]);let t=new c.LineBasicMaterial({color:`red`,depthTest:!1,depthWrite:!1});new c.Line(e,t);let n=new c.Vector3().copy(new c.Vector3(m.start.x,m.start.y,m.start.z)).add(new c.Vector3(m.end.x,m.end.y,m.end.z)).multiplyScalar(.5),r=new c.Vector3(m.centerDir.x,m.centerDir.y,m.centerDir.z);new c.ArrowHelper(r,n,1,`red`)}if(p){let e=[];p.forEach((t,n)=>{e.push(new c.Vector3(t.x,t.y,t.z))});let n=new c.BufferGeometry;n.setFromPoints(e);let r=new c.LineBasicMaterial({color:`yellow`,depthTest:!1,depthWrite:!1}),i=new c.Line(n,r);t.add(i)}if(v){let e=[],n=[];v.coordinates.forEach((t,r)=>{e.push(new c.Vector3(t.x,t.y,t.z)),n.length<4&&n.push(new c.Vector3(t.x,t.y,t.z))});let r=new c.BufferGeometry;r.setFromPoints(e);let i=new c.LineBasicMaterial({color:`green`,depthTest:!1,depthWrite:!1}),a=new c.Line(r,i);t.add(a);let o=g(n.map(e=>new c.Vector3(e.x,e.y,v.heightData.minZ)),n.map(e=>new c.Vector3(e.x,e.y,e.z)));t.add(o);let[s,l,u]=e,d=s.distanceTo(l),f=new c.Vector3().copy(s).add(l).multiplyScalar(.5);new _({value:String(d.toFixed(3)),position:f}).getLabel();let p=l.distanceTo(u),m=new c.Vector3().copy(l).add(u).multiplyScalar(.5);new _({value:String(p.toFixed(3)),position:m}).getLabel()}if(f){let e=new c.BoxGeometry(f.size.x,f.size.y,f.size.z),n=new c.LineBasicMaterial({color:i,linewidth:2}),r=new c.EdgesGeometry(e),a=new c.LineSegments(r,n),o=new Vector3(f.center.x,f.center.y,f.center.z),s=new Quaternion(f.rotation.x,f.rotation.y,f.rotation.z,f.rotation.w);a.position.copy(o),a.quaternion.copy(s),t.add(a)}})}return t},y=(e,t,n,r)=>{let i=e,a=[];if(r&&r.length&&(a=r.map(e=>e.clone())),!i||i.length<4)return{};let o=new c.Vector3().subVectors(i[1],i[0]).normalize(),s=new c.Vector3().subVectors(i[3],i[0]).normalize(),l=o.clone().cross(s).normalize(),u=1/0,d=-1/0,f=1/0,p=-1/0;for(let e of i){let t=e.dot(o),n=e.dot(s);t<u&&(u=t),t>d&&(d=t),n<f&&(f=n),n>p&&(p=n)}let m=i[0].dot(l),g=o.clone().multiplyScalar(u).add(s.clone().multiplyScalar(f)).add(l.clone().multiplyScalar(m)),_=o.clone().multiplyScalar(d).add(s.clone().multiplyScalar(f)).add(l.clone().multiplyScalar(m)),v=o.clone().multiplyScalar(d).add(s.clone().multiplyScalar(p)).add(l.clone().multiplyScalar(m)),y=o.clone().multiplyScalar(u).add(s.clone().multiplyScalar(p)).add(l.clone().multiplyScalar(m)),b=[g,_,v,y],x=h(new c.Vector3().subVectors(g,_),new c.Vector3(0,0,1));if(x&&x.parallel&&(b=[g,y,v,_]),r.length>0){let e=new c.Vector3().subVectors(b[1],b[0]).normalize(),r=e.clone().negate(),i=new c.Vector3().subVectors(b[3],b[0]).normalize(),o=i.clone().negate(),s=b[0].distanceTo(b[1]),l=b[0].distanceTo(b[3]),u=s/t,d=l/n,f=.001;for(let r=0;r<u;r++){let r=b[0],o=0;for(let s=0;s<d;s++){let s=r.clone().addScaledVector(e,t),l=s.clone().addScaledVector(i,n),u=r.clone().addScaledVector(i,n),d=new c.Vector3().add(r).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){o++,a.splice(e,1);break}r=u}if(o>=d/2)break;b[0]=b[0].addScaledVector(e,t),b[3]=b[3].addScaledVector(e,t)}s=b[0].distanceTo(b[1]),u=s/t;for(let e=0;e<u;e++){let e=b[1],o=0;for(let s=0;s<d;s++){let s=e.clone().addScaledVector(r,t),l=s.clone().addScaledVector(i,n),u=e.clone().addScaledVector(i,n),d=new c.Vector3().add(e).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){o++,a.splice(e,1);break}e=u}if(o>=d/2)break;b[1]=b[1].addScaledVector(r,t),b[2]=b[2].addScaledVector(r,t)}s=b[0].distanceTo(b[1]),u=s/t;for(let r=0;r<d;r++){let r=b[3],i=0;for(let s=0;s<u;s++){let s=r.clone().addScaledVector(e,t),l=s.clone().addScaledVector(o,n),u=r.clone().addScaledVector(o,n),d=new c.Vector3().add(r).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){i++,a.splice(e,1);break}r=s}if(i>=u/2)break;b[2]=b[2].addScaledVector(o,n),b[3]=b[3].addScaledVector(o,n)}}let S=b[0].distanceTo(b[1])*b[0].distanceTo(b[3]);return{facePoints:b,boxArea:S}},b=(e,t,n,r,i=c.MathUtils.degToRad(10))=>{let a=new c.Vector3,o=new c.Vector3;a.subVectors(new c.Vector3(t.x,t.y,0),new c.Vector3(e.x,e.y,0)).normalize(),o.subVectors(new c.Vector3(r.x,r.y,0),new c.Vector3(n.x,n.y,0)).normalize();let s=a.dot(o),l=Math.acos(Math.min(Math.abs(s),1)),u=1-Math.min(l/i,1),d=s>0?`same`:`opposite`;return{parallelism:u,angle:l,angleDeg:c.MathUtils.radToDeg(l),isParallel:l<i,direction:d,vectors:{v1:a,v2:o}}},x=(e,t,n,r)=>{let i=new c.Vector3().subVectors(t,e),a=new c.Vector3().subVectors(r,n),o=i.length(),s=a.length();if(o===0||s===0)return{rate:NaN,angle:NaN,isPerpendicular:!1,isParallel:!1};i.normalize(),a.normalize();let l=Math.abs(i.dot(a)),u=Math.min(1,Math.max(0,l)),d=Math.acos(u),f=c.MathUtils.radToDeg(d),p=1-u;return{rate:p,percent:`${(p*100).toFixed(2)}%`,angle:f,isPerpendicular:Math.abs(f-90)<.01,isParallel:f<.01}},S=(e,t,n=!1)=>new c.Vector3((e.x+t.x)/2,(e.y+t.y)/2,n?0:(e.z+t.z)/2),C=(e,t,n,r,i={})=>{let{parallelAngleMax:a=c.MathUtils.degToRad(10),collinearAngleMax:o=c.MathUtils.degToRad(7),distanceThreshold:s=2,overlapThreshold:l=.01}=i,u=new c.Vector3().subVectors(t,e),d=new c.Vector3().subVectors(r,n),f=u.clone().normalize(),p=d.clone().normalize(),m=c.MathUtils.clamp(f.dot(p),-1,1),h=Math.acos(Math.abs(m)),g=c.MathUtils.radToDeg(h);if(h>a)return{type:`not_parallel`,angleDeg:g,avgPerpendicularDistance:null,maxPerpendicularDistance:null,gap:null,overlap:null,closestDistance:null};m<0&&p.negate();let _=new c.Vector3().addVectors(f,p).normalize(),v=new c.Vector3().addVectors(e,t).multiplyScalar(.5),y=w(n,v,f),b=w(r,v,f),x=(y+b)/2,S=Math.max(y,b),C=e.dot(_),E=t.dot(_),D=n.dot(_),O=r.dot(_),k=Math.min(C,E),A=Math.max(C,E),j=Math.min(D,O),M=Math.max(D,O),N=A-k,P=M-j,F=Math.min(N,P),I=Math.min(A,M)-Math.max(k,j),L=I<0?-I:0,R=I>0?I:0,z=F>0?R/F:0,B=T(e,t,n,r),V=h<=o&&x<s,H;return V?H=z>.5?`collinear_overlap`:`collinear_gap`:h<=a&&(H=`parallel_offset`),{type:H,angleDeg:g,avgPerpendicularDistance:x,maxPerpendicularDistance:S,gap:L,overlap:R,closestDistance:B}};function w(e,t,n){let r=new c.Vector3().subVectors(e,t),i=r.dot(n),a=n.clone().multiplyScalar(i);return new c.Vector3().subVectors(r,a).length()}function T(e,t,n,r){let i=new c.Vector3().subVectors(t,e),a=new c.Vector3().subVectors(r,n),o=new c.Vector3().subVectors(n,e),s=i.dot(i),l=i.dot(a),u=a.dot(a),d=i.dot(o),f=a.dot(o),p=s*u-l*l,m,h;p<1e-10?(m=0,h=u===0?0:f/u):(m=(l*f-u*d)/p,h=(s*f-l*d)/p),m=c.MathUtils.clamp(m,0,1),h=u===0?0:c.MathUtils.clamp((l*m+f)/u,0,1),m=s===0?0:c.MathUtils.clamp((l*h-d)/s,0,1);let g=e.clone().add(i.clone().multiplyScalar(m)),_=n.clone().add(a.clone().multiplyScalar(h));return g.distanceTo(_)}var E=(e,t,n,r=.05,i=.02)=>{let[a,o,s,l]=e,u=new c.Vector3().subVectors(o,a),d=new c.Vector3().subVectors(l,a),f=new c.Vector3().crossVectors(u,d).normalize(),p=u.length(),m=d.length(),h=u.clone().normalize(),g=d.clone().normalize(),_=n-r,v=n+r,y=new c.Vector3,b=[],x=Math.ceil(p/i),S=Math.ceil(m/i),C=p/x,w=m/S,T=new Uint8Array(x*S);for(let e=0;e<t.length;e++){y.subVectors(t[e],a);let n=Math.abs(y.dot(f));if(n<_||n>v)continue;let r=y.dot(h),i=y.dot(g);if(r<0||r>p||i<0||i>m)continue;b.push(new c.Vector3(t[e].x,t[e].y,t[e].z));let o=Math.min(Math.floor(r/C),x-1),s=Math.min(Math.floor(i/w),S-1);T[s*x+o]=1}let E=0;for(let e=0;e<T.length;e++)T[e]&&E++;let D=x*S,O=p*m,k=E==0||D==0?0:E/D*O;return{filteredPoints:b,coveragePercent:E==0||D==0?0:E/D*100,quadArea:O,coveredArea:k}},D=(e,t)=>Math.round(Math.max(5,Math.min(350,t*Math.sqrt(e)))),O=e=>{let t=new c.Vector3(e.start.x,e.start.y,e.start.z),n=new c.Vector3(e.end.x,e.end.y,e.end.z),r=t.distanceTo(n),i=e.rooftopPz-e.start.z,a=D(r,100),o=D(i,70),s=i/o,l=new Map;for(let e=0;e<o;e++)l.set((e+1)*s,{count:0,minZ:1/0,maxZ:-1/0});let u=new c.Line3(t,n),d=e.originalPoints,f=new c.Vector3;for(let e=0;e<d.length;e++){let t=d[e],n=u.closestPointToPoint(t,!0,f).distanceTo(t),r=Math.floor(n/s);if(r<o){let e=l.get((r+1)*s);e.count++,t.z<e.minZ&&(e.minZ=t.z),t.z>e.maxZ&&(e.maxZ=t.z)}}let p,m,h=a/2;for(let[e,t]of l)if(t.count>=h){p=t.minZ;break}for(let[e,t]of[...l.entries()].reverse())if(t.count>=h){m=t.maxZ;break}return{minZ:p,maxZ:m}},k=(e,t)=>{function n(e,t,n,r,i,a,o,s,l){let u=new c.Line3(e,t),d=new Map,f=new c.Vector3,p=e.clone(),m=t.clone(),h=0;for(;;){let g=new Map,_=0;for(let e=0;e<l.checkResults.length;e++)if(!(l.checkResults[e].allCenterPoints.length/s*100<1))for(let t=0;t<l.checkResults[e].allCenterPoints.length;t++){if(d.has(e)&&d.get(e).removePtsIndex.includes(t))continue;let n=l.checkResults[e].allCenterPoints[t];n=new c.Vector3(n.x,n.y,n.z);let r=u.closestPointToPoint(n,!0,f),a=n.distanceTo(r);Math.abs(a-i)<.01&&(_++,g.has(e)?g.get(e).removePtsIndex.push(t):g.set(e,{index:e,removePtsIndex:[t]}))}if(h==o){e=p,t=m;break}if(_<a/20*19||_==0){g.clear(),o-h<5&&(e=p,t=m,d.clear());break}else{h++;for(let[e,t]of g)d.has(e)?d.get(e).removePtsIndex.push(...t.removePtsIndex):d.set(e,t);g.clear(),e=e.addScaledVector(n,r),t=t.addScaledVector(n,r),u.set(e,t)}}if(d.size>0&&h!=o)for(let[e,t]of d){let n=[],r=[];for(let i=0;i<l.checkResults[e].allCenterPoints.length;i++)t.removePtsIndex.includes(i)||(n.push(l.checkResults[e].allCenterPoints[i]),r.push(l.checkResults[e].originalVertices[i]));l.checkResults[e].allCenterPoints=n,l.checkResults[e].originalVertices=r}}for(let t=0;t<e.length;t++){let r=e[t];if(r.length<.5)continue;let i=-1,a=-1;if(!r.checkResults||r.checkResults.length<=0)continue;if(r.checkResults[0].originalVertices&&r.checkResults[0].originalVertices.length>0){let[e,t,n,o]=r.checkResults[0].originalVertices[0];e=new c.Vector3(e.x,e.y,e.z),t=new c.Vector3(t.x,t.y,t.z),n=new c.Vector3(n.x,n.y,n.z),o=new c.Vector3(o.x,o.y,o.z),i=e.distanceTo(t),a=e.distanceTo(o);let s=h(new c.Vector3().subVectors(e,t).normalize(),new c.Vector3(0,0,1));s&&s.parallel&&([a,i]=[i,a])}if(i<0||a<0)continue;let o=new c.Vector3(r.start.x,r.start.y,r.start.z),s=new c.Vector3(r.end.x,r.end.y,r.end.z),l=o.distanceTo(s),u=r.rooftopPz-r.start.z,d=Math.ceil(l/i),f=Math.ceil(u/a),p=o.clone(),m=s.clone(),g=m.clone().add(new c.Vector3(0,0,u)),_=p.clone().add(new c.Vector3(0,0,u)),v=new c.Vector3().subVectors(m,p).normalize(),y=v.clone().negate();new c.Vector3().subVectors(g,p).normalize().clone().negate();let b=i/2;a/2;let x=l*u/(i*a);n(p,_,v,i,b,f,d,x,r),n(m,g,y,i,b,f,d,x,r),r.start=p,r.end=m;let S=new c.Plane;S.setFromCoplanarPoints(p,m,g);let C=[];r.originalPoints.forEach(e=>{let t=new c.Vector3;S.projectPoint(e,t),t.z=p.z,C.push(t)});let w=new c.Vector3,T=new c.Vector3;S.projectPoint(p,w),S.projectPoint(m,T);let E=new c.Line3(w,T),D=[],O=new c.Vector3;C.forEach((e,t)=>{E.closestPointToPoint(e,!0,O).distanceTo(e)<.001&&D.push(r.originalPoints[t])}),r.originalPoints=D}},A=class{results;clusterResults;constructor(){this.results=null}initLimits1(e,t){let n,r;return n=e<.3?5:e<.5?8:e<.8?10:e<1?15:e<2?30:e<3?35:e<4?40:e<5?45:e<6?50:e<7?60:e<8.5?70:e<10?80:e<15?100:e<20?120:e<25?140:e<30?160:e<35?180:e<40?200:e<45?230:e<50?250:350,t<1?r=30:t<2?r=40:t<2.5?r=45:t<3?r=60:t<3.6?r=70:t<4&&(r=80),{horizontalSubdivisions:n,verticalSubdivisions:r}}initLimits2(e,t){return{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,e/.08))),verticalSubdivisions:Math.round(Math.max(30,Math.min(80,t/.06)))}}initLimits4(e,t){return{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,25*Math.sqrt(e))))*1,verticalSubdivisions:Math.round(Math.max(30,Math.min(80,25*Math.sqrt(t))))*1}}initLimits3(e,t){let n;return n=e<2?.06:e<10?.1:.15,{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,e/n))),verticalSubdivisions:Math.round(Math.max(30,Math.min(80,t/.06)))}}createWallPlaneMeshFromFourPoints(e,t,n,r,i,a,o=16777215){let s=[e,t,n,r];for(let e=0;e<s.length;e++)this.isValidVector3(s[e])||(console.error(`点${e+1}包含无效数据:`,s[e]),s[e]=new c.Vector3(e,0,e));let l=new c.BufferGeometry,u=new Float32Array([s[0].x,s[0].y,s[0].z,s[1].x,s[1].y,s[1].z,s[2].x,s[2].y,s[2].z,s[3].x,s[3].y,s[3].z]),d=[0,1,2,0,2,3],f=new Float32Array([0,0,1,0,1,1,0,1]);l.setAttribute(`position`,new c.BufferAttribute(u,3)),l.setAttribute(`uv`,new c.BufferAttribute(f,2)),l.setIndex(d),l.computeVertexNormals();let p=new c.Mesh(l,i),m=new c.EdgesGeometry(l),h=new c.LineSegments(m,new c.LineBasicMaterial({color:o}));return a.add(h),p}createSubdividedWallPlane(e,t,n,r,i){let a=[];if(!e||!e.start||!e.end||isNaN(e.rooftopPz))return a;let o=new c.Vector3(e.start.x,e.start.y,e.start.z),s=new c.Vector3(e.end.x,e.end.y,e.end.z),l=[o,s,new c.Vector3(e.end.x,e.end.y,e.rooftopPz),new c.Vector3(e.start.x,e.start.y,e.rooftopPz)];for(let e=0;e<l.length;e++)if(!this.isValidVector3(l[e]))return console.error(`墙体基础点${e}无效:`,l[e]),a;let u=o.distanceTo(s),d=Math.abs(e.rooftopPz-e.start.z);if(u===0||d===0)return console.error(`墙体宽度或高度为0`),console.log(`line.rooftopPz`,e.rooftopPz),console.log(`bottomLeft`,o),console.log(`bottomRight`,s),console.log(e.length),a;let f=u/n,p=d/t,m=new c.Vector3().subVectors(s,o).normalize(),h=new c.Vector3(0,0,1);for(let e=0;e<t;e++)for(let t=0;t<n;t++)try{let n={points:[new c.Vector3().copy(o).add(m.clone().multiplyScalar(t*f)).add(h.clone().multiplyScalar(e*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar((t+1)*f)).add(h.clone().multiplyScalar(e*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar((t+1)*f)).add(h.clone().multiplyScalar((e+1)*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar(t*f)).add(h.clone().multiplyScalar((e+1)*p))],userData:{}};n.userData={type:`wallSegment`,row:e,col:t,originalMaterial:r,width:f,height:p},a.push(n)}catch(n){console.error(`创建墙体小平面(${e}, ${t})时出错:`,n)}return a}calculateMinRequiredPoints(e){let t=Math.floor(Math.log1p(e)*.5);return Math.max(1,t)}calculateExpectedDensity(e){return e<1?10:e<4?5:2}evaluateSegmentByArea(e,t,n,r){if(t===0)return!1;let i=e.area,a=e.minRequiredPoints,o=e.expectedDensity,s=t/Math.max(i,.001),c=t>=a,l=s>=o*.3,u=!0;return i<.5&&t>0&&(u=this.checkSmallAreaDistribution(e,n,r)),c&&l&&u}checkSmallAreaDistribution(e,t,n){if(t.length<2)return!0;let r=t.map(e=>n[e]);e.bounds;let i=e.center,a=0,o=Math.sqrt(e.area)*.3;return r.forEach(e=>{e.distanceTo(i)<=o&&a++}),a/r.length>=.3}getFailureReason(e,t){let n=e.area,r=e.minRequiredPoints,i=e.expectedDensity,a=t/Math.max(n,.001),o=[];return t===0?o.push(`无点`):(t<r&&o.push(`点数不足: ${t}/${r}`),a<i*.3&&o.push(`密度不足: ${a.toFixed(2)}/${i.toFixed(2)}`),n<.5&&t>0&&(this.checkSmallAreaDistribution(e,[],[])||o.push(`小平面分布不均`))),o.length>0?o.join(`, `):`未知原因`}calculateMedian(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==0?(t[n-1]+t[n])/2:t[n]}isPointInBoundingBox(e,t,n=.1){return e.x>=t.min[0]-n&&e.x<=t.max[0]+n&&e.y>=t.min[1]-n&&e.y<=t.max[1]+n&&e.z>=t.min[2]-n&&e.z<=t.max[2]+n}getSegmentPlane(e){let t=e.geometry;if(!t||!t.attributes.position)return null;let n=t.attributes.position;if(n.count<3)return null;let r=new c.Vector3().fromBufferAttribute(n,0),i=new c.Vector3().fromBufferAttribute(n,1),a=new c.Vector3().fromBufferAttribute(n,2);r.applyMatrix4(e.matrixWorld),i.applyMatrix4(e.matrixWorld),a.applyMatrix4(e.matrixWorld);let o=new c.Plane;return o.setFromCoplanarPoints(r,i,a),o}analyzePointDistribution(e,t,n=.01){this.results={totalSegments:0,segmentsWithPoints:0,segmentsWithoutPoints:0,missingSegments:[],pointsInSegments:new Map,segmentsByPoint:new Map,segmentDetails:new Map,tolerance:n,analysisTime:null};let r=performance.now(),i=[];e.forEach(e=>{if(e.userData&&e.userData.type===`wallSegment`){let t=this.getWorldVerticesNew(e.points);if(t.length<4)return;let n=new c.Vector3().add(t[0]).add(t[1]).add(t[2]).add(t[3]).multiplyScalar(.25);e.userData.center=n,e.vertices=t,i.push(e)}}),this.results.totalSegments=i.length;for(let e of i){if(e.vertices.length<4)continue;let r=e.userData.center,i=`row${e.userData.row}_col${e.userData.col}`,[a,o,s,l]=e.vertices,u=new c.Vector3().subVectors(o,a).normalize(),d=new c.Vector3().subVectors(l,a).normalize(),f=a.distanceTo(o),p=a.distanceTo(l),m=new c.Plane;m.setFromCoplanarPoints(a,o,l);let h=f/2,g=p/2;for(let e=0;e<t.length;e++)this.isPointInWallSegmentOptimized(t[e],r,m,a,u,d,f,p,h,g,n)&&(this.results.pointsInSegments.has(i)||this.results.pointsInSegments.set(i,[]),this.results.pointsInSegments.get(i).push(e))}return i.forEach(e=>{let t=`row${e.userData.row}_col${e.userData.col}`,n=this.results.pointsInSegments.has(t)?this.results.pointsInSegments.get(t).length:0;n>=1?this.results.segmentsWithPoints++:(this.results.segmentsWithoutPoints++,this.results.missingSegments.push({row:e.userData.row,col:e.userData.col,width:e.userData.width,height:e.userData.height,segmentKey:t,vertices:e.vertices,center:e.userData.center,mesh:e,pointCount:n,hasPointsButNotEnough:n>0&&n<1}))}),this.results.analysisTime=performance.now()-r,this.printAnalysisResults(),this.results}isPointInWallSegmentOptimized(e,t,n,r,i,a,o,s,l,u,d){if(Math.abs(n.distanceToPoint(e))>d)return!1;let f=new c.Vector3().subVectors(e,t),p=Math.abs(f.dot(i)),m=Math.abs(f.dot(a));if(p>l&&m>u)return!1;let h=new c.Vector3().subVectors(e,r),g=h.dot(i),_=h.dot(a),v=g>=-d&&g<=o+d,y=_>=-d&&_<=s+d;return v&&y}isPointInWallSegment(e,t,n,r=.1){if(!e.geometry)return!1;try{let i=this.getWorldVertices(e);return i.length<4?!1:this.isPointInRotatedWall(i,t,n,r)}catch(e){return console.error(`判断点是否在墙体平面内时出错:`,e),!1}}isPointInRotatedWall(e,t,n,r=.1){let[i,a,o,s]=e,l=new c.Plane;if(l.setFromCoplanarPoints(i,a,s),Math.abs(l.distanceToPoint(t))>r)return!1;let u=new c.Vector3().subVectors(a,i).normalize(),d=new c.Vector3().subVectors(s,i).normalize();new c.Vector3().crossVectors(u,d).normalize();let f=new c.Vector3().subVectors(t,i),p=f.dot(u),m=f.dot(d),h=i.distanceTo(a),g=i.distanceTo(s),_=p>=-r&&p<=h+r,v=m>=-r&&m<=g+r;return _&&v&&n.distanceTo(t)<h/2&&n.distanceTo(t)<g/2}getWorldVertices(e){if(e._cachedWorldVertices&&e.matrixWorld.equals(e._cachedMatrixWorld))return e._cachedWorldVertices;let t=e.geometry.getAttribute(`position`),n=[];for(let r=0;r<Math.min(4,t.count);r++){let i=new c.Vector3;i.fromBufferAttribute(t,r),i.applyMatrix4(e.matrixWorld),n.push(i)}return e._cachedWorldVertices=n,e._cachedMatrixWorld=e.matrixWorld.clone(),n}getWorldVerticesNew(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n].clone();t.push(r)}return t}getWallSegmentBounds(e){if(!e.geometry)return null;let t=e.geometry.getAttribute(`position`),n=new c.Box3;for(let r=0;r<t.count;r++){let i=new c.Vector3;i.fromBufferAttribute(t,r),i.applyMatrix4(e.matrixWorld),n.expandByPoint(i)}return{min:n.min.toArray(),max:n.max.toArray(),center:n.getCenter(new c.Vector3).toArray(),size:n.getSize(new c.Vector3).toArray()}}highlightEmptySegments(e,t,n,r=1){if(!this.results){console.warn(`请先运行分析函数`);return}let i=new Map,a=new Map;this.results.missingSegments.forEach(e=>{i.set(e.segmentKey,e),a.has(e.row)||a.set(e.row,new Map),a.get(e.row).set(e.col,{segmentKey:e.segmentKey,isEmpty:!0,visited:!1})}),e.forEach(e=>{if(e.userData&&e.userData.type===`wallSegment`){let t=`row${e.userData.row}_col${e.userData.col}`,n=i.has(t);a.has(e.userData.row)||a.set(e.userData.row,new Map),a.get(e.userData.row).has(e.userData.col)||a.get(e.userData.row).set(e.userData.col,{segmentKey:t,isEmpty:n,visited:!1})}});let o=[],s=[[0,1],[1,0],[0,-1],[-1,0]];for(let[e,t]of i){let e=a.get(t.row)?.get(t.col);if(e&&!e.visited){let n=[],c=[[t.row,t.col]];for(e.visited=!0;c.length>0;){let[e,t]=c.shift(),r=`row${e}_col${t}`;i.has(r)&&n.push(i.get(r));for(let[n,r]of s){let i=e+n,o=t+r;if(a.has(i)&&a.get(i).has(o)){let e=a.get(i).get(o);!e.visited&&e.isEmpty&&(e.visited=!0,c.push([i,o]))}}}n.length>=r&&o.push(n)}}let c=this.createClusterMaterials(o.length),l=[];return this.clusterResults={clusters:o.sort((e,t)=>t.length-e.length),highlightedMeshes:l,clusterMaterials:c,totalClusters:o.length,totalHighlighted:l.length},this.clusterResults}calculateBoundaryRegularity(e,t,n,r,i){let a=0,o=0,s=t,c=!0;for(let t=r;t<=i;t++)e.has(s)&&e.get(s).has(t)?o++:c=!1;c&&a++;let l=n,u=!0;for(let t=r;t<=i;t++)e.has(l)&&e.get(l).has(t)?o++:u=!1;u&&a++;let d=r,f=!0;for(let r=t;r<=n;r++)e.has(r)&&e.get(r).has(d)?o++:f=!1;f&&a++;let p=i,m=!0;for(let r=t;r<=n;r++)e.has(r)&&e.get(r).has(p)?o++:m=!1;return m&&a++,a/4}calculateClusterQualityScore(e){let t=1/Math.max(1,e.aspectRatio);return e.compactness*.4+e.boundaryRegularity*.4+t*.2}calculateStrictClusterBounds(e){if(e.length===0)return{width:0,height:0};let t=[];if(e.forEach(e=>{e.vertices&&e.vertices.length>0&&t.push(...e.vertices)}),t.length===0){let t=[...new Set(e.map(e=>e.row))];return{width:[...new Set(e.map(e=>e.col))].length*(e[0].bounds?.width||1),height:t.length*(e[0].bounds?.height||1)}}let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y)),o=Math.min(...t.map(e=>e.z)),s=Math.max(...t.map(e=>e.z));return{width:Math.abs(r-n),height:Math.max(Math.abs(a-i),Math.abs(s-o))}}createClusterMaterials(e){let t=[],n=[16711935,65535,16753920,16738740,9055202,3329330,`lavenderblush`,`lawngreen`,`lemonchiffon`,`lightblue`,`lightcoral`];for(let r=0;r<e;r++){let e=n[r%n.length],i=new c.MeshBasicMaterial({color:e,transparent:!0,opacity:.6,side:c.DoubleSide});t.push(i)}return t}clearHighlights(e){this.clusterResults&&this.clusterResults.highlightedMeshes&&(this.clusterResults.highlightedMeshes.forEach(t=>{e.remove(t),t.material&&t.material.dispose()}),this.results&&this.results.segmentDetails&&this.results.segmentDetails.forEach((e,t)=>{e.mesh&&e.mesh.userData.originalMaterial&&(e.mesh.material=e.mesh.userData.originalMaterial)}),this.clusterResults.highlightedMeshes=[])}getClusterInfo(){return this.clusterResults?{totalClusters:this.clusterResults.totalClusters,clusterSizes:this.clusterResults.clusters.map((e,t)=>({clusterIndex:t,size:e.length,segments:e.map(e=>e.segmentKey)})),largestCluster:Math.max(...this.clusterResults.clusters.map(e=>e.length)),smallestCluster:Math.min(...this.clusterResults.clusters.map(e=>e.length))}:null}restoreOriginalMaterials(e){let t=0;e.traverse(e=>{e.userData&&e.userData.originalMaterial&&(e.material=e.userData.originalMaterial,delete e.userData.originalMaterial,t++)}),console.log(`恢复了 ${t} 个平面的原始材质`)}createDebugHelpers(e){let t=new c.Group;return e.traverse(e=>{if(e.userData&&e.userData.type===`wallSegment`){let n=this.getWorldVertices(e);if(n.length<4)return;let r=new c.Vector3().add(n[0]).add(n[1]).add(n[2]).add(n[3]).multiplyScalar(.25),i=new c.Vector3().subVectors(n[1],n[0]).normalize(),a=new c.Vector3().subVectors(n[3],n[0]).normalize(),o=new c.Vector3().crossVectors(i,a).normalize(),s=new c.ArrowHelper(o,r,.3,16711680),l=new c.ArrowHelper(i,r,.2,65280),u=new c.ArrowHelper(a,r,.2,255);t.add(s),t.add(l),t.add(u)}}),t}printAnalysisResults(){if(!this.results){console.warn(`没有可用的分析结果`);return}this.results.missingSegments.length>0&&this.results.missingSegments.forEach(e=>{}),this.results.pointsInSegments.forEach((e,t)=>{})}isValidVector3(e){return e&&!isNaN(e.x)&&!isNaN(e.y)&&!isNaN(e.z)&&isFinite(e.x)&&isFinite(e.y)&&isFinite(e.z)}mergeWallGroupMeshes(e){let t=[];if(e.traverse(e=>{e.isMesh&&e.geometry&&t.push(e)}),t.length===0)return null;try{let e=t.map(e=>e.geometry);e.forEach((e,n)=>{e.applyMatrix4(t[n].matrixWorld)});let n=l(e),r=t[0].material.clone(),i=new c.Mesh(n,r);return i.name=`mergedWalls`,i}catch(e){return console.error(`合并网格时出错:`,e),null}}},j=e=>{let t={},n=[],r=[],i=[];return e[0].width,e[0].height,e.forEach(e=>{r.push(...e.vertices),i.push(e.center),n.push(e.vertices)}),t.originalVertices=n,t.allCenterPoints=i,t},M=e=>{let t=new c.Vector3().copy(e.start).add(e.end).multiplyScalar(.5),n=new c.Vector3().subVectors(new c.Vector3(t.x,t.y,t.z+1),t).normalize(),r=new c.Vector3(e.direction.x,e.direction.y,0);r.applyAxisAngle(n,Math.PI/2);let i=new c.Vector3().copy(t).add(r.clone().multiplyScalar(e.length)),a=new c.Vector3().copy(t).sub(r.clone().multiplyScalar(e.length));return t.z=e.start.z,i.z=e.start.z,a.z=e.start.z,{start:i,end:a,center:t,direction:r}},N=(e,t,n=!0)=>{let r=[];if(!e)return[];for(let i=0;i<e.length;i++){let a=e[i];if(!a)continue;let o=new c.Vector3(a.start.x,a.start.y,a.start.z);o.applyEuler(new c.Euler(-Math.PI/2,0,0));let s=new c.Vector3(a.end.x,a.end.y,a.end.z);if(s.applyEuler(new c.Euler(-Math.PI/2,0,0)),t.add(p(String(i),new c.Vector3((o.x+s.x)/2,(o.y+s.y)/2,(o.z+s.z)/2))),(a.isBayWindow||a.isWindow)&&n)continue;let l=new c.Plane().setFromCoplanarPoints(new c.Vector3(a.start.x,a.start.y,a.start.z),new c.Vector3(a.end.x,a.end.y,a.end.z),new c.Vector3(a.start.x,a.start.y,a.rooftopPz)),u=[];a.originalPoints.forEach((e,t)=>{let n=new c.Vector3;l.projectPoint(e,n),u.push(n)});let d=new c.Vector3(a.start.x,a.start.y,a.start.z).distanceTo(new c.Vector3(a.end.x,a.end.y,a.end.z)),f=Math.abs(a.rooftopPz-a.start.z),m=new c.MeshBasicMaterial({color:`red`,side:c.DoubleSide,wireframe:!1,transparent:!0,opacity:.5}),h=new c.Group,g=new A,{horizontalSubdivisions:_,verticalSubdivisions:v}=g.initLimits4(d,f),y=g.createSubdividedWallPlane(a,v,_,m,h);g.analyzePointDistribution(y,u,.01);let b=new c.MeshBasicMaterial({color:`black`,transparent:!0,opacity:.8,side:c.DoubleSide}),x=g.highlightEmptySegments(y,b,h),S=[];for(let e of x.clusters){let t=j(e);t&&S.push(t)}let C=M(a).direction;a.checkResults=S,a.verticalDirection=C,a.originaIndex=i,r.push(a)}return r},P=async(e,t,n,r)=>{let i=await fetch(e);if(!i)return;let a=await i.json();for(let e=0;e<a.length;e++){let t=a[e];if(!t)continue;let n=new c.Vector3(t.start.x,t.start.y,t.start.z);n.applyEuler(new c.Euler(-Math.PI/2,0,0));let i=new c.Vector3(t.end.x,t.end.y,t.end.z);i.applyEuler(new c.Euler(-Math.PI/2,0,0)),r.add(p(String(e),new c.Vector3((n.x+i.x)/2,(n.y+i.y)/2,(n.z+i.z)/2)))}a.sort((e,t)=>e.originalIndex-t.originalIndex),console.log(`lins`,a);let o=await fetch(t);if(!o)return;let s=await o.json(),u=Array.isArray(s)?s:Object.values(s),d=await fetch(n);if(console.log(`respcd`,d),!d)return;let f=await d.json();console.time(),a=await F(a,u,f,r),console.timeEnd();let m=new c.MeshBasicMaterial({color:`#cffd00`,transparent:!0,opacity:.4,side:c.DoubleSide}),h=new c.MeshBasicMaterial({color:`#ff0000`,transparent:!0,opacity:.4,side:c.DoubleSide});new c.LineBasicMaterial({color:`#cffd00`});let g=new c.PointsMaterial({color:65535,size:.01}),_=[],y=[];for(let e of a){if(!e.originalPoints||e.originalPoints.length===0)continue;let t=new Float32Array(e.originalPoints.length*3);e.originalPoints.forEach((e,n)=>{t[n*3]=e.x,t[n*3+1]=e.y,t[n*3+2]=e.z});let n=new c.BufferGeometry;n.setAttribute(`position`,new c.BufferAttribute(t,3)),_.push(n);let r=[];r.push(new c.Vector3(e.start.x,e.start.y,e.start.z)),r.push(new c.Vector3(e.end.x,e.end.y,e.end.z));let i=new c.BufferGeometry;i.setFromPoints(r),y.push(i)}if(_.length>0){let e=l(_,!1);e.rotateX(-Math.PI/2),r.add(new c.Points(e,g)),_.forEach(e=>e.dispose())}let b=[],x=[],S=new c.LineBasicMaterial({color:`#f30606`}),C=new c.MeshBasicMaterial({color:`#071ac4`});for(let e=0;e<u.length;e++){let t=new c.SphereGeometry(.05);t.translate(u[e].x,u[e].y,u[e].z);let n=[],r=new c.Vector3(u[e].x,u[e].y,u[e].z),i=new c.Quaternion(u[e].qx,u[e].qy,u[e].qz,u[e].qw),a=new c.Vector3(0,0,-1).applyQuaternion(i),o=r.clone().addScaledVector(a,.001);n.push(r),n.push(o);let s=new c.BufferGeometry;s.setFromPoints(n),x.push(s),b.push(t)}if(b.length>0){let e=l(b,!1);e.rotateX(-Math.PI/2),r.add(new c.Mesh(e,C)),b.forEach(e=>e.dispose())}if(x.length>0){let e=l(x,!1);e.rotateX(-Math.PI/2),r.add(new c.Line(e,S)),x.forEach(e=>e.dispose())}let w=v(f);w.rotateX(-Math.PI/2),r.add(w),console.log(`jsonpcdData`,f),a.forEach(e=>{if(e.doorAndBeamData&&e.doorAndBeamData.length>0){let t=new c.Group;e.doorAndBeamData.forEach(e=>{if(e.beamStart){let n=new c.BufferGeometry,r=new Float32Array([e.beamStart.x,e.beamStart.y,e.beamStart.z,e.beamEnd.x,e.beamEnd.y,e.beamEnd.z,e.beamEnd.x,e.beamEnd.y,e.beamEnd.z+e.beamHeight,e.beamStart.x,e.beamStart.y,e.beamStart.z+e.beamHeight]);n.setAttribute(`position`,new c.BufferAttribute(r,3)),n.setIndex([0,1,2,0,2,3]),n.computeVertexNormals(),n.rotateX(-Math.PI/2),t.add(new c.Mesh(n,m))}let n=new c.BufferGeometry,r=new Float32Array([e.doorStart.x,e.doorStart.y,e.doorStart.z,e.doorEnd.x,e.doorEnd.y,e.doorEnd.z,e.doorEnd.x,e.doorEnd.y,e.doorEnd.z+e.doorHeight,e.doorStart.x,e.doorStart.y,e.doorStart.z+e.doorHeight]);n.setAttribute(`position`,new c.BufferAttribute(r,3)),n.setIndex([0,1,2,0,2,3]),n.computeVertexNormals(),n.rotateX(-Math.PI/2),t.add(new c.Mesh(n,h));let i=`id:${e.id},Nid:${e.nearId}`,a=new c.Vector3((e.doorStart.x+e.doorEnd.x)/2,(e.doorStart.y+e.doorEnd.y)/2,e.doorStart.z+e.doorHeight);a.applyEuler(new c.Euler(-Math.PI/2,0,0)),t.add(p(i,a))}),r.add(t)}})},F=async(e,t,n)=>{if(e.length<=0||t.length<=0)return e;n||=[];for(let t of e){let e=[];if(!(!t.checkResults||t.checkResults.length<=0)){for(let n=0;n<t.checkResults.length;n++){let r=t.checkResults[n];if(r.isDoor=!1,!r.originalVertices||r.originalVertices.length==0)continue;let i=[];r.originalVertices.forEach(e=>{let t=[];e.forEach(e=>{t.push(new c.Vector3(e.x,e.y,e.z))}),i.push(t)});let a=i.length,o=Array.from({length:a},(e,t)=>t);function s(e){for(;o[e]!==e;)o[e]=o[o[e]],e=o[e];return e}for(let e=0;e<a;e++)for(let t=e+1;t<a;t++){let n=i[e],r=i[t];if(n.some(e=>r.some(t=>e.equals(t)))){let n=s(e),r=s(t);n!==r&&(o[n]=r)}}let l=new Map,u=-1,d=-1;for(let e=0;e<a;e++){let t=s(e);l.has(t)||l.set(t,{points:[],area:0,originalVertices:[],index:-1,gridWidth:-1,gridHeight:-1,centerPts:[]});let r=l.get(t),[a,o,f,p]=i[e],m=new c.Vector3().add(a).add(o).add(f).add(p).multiplyScalar(.25);if(r.points.push(...i[e]),r.area+=a.distanceTo(o)*a.distanceTo(p),r.originalVertices.push(i[e]),r.index=n,r.centerPts.push(m),u==-1||d==-1){let e=new c.Vector3().subVectors(a,o).normalize();d=a.distanceTo(p),u=a.distanceTo(o);let t=h(e,new c.Vector3(0,0,1));t&&t.parallel&&([d,u]=[u,d])}r.gridWidth=u,r.gridHeight=d}e.push(...l.values())}t.mergeCheckRegion=e}}let r=new Map;for(let t of e){let e=t.rooftopPz-t.start.z,n=Math.floor(t.rooftopPz-t.start.z);r.has(n)?r.set(n,{num:r.get(n).num+1,totalHeight:r.get(n).totalHeight+e}):r.set(n,{num:1,totalHeight:e})}let i=[...r.entries()].reduce((e,t)=>t[1].num>e[1].num?t:e),a=i[0];i[1].totalHeight/i[1].num;let o=[];for(let e=0;e<n.length;e++){let t=n[e];if(t.isFindBeam=!1,t.category==`door`){let n=[];t.coordinatesByArea.coordinates.forEach(e=>{n.push(new c.Vector3(e.x,e.y,e.z))}),n[0].equals(n[n.length-1])&&n.pop();let r=n[0].distanceTo(n[1]),i=n[0].distanceTo(n[3]);if(i>r&&([r,i]=[i,r],n=[n[0],n[3],n[2],n[1]]),r<.5)continue;let a=S(n[0],n[3],!0),s=S(n[1],n[2],!0);o.push({doorStartPt:a,doorEndPt:s,boxPoints:n,minZ:t.coordinatesByArea.heightData.minZ,maxZ:t.coordinatesByArea.heightData.maxZ,index:e,isFind:!1})}}for(let t=0;t<o.length;t++){let n=o[t];for(let t=0;t<e.length;t++){if(e[t].length<.8)continue;let r=[],i=S(e[t].start,e[t].end,!0);r.push(i),r.push(S(i,e[t].start,!0)),r.push(S(i,e[t].end,!0));let a=!1,o=n.boxPoints.length;for(let e=0;e<r.length;e++){let t=r[e].x,i=r[e].y;for(let e=0,r=o-1;e<o;r=e++){let o=n.boxPoints[e].x,s=n.boxPoints[e].y,c=n.boxPoints[r].x,l=n.boxPoints[r].y;s>i!=l>i&&t<(c-o)*(i-s)/(l-s)+o&&(a=!a)}if(a)break}if(a){let r=new c.Vector3(e[t].start.x,e[t].start.y,0),i=new c.Vector3(e[t].end.x,e[t].end.y,0),a=n.doorStartPt.distanceTo(n.doorEndPt),o=r.distanceTo(i),s=b(n.doorStartPt,n.doorEndPt,r,i);if(Math.abs(o-a)<.5&&s&&s.isParallel){n.doorStartPt=new c.Vector3(e[t].start.x,e[t].start.y,0),n.doorEndPt=new c.Vector3(e[t].end.x,e[t].end.y,0);break}}else continue}}let s=0,l=[];for(let r=0;r<e.length;r++){let i=e[r];if(!i.mergeCheckRegion||i.mergeCheckRegion.length==0)continue;i.doorAndBeamData=[],i.completePointAreaPercentage=-1;let u=new c.Box3;u.setFromPoints(i.originalPoints);let d=u.max.z,p=u.min.z,m=i.rooftopPz-i.start.z;if(m<a-.5||m>a+2)continue;let h=0;for(let a of i.mergeCheckRegion){let{facePoints:u,boxArea:g}=y(a.points,a.gridWidth,a.gridHeight,a.centerPts);if(!(!u||u.length<=0)&&(h+=a.area,a.area/g*100>60)){let h=u[0].distanceTo(u[1]),g=h/i.length*100,_=u[0].distanceTo(u[3]),v=i.rooftopPz-u[2].z,y=p>i.start.z-.15&&i.length<1.5||i.length>1.5;if(_<.5||!y||d<u[2].z||v>m/2)continue;let x=!1,w=!1,T=!1,E=-1,D=u[2].clone(),O=u[3].clone(),k=u[0].clone(),A=u[1].clone();if(Math.abs(u[0].z-i.start.z)<.1&&(g<85&&h>.4||h>.7&&_>m-m/3)){let e=!1;for(let n=0;n<t.length;n++){let r=n+1;if(r>=t.length)continue;let i=new c.Vector3(t[n].x,t[n].y,t[n].z),a=new c.Vector3(t[r].x,t[r].y,t[r].z);if(f(new c.Vector3(i.x,i.y,0),new c.Vector3(a.x,a.y,0),new c.Vector3(u[0].x,u[0].y,0),new c.Vector3(u[1].x,u[1].y,0),.1)!=null){e=!0;break}}for(let e=0;e<o.length;e++){let t=new c.Vector3(o[e].doorStartPt.x,o[e].doorStartPt.y,0),r=new c.Vector3(o[e].doorEndPt.x,o[e].doorEndPt.y,0),a=new c.Vector3(u[0].x,u[0].y,0),s=new c.Vector3(u[1].x,u[1].y,0),l=new c.Vector3().subVectors(t,r).normalize(),d=new c.Vector3().subVectors(a,s).normalize(),p=.2,m=f(t.clone().addScaledVector(l,p),r.clone().addScaledVector(l.clone().negate(),p),a.clone().addScaledVector(d,p),s.clone().addScaledVector(d.clone().negate(),p)),h=u[2].z<o[e].maxZ||Math.abs(u[2].z-o[e].maxZ)<.3,g=b(t.clone(),r.clone(),a.clone(),s.clone());if(m&&h)n[o[e].index].isFindBeam=!0,w=!0,o[e].isFind=!0;else if(h&&g&&g.isParallel){let a=S(t,r),s=new c.Line3(new c.Vector3(i.start.x,i.start.y,0),new c.Vector3(i.end.x,i.end.y,0)),l=new c.Vector3,u=s.closestPointToPoint(a,!0,l);a.distanceTo(u)<.3&&(n[o[e].index].isFindBeam=!0)}}if(!w)for(let e=0;e<o.length;e++){let t=new c.Vector3(o[e].doorStartPt.x,o[e].doorStartPt.y,0),r=new c.Vector3(o[e].doorEndPt.x,o[e].doorEndPt.y,0),a=new c.Vector3(u[0].x,u[0].y,0),l=new c.Vector3(u[1].x,u[1].y,0),d=u[2].z<o[e].maxZ||Math.abs(u[2].z-o[e].maxZ)<.3,f=Math.abs(u[2].z-o[e].maxZ)>.2;if(d&&!f){let d=C(t.clone(),r.clone(),a.clone(),l.clone(),{distanceThreshold:2});if(s==4&&console.log(o[e],d),d&&d.type==`collinear_gap`){let s=S(t,r),f=new c.Line3(new c.Vector3(i.start.x,i.start.y,0),new c.Vector3(i.end.x,i.end.y,0)),p=new c.Vector3,m=f.closestPointToPoint(s,!0,p);if(s.distanceTo(m)<.15){let i=a.distanceTo(t),s=l.distanceTo(t);if(i>.25&&s>.25){let e=a.distanceTo(r),t=l.distanceTo(r);if(e>.2&&t>.2)continue}w=!0,T=!0,E=o[e].index,o[e].isFind=!0,n[o[e].index].isFindBeam=!0;let f=new c.Vector3().subVectors(a,l).normalize(),p=t.distanceTo(r)-d.overlap;s<i&&f.negate(),i>s?(D=u[2].clone().addScaledVector(f,p),O=u[3].clone(),k=D.clone(),A=O.clone(),k.z=A.z=u[0].z):(D=u[2].clone(),O=u[3].clone().addScaledVector(f,p),k=D.clone(),A=O.clone(),k.z=A.z=u[0].z)}}else if(d&&d.type==`collinear_overlap`){let i=a.distanceTo(l),s=r.distanceTo(t);(Math.abs(i-d.overlap)<.25||Math.abs(s-d.overlap)<.25)&&(w=!0,T=!0,E=o[e].index,o[e].isFind=!0,n[o[e].index].isFindBeam=!0)}}}(w||e||_>m/2&&h>.8&&Math.abs(p-i.start.z)<.4)&&(x=!0)}if(x){i.checkResults[a.index].isDoor=!0;let t={id:s,beamStart:D,beamEnd:O,beamHeight:i.rooftopPz-u[2].z,doorStart:k,doorEnd:A,doorHeight:_,nearId:-1,type:`doorBeam`,isDoor:w,isPullOutDoor:T,pcbDoorIndex:E};for(let n=0;n<l.length;n++){let r=e[l[n].linesIndex].doorAndBeamData[l[n].doorIndex];if(r.nearId!=-1)continue;let i=b(D.clone(),O.clone(),r.beamStart.clone(),r.beamEnd.clone());if(i&&i.isParallel){let e=D.distanceTo(O),n=r.beamStart.distanceTo(r.beamEnd),i=new c.Line3(D.clone(),O.clone());i.start.z=0,i.end.z=0;let a=S(r.beamStart,r.beamEnd,!0);n>e&&(i.start=new c.Vector3(r.beamStart.x,r.beamStart.y,0),i.end=new c.Vector3(r.beamEnd.x,r.beamEnd.y,0),a=S(D,O,!0));let o=new c.Vector3,l=i.closestPointToPoint(a,!0,o),u=l.distanceTo(a),d=new c.Vector3().subVectors(a,l).normalize(),p=d.clone().negate(),m=a.clone().addScaledVector(p,u+.1),h=f(i.start,i.end,a,m);if(u<.5&&h!=null){r.nearId=s,t.nearId=r.id;let i=.8;(r.isDoor||t.isDoor)&&(r.isDoor=!0,t.isDoor=!0),e<n?e>i&&!r.isPullOutDoor?(r.beamStart=D.clone().addScaledVector(p,u),r.beamEnd=O.clone().addScaledVector(p,u),r.doorStart=k.clone().addScaledVector(p,u),r.doorEnd=A.clone().addScaledVector(p,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):!T||T&&r.isPullOutDoor&&E==r.pcbDoorIndex?(t.beamStart=r.beamStart.clone().addScaledVector(d,u),t.beamEnd=r.beamEnd.clone().addScaledVector(d,u),t.doorStart=r.doorStart.clone().addScaledVector(d,u),t.doorEnd=r.doorEnd.clone().addScaledVector(d,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight):(r.beamStart=D.clone().addScaledVector(p,u),r.beamEnd=O.clone().addScaledVector(p,u),r.doorStart=k.clone().addScaledVector(p,u),r.doorEnd=A.clone().addScaledVector(p,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):e>n&&(n>i&&!T?(t.beamStart=r.beamStart.clone().addScaledVector(p,u),t.beamEnd=r.beamEnd.clone().addScaledVector(p,u),t.doorStart=r.doorStart.clone().addScaledVector(p,u),t.doorEnd=r.doorEnd.clone().addScaledVector(p,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight):!r.isPullOutDoor||T&&r.isPullOutDoor&&E==r.pcbDoorIndex?(r.beamStart=D.clone().addScaledVector(d,u),r.beamEnd=O.clone().addScaledVector(d,u),r.doorStart=k.clone().addScaledVector(d,u),r.doorEnd=A.clone().addScaledVector(d,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):(t.beamStart=r.beamStart.clone().addScaledVector(p,u),t.beamEnd=r.beamEnd.clone().addScaledVector(p,u),t.doorStart=r.doorStart.clone().addScaledVector(p,u),t.doorEnd=r.doorEnd.clone().addScaledVector(p,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight));break}}}i.doorAndBeamData.push(t),l.push({linesIndex:r,doorIndex:i.doorAndBeamData.length-1}),s++}}}let g=i.length*(i.rooftopPz-i.start.z);i.completePointAreaPercentage=h/g*100}let u=.65,d=[],p=[],m=.2;for(let t=0;t<o.length;t++){if(o[t].isFind)continue;let r=new c.Vector3(o[t].doorStartPt.x,o[t].doorStartPt.y,0),i=new c.Vector3(o[t].doorEndPt.x,o[t].doorEndPt.y,0),a=new c.Vector3().subVectors(r,i).normalize();for(let l=0;l<e.length;l++){if(e[l].length<1||e[l].completePointAreaPercentage>60)continue;let h=new c.Vector3(e[l].start.x,e[l].start.y,0),g=new c.Vector3(e[l].end.x,e[l].end.y,0),_=new c.Vector3().subVectors(h,g).normalize(),v=.3,y=r.clone().addScaledVector(a,v),S=i.clone().addScaledVector(a.clone().negate(),v),w=h.clone().addScaledVector(_,v),T=g.clone().addScaledVector(_.clone().negate(),v);f(y,S,w,T);let E=b(y,S,w,T),D=r.distanceTo(h)>i.distanceTo(h)?i:r,O=D.distanceTo(h),k=D.distanceTo(g);if((O<m||k<m)&&E&&!E.isParallel){let i=r.distanceTo(h)<r.distanceTo(g)?h:g,a=!1;for(let r=0;r<e.length;r++){if(r==l||d.includes(r)||e[r].length<1)continue;let f=new c.Vector3(e[r].start.x,e[r].start.y,0),m=new c.Vector3(e[r].end.x,e[r].end.y,0),_=x(h,g,f,m);if(_&&_.angle>85){let _=new c.Line3(h,g),v=new c.Vector3,y=_.closestPointToPoint(f,!0,v),x=_.closestPointToPoint(m,!0,v),S=y.distanceTo(f),w=x.distanceTo(m),T,E;if(S>w&&w>u)T=m,E=x;else if(S<w&&S>u)T=f,E=y;else continue;if(S=i.distanceTo(f),w=i.distanceTo(m),S>2&&w>2)continue;let D=b(T,E,f,m);if(!D||!D.isParallel)continue;T.z=E.z=e[r].start.z;let O=!1;for(let e=0;e<p.length;e++){let t=C(p[e].start,p[e].end,T,E);if(t&&t.type==`collinear_overlap`){O=!0;break}}if(O)continue;p.push({start:T,end:E}),d.push(r);let k=e[r].rooftopPz-e[r].start.z,A=e[l].rooftopPz-e[l].start.z,j=k<A?k:A;e[r].doorAndBeamData.push({id:s,doorStart:T,doorEnd:E,doorHeight:j,nearId:-1,type:`onlyDoor`,isDoor:!0}),n[o[t].index].isFindBeam=!0,n[o[t].index].isFindOnlyDoor=!0,s++,a=!0;break}}if(a)break}}}let g=0;for(let t=0;t<e.length;t++){let n=e[t];n.mainBeamDataIds||=[],n.isMainBeam||=!1;let{minZ:r,maxZ:i}=O(n);if(r==null||i==null)continue;i-r;let o=n.rooftopPz-n.start.z;if(o<a-.5||o>a+2||Math.abs(r-n.start.z)>.3||n.length<1)continue;let s=new c.Vector3(n.start.x,n.start.y,0),l=new c.Vector3(n.end.x,n.end.y,0);for(let r=0;r<e.length;r++){if(r==t||e[r].length<1)continue;let a=e[r],o=new c.Vector3(a.start.x,a.start.y,0),u=new c.Vector3(a.end.x,a.end.y,0),d=b(s,l,o,u),f=S(s,l),p=new c.Line3(o,u).closestPointToPoint(f,!0,new c.Vector3),m=f.distanceTo(p),h=O(a);if(!(h.minZ===void 0||h.maxZ===void 0)&&!(h.maxZ-h.minZ>1)&&d&&d.isParallel&&m<.25&&Math.abs(i-h.minZ)<.1){let e=`mainBeamId${g}`;a.mainBeamDataIds||=[],a.isMainBeam||=!0,a.mainBeamDataIds.push(e),n.mainBeamDataIds.push(e),g++;break}}}return e},I=(e,t)=>{if(e.length<=0)return e;for(let t of e){let e=[];for(let n=0;n<t.checkResults.length;n++){let r=t.checkResults[n];if(r.isDoor=!1,!r.originalVertices||r.originalVertices.length==0)continue;let i=[];r.originalVertices.forEach(e=>{let t=[];e.forEach(e=>{t.push(new c.Vector3(e.x,e.y,e.z))}),i.push(t)});let a=i.length,o=Array.from({length:a},(e,t)=>t);function s(e){for(;o[e]!==e;)o[e]=o[o[e]],e=o[e];return e}for(let e=0;e<a;e++)for(let t=e+1;t<a;t++){let n=i[e],r=i[t];if(n.some(e=>r.some(t=>e.equals(t)))){let n=s(e),r=s(t);n!==r&&(o[n]=r)}}let l=new Map,u=-1,d=-1;for(let e=0;e<a;e++){let t=s(e);l.has(t)||l.set(t,{points:[],area:0,originalVertices:[],index:-1,gridWidth:-1,gridHeight:-1,centerPts:[]});let r=l.get(t),[a,o,f,p]=i[e],m=new c.Vector3().add(a).add(o).add(f).add(p).multiplyScalar(.25);if(r.points.push(...i[e]),r.area+=a.distanceTo(o)*a.distanceTo(p),r.originalVertices.push(i[e]),r.index=n,r.centerPts.push(m),u==-1||d==-1){let e=new c.Vector3().subVectors(a,o).normalize();d=a.distanceTo(p),u=a.distanceTo(o);let t=h(e,new c.Vector3(0,0,1));t&&t.parallel&&([d,u]=[u,d])}r.gridWidth=u,r.gridHeight=d}e.push(...l.values())}t.mergeCheckRegion=e}let n=new Map;for(let t of e){let e=t.rooftopPz-t.start.z,r=Math.floor(t.rooftopPz-t.start.z);n.has(r)?n.set(r,{num:n.get(r).num+1,totalHeight:n.get(r).totalHeight+e}):n.set(r,{num:1,totalHeight:e})}let r=[...n.entries()].reduce((e,t)=>t[1].num>e[1].num?t:e),i=r[0];r[1].totalHeight/r[1].num,new c.MeshBasicMaterial({color:`#cffd00`,transparent:!0,opacity:.4,side:c.DoubleSide}),new c.PointsMaterial({color:65535,size:.01});for(let n=0;n<e.length;n++){let r=e[n],{minZ:a,maxZ:o}=O(r);if(a==null||o==null)continue;r.doorAndBeamData=[],r.completePointAreaPercentage=-1,o-a;let s=r.rooftopPz-r.start.z;if(s<i-.5||s>i+2||Math.abs(a-r.start.z)>.3||r.length<1)continue;let l=new c.Vector3(r.start.x,r.start.y,0),u=new c.Vector3(r.end.x,r.end.y,0);for(let r=0;r<e.length;r++){if(r==n||e[r].length<1)continue;let i=e[r],a=new c.Vector3(i.start.x,i.start.y,0),s=new c.Vector3(i.end.x,i.end.y,0),d=b(l,u,a,s),f=S(l,u),m=new c.Line3(a,s).closestPointToPoint(f,!0,new c.Vector3),h=f.distanceTo(m),g=O(i);if(!(g.minZ===void 0||g.maxZ===void 0)&&!(g.maxZ-g.minZ>1)&&d&&d.isParallel&&h<.25&&Math.abs(o-g.minZ)<.1){let i=S(l,u),o=S(a,s);i.z=o.z=1,i.applyEuler(new c.Euler(-Math.PI/2,0,0)),o.applyEuler(new c.Euler(-Math.PI/2,0,0));let d=`w:${e[n].originaIndex},b:${e[r].originaIndex}`,f=`b:${e[r].originaIndex},w:${e[n].originaIndex}`;t.add(p(d,i,{textColor:`#fd0000`})),t.add(p(f,o,{textColor:`#fd0000`}))}}}return e};exports.classifySegments=C,exports.getAllGeometry=N,exports.getBeamLine=F,exports.getMainBeamLine=I,exports.getParallelism=b,exports.getPointCloudMinMax=O,exports.getPointCoverageOnQuad=E,exports.isParallel=h,exports.perpendicularInfo=x,exports.removeNoisePoints=k,exports.segmentsIntersect2D=f,exports.usegetBeamLine=P;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`three`);c=s(c);function l(e,t=!1){let n=e[0].index!==null,r=new Set(Object.keys(e[0].attributes)),i=new Set(Object.keys(e[0].morphAttributes)),a={},o={},s=e[0].morphTargetsRelative,l=new c.BufferGeometry,d=0;for(let c=0;c<e.length;++c){let u=e[c],f=0;if(n!==(u.index!==null))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.`),null;for(let e in u.attributes){if(!r.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. All geometries must have compatible attributes; make sure "`+e+`" attribute exists among all geometries, or in none of them.`),null;a[e]===void 0&&(a[e]=[]),a[e].push(u.attributes[e]),f++}if(f!==r.size)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. Make sure all geometries have the same number of attributes.`),null;if(s!==u.morphTargetsRelative)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. .morphTargetsRelative must be consistent throughout all geometries.`),null;for(let e in u.morphAttributes){if(!i.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. .morphAttributes must be consistent throughout all geometries.`),null;o[e]===void 0&&(o[e]=[]),o[e].push(u.morphAttributes[e])}if(t){let e;if(n)e=u.index.count;else if(u.attributes.position!==void 0)e=u.attributes.position.count;else return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+c+`. The geometry must have either an index or a position attribute`),null;l.addGroup(d,e,c),d+=e}}if(n){let t=0,n=[];for(let r=0;r<e.length;++r){let i=e[r].index;for(let e=0;e<i.count;++e)n.push(i.getX(e)+t);t+=e[r].attributes.position.count}l.setIndex(n)}for(let e in a){let t=u(a[e]);if(!t)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` attribute.`),null;l.setAttribute(e,t)}for(let e in o){let t=o[e][0].length;if(t===0)break;l.morphAttributes=l.morphAttributes||{},l.morphAttributes[e]=[];for(let n=0;n<t;++n){let t=[];for(let r=0;r<o[e].length;++r)t.push(o[e][r][n]);let r=u(t);if(!r)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` morphAttribute.`),null;l.morphAttributes[e].push(r)}}return l}function u(e){let t,n,r,i=-1,a=0;for(let o=0;o<e.length;++o){let s=e[o];if(t===void 0&&(t=s.array.constructor),t!==s.array.constructor)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.`),null;if(n===void 0&&(n=s.itemSize),n!==s.itemSize)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.`),null;if(r===void 0&&(r=s.normalized),r!==s.normalized)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.`),null;if(i===-1&&(i=s.gpuType),i!==s.gpuType)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.`),null;a+=s.count*n}let o=new t(a),s=new c.BufferAttribute(o,n,r),l=0;for(let t=0;t<e.length;++t){let r=e[t];if(r.isInterleavedBufferAttribute){let e=l/n;for(let t=0,i=r.count;t<i;t++)for(let i=0;i<n;i++){let n=r.getComponent(t,i);s.setComponent(t+e,i,n)}}else o.set(r.array,l);l+=r.count*n}return i!==void 0&&(s.gpuType=i),s}var d=class extends c.Object3D{constructor(e=document.createElement(`div`)){super(),this.isCSS2DObject=!0,this.element=e,this.element.style.position=`absolute`,this.element.style.userSelect=`none`,this.element.setAttribute(`draggable`,!1),this.center=new c.Vector2(.5,.5),this.addEventListener(`removed`,function(){this.traverse(function(e){e.element&&e.element instanceof e.element.ownerDocument.defaultView.Element&&e.element.parentNode!==null&&e.element.remove()})})}copy(e,t){return super.copy(e,t),this.element=e.element.cloneNode(!0),this.center=e.center,this}};new c.Vector3,new c.Matrix4,new c.Matrix4,new c.Vector3,new c.Vector3;var f=(e,t,n,r,i=1e-8)=>{let a=t.x-e.x,o=t.y-e.y,s=r.x-n.x,l=r.y-n.y,u=a*l-o*s;if(Math.abs(u)<i)return null;let d=((n.x-e.x)*l-(n.y-e.y)*s)/u,f=((n.x-e.x)*o-(n.y-e.y)*a)/u;return d<-i||d>1+i||f<-i||f>1+i?null:{point:new c.Vector3(e.x+d*a,e.y+d*o,e.z)}},p=(e,t,n={})=>{let{fontSize:r=36,fontFamily:i=`sans-serif`,backgroundColor:a=`rgba(0,0,0,0)`,textColor:o=`#ffffff`,padding:s=10,maxWidth:l=256}=n,u=document.createElement(`canvas`).getContext(`2d`);u.font=`bold ${r}px ${i}`;let d=u.measureText(e).width,f=Math.min(d+s*2,l),p=r+s*2,h=document.createElement(`canvas`);h.width=f,h.height=p;let g=h.getContext(`2d`);g.fillStyle=a,g.fillRect(0,0,f,p),g.fillStyle=o,g.font=`bold ${r}px ${i}`,g.textAlign=`center`,g.textBaseline=`middle`,d>l-s*2?m(g,e,f/2,p/2,l,r):g.fillText(e,f/2,p/2);let _=new c.CanvasTexture(h),v=new c.SpriteMaterial({map:_,depthTest:!1,transparent:!0}),y=new c.Sprite(v);y.position.set(t.x,t.y,t.z);let b=.005;return y.scale.set(f*b,p*b,1),y};function m(e,t,n,r,i,a){let o=t.split(``),s=``,c=a*1.2,l=r;for(let t=0;t<o.length;t++){let r=s+o[t];e.measureText(r).width>i&&t>0?(e.fillText(s,n,l),s=o[t],l+=c):s=r}e.fillText(s,n,l)}var h=(e,t,n=.01)=>{let r=Math.sqrt(e.x*e.x+e.y*e.y+e.z*e.z),i=Math.sqrt(t.x*t.x+t.y*t.y+t.z*t.z);if(r<1e-10||i<1e-10)return{parallel:!1,sameDirection:null,angle:NaN};let a={x:e.x/r,y:e.y/r,z:e.z/r},o={x:t.x/i,y:t.y/i,z:t.z/i},s=a.x*o.x+a.y*o.y+a.z*o.z;s=Math.max(-1,Math.min(1,s));let c=Math.acos(Math.abs(s)),l=c<=n;return{parallel:l,sameDirection:l?s>0:null,angle:c}};function g(e,t){let n=new c.BufferGeometry,r=[],i=[];e.forEach(e=>r.push(e.x,e.y,e.z)),t.forEach(e=>r.push(e.x,e.y,e.z)),i.push(0,2,1,0,3,2),i.push(4,5,6,4,6,7),i.push(0,1,5,0,5,4),i.push(1,2,6,1,6,5),i.push(2,3,7,2,7,6),i.push(3,0,4,3,4,7),n.setAttribute(`position`,new c.Float32BufferAttribute(r,3)),n.setIndex(i),n.computeVertexNormals();let a=new c.MeshBasicMaterial({color:`green`,transparent:!0,opacity:.5,side:c.DoubleSide});return new c.Mesh(n,a)}var _=class{constructor(e={}){this.config={value:e.value||`0.0000m`,position:e.position||new c.Vector3(0,0,0),style:{fontFamily:e.style?.fontFamily||`Arial, sans-serif`,fontSize:e.style?.fontSize||`16px`,fontWeight:e.style?.fontWeight||`normal`,fontStyle:e.style?.fontStyle||`normal`},backgroundOpacity:e.backgroundOpacity||.7},this.label=null,this.labelElement=null,this.createLabel()}createLabel(){return this.labelElement=document.createElement(`div`),this.labelElement.textContent=this.config.value,this.applyBlackWhiteStyle(),this.label=new d(this.labelElement),this.label.position.copy(this.config.position),this.label}applyBlackWhiteStyle(){let e=this.labelElement.style,t=this.config;e.fontFamily=t.style.fontFamily,e.fontSize=t.style.fontSize,e.fontWeight=t.style.fontWeight,e.fontStyle=t.style.fontStyle,e.color=`#FFFFFF`,e.textShadow=`0 1px 2px rgba(0, 0, 0, 0.5)`,e.backgroundColor=`rgba(0, 0, 0, ${t.backgroundOpacity})`,e.padding=`6px 12px`,e.borderRadius=`4px`,e.position=`absolute`,e.whiteSpace=`nowrap`,e.userSelect=`none`,e.pointerEvents=`none`,e.zIndex=`1000`,e.textAlign=`center`,e.lineHeight=`1.2`}updateValue(e){this.labelElement&&(this.labelElement.textContent=e)}updatePosition(e){this.label&&this.label.position.copy(e)}updateFontStyle(e){if(this.labelElement){let t=this.labelElement.style;e.fontFamily&&(t.fontFamily=e.fontFamily),e.fontSize&&(t.fontSize=e.fontSize),e.fontWeight&&(t.fontWeight=e.fontWeight),e.fontStyle&&(t.fontStyle=e.fontStyle)}}getLabel(){return this.label}getLabelElement(){return this.labelElement}dispose(){this.labelElement&&this.labelElement.parentNode&&this.labelElement.parentNode.removeChild(this.labelElement),this.label=null,this.labelElement=null}},v=e=>{let t=new c.Group;if(e&&e.length){let n=`green.red.pink.white.azure.yellow.bisque.grey.blanchedalmond.blue.blueviolet.brown.burlywood.cadetblue.chartreuse.chocolate.coral.cornflowerblue.cornsilk.crimson.cyan.darkblue.darkcyan.darkgoldenrod.darkgray.darkgreen.darkgrey.darkkhaki.darkmagenta.darkolivegreen.darkorange.darkorchid.darkred.darksalmon.darkseagreen.darkslateblue.darkslategray.darkslategrey.darkturquoise.darkviolet.deeppink.deepskyblue.dimgray.dimgrey.dodgerblue.firebrick.floralwhite.forestgreen.fuchsia.gainsboro.ghostwhite.gold.goldenrod.gray.aliceblue.greenyellow.black.honeydew.hotpink.indianred.indigo.ivory.khaki.lavender.lavenderblush.lawngreen.lemonchiffon.lightblue.lightcoral.lightcyan.lightgoldenrodyellow.lightgray.lightgreen.lightgrey.lightpink.lightsalmon.lightseagreen.lightskyblue.lightslategray.lightslategrey.lightsteelblue.lightyellow.lime.limegreen.linen.magenta.maroon.mediumaquamarine.mediumblue.mediumorchid.mediumpurple.mediumseagreen.mediumslateblue.mediumspringgreen.mediumturquoise.mediumvioletred.midnightblue.mintcream.mistyrose.moccasin.navajowhite.navy.oldlace.olive.olivedrab.orange.orangered.orchid.palegoldenrod.palegreen.paleturquoise.palevioletred.papayawhip.peachpuff.peru.pink.plum.powderblue.purple.rebeccapurple.yellow.rosybrown.royalblue.saddlebrown.salmon.sandybrown.seagreen.seashell.sienna.silver.skyblue.slateblue.slategray.slategrey.snow.springgreen.steelblue.tan.teal.thistle.tomato.turquoise.violet.wheat.white.whitesmoke.yellow.yellowgreen`.split(`.`);e.forEach((e,r)=>{let i=n[r],a=new c.Group,{pcdPoints:o,category:s,name:l,center:u,box:d,obbBox:f,contour:p,nline:m,coordinatesByWidth:h,coordinatesByArea:v}=e,y=o.length;if(s!=`door`)return;s===`balcony railing`&&console.log(`pcdObj`,e);let b=new c.Box3(new c.Vector3(d.min.x,d.min.y,d.min.z),new c.Vector3(d.max.x,d.max.y,d.max.z)),x=new c.Box3Helper(b,i);a.add(x);let S=new _({value:l,position:new c.Vector3(u.x,u.y,u.z)}).getLabel();a.add(S);let C=new c.InstancedMesh(new c.SphereGeometry(.007,8,8),new c.MeshBasicMaterial({color:i}),y);a.add(C);let w=new c.Matrix4,T=0;if(o.forEach(e=>{w.setPosition(e.x,e.y,e.z),C.setMatrixAt(T,w),T++}),C.instanceMatrix.needsUpdate=!0,m){let e=new c.BufferGeometry;e.setFromPoints([new c.Vector3(m.start.x,m.start.y,m.start.z),new c.Vector3(m.end.x,m.end.y,m.end.z)]);let t=new c.LineBasicMaterial({color:`red`,depthTest:!1,depthWrite:!1});new c.Line(e,t);let n=new c.Vector3().copy(new c.Vector3(m.start.x,m.start.y,m.start.z)).add(new c.Vector3(m.end.x,m.end.y,m.end.z)).multiplyScalar(.5),r=new c.Vector3(m.centerDir.x,m.centerDir.y,m.centerDir.z);new c.ArrowHelper(r,n,1,`red`)}if(p){let e=[];p.forEach((t,n)=>{e.push(new c.Vector3(t.x,t.y,t.z))});let n=new c.BufferGeometry;n.setFromPoints(e);let r=new c.LineBasicMaterial({color:`yellow`,depthTest:!1,depthWrite:!1}),i=new c.Line(n,r);t.add(i)}if(v){let e=[],n=[];v.coordinates.forEach((t,r)=>{e.push(new c.Vector3(t.x,t.y,t.z)),n.length<4&&n.push(new c.Vector3(t.x,t.y,t.z))});let r=new c.BufferGeometry;r.setFromPoints(e);let i=new c.LineBasicMaterial({color:`green`,depthTest:!1,depthWrite:!1}),a=new c.Line(r,i);t.add(a);let o=g(n.map(e=>new c.Vector3(e.x,e.y,v.heightData.minZ)),n.map(e=>new c.Vector3(e.x,e.y,e.z)));t.add(o);let[s,l,u]=e,d=s.distanceTo(l),f=new c.Vector3().copy(s).add(l).multiplyScalar(.5);new _({value:String(d.toFixed(3)),position:f}).getLabel();let p=l.distanceTo(u),m=new c.Vector3().copy(l).add(u).multiplyScalar(.5);new _({value:String(p.toFixed(3)),position:m}).getLabel()}if(f){let e=new c.BoxGeometry(f.size.x,f.size.y,f.size.z),n=new c.LineBasicMaterial({color:i,linewidth:2}),r=new c.EdgesGeometry(e),a=new c.LineSegments(r,n),o=new Vector3(f.center.x,f.center.y,f.center.z),s=new Quaternion(f.rotation.x,f.rotation.y,f.rotation.z,f.rotation.w);a.position.copy(o),a.quaternion.copy(s),t.add(a)}})}return t},y=(e,t,n,r)=>{let i=e,a=[];if(r&&r.length&&(a=r.map(e=>e.clone())),!i||i.length<4)return{};let o=new c.Vector3().subVectors(i[1],i[0]).normalize(),s=new c.Vector3().subVectors(i[3],i[0]).normalize(),l=o.clone().cross(s).normalize(),u=1/0,d=-1/0,f=1/0,p=-1/0;for(let e of i){let t=e.dot(o),n=e.dot(s);t<u&&(u=t),t>d&&(d=t),n<f&&(f=n),n>p&&(p=n)}let m=i[0].dot(l),g=o.clone().multiplyScalar(u).add(s.clone().multiplyScalar(f)).add(l.clone().multiplyScalar(m)),_=o.clone().multiplyScalar(d).add(s.clone().multiplyScalar(f)).add(l.clone().multiplyScalar(m)),v=o.clone().multiplyScalar(d).add(s.clone().multiplyScalar(p)).add(l.clone().multiplyScalar(m)),y=o.clone().multiplyScalar(u).add(s.clone().multiplyScalar(p)).add(l.clone().multiplyScalar(m)),b=[g,_,v,y],x=h(new c.Vector3().subVectors(g,_),new c.Vector3(0,0,1));x&&x.parallel&&(b=[g,y,v,_]);let S=0;if(r.length>0){let e=new c.Vector3().subVectors(b[1],b[0]).normalize(),r=e.clone().negate(),i=new c.Vector3().subVectors(b[3],b[0]).normalize(),o=i.clone().negate(),s=b[0].distanceTo(b[1]),l=b[0].distanceTo(b[3]),u=s/t,d=l/n,f=.001;for(let r=0;r<u;r++){let r=b[0],o=0;for(let s=0;s<d;s++){let s=r.clone().addScaledVector(e,t),l=s.clone().addScaledVector(i,n),u=r.clone().addScaledVector(i,n),d=new c.Vector3().add(r).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){o++;break}r=u}if(o>=d/2)break;S+=o,b[0]=b[0].addScaledVector(e,t),b[3]=b[3].addScaledVector(e,t)}s=b[0].distanceTo(b[1]),u=s/t;for(let e=0;e<u;e++){let e=b[1],o=0;for(let s=0;s<d;s++){let s=e.clone().addScaledVector(r,t),l=s.clone().addScaledVector(i,n),u=e.clone().addScaledVector(i,n),d=new c.Vector3().add(e).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){o++;break}e=u}if(o>=d/2)break;S+=o,b[1]=b[1].addScaledVector(r,t),b[2]=b[2].addScaledVector(r,t)}s=b[0].distanceTo(b[1]),u=s/t;for(let r=0;r<d;r++){let r=b[3],i=0;for(let s=0;s<u;s++){let s=r.clone().addScaledVector(e,t),l=s.clone().addScaledVector(o,n),u=r.clone().addScaledVector(o,n),d=new c.Vector3().add(r).add(s).add(l).add(u).multiplyScalar(.25);for(let e=0;e<a.length;e++)if(a[e].distanceTo(d)<f){i++;break}r=s}if(i>=u/2)break;S+=i,b[2]=b[2].addScaledVector(o,n),b[3]=b[3].addScaledVector(o,n)}}let C=b[0].distanceTo(b[1])*b[0].distanceTo(b[3]);return{facePoints:b,boxArea:C,totalInPlaneNum:S}},b=(e,t,n,r,i=c.MathUtils.degToRad(10))=>{let a=new c.Vector3,o=new c.Vector3;a.subVectors(new c.Vector3(t.x,t.y,0),new c.Vector3(e.x,e.y,0)).normalize(),o.subVectors(new c.Vector3(r.x,r.y,0),new c.Vector3(n.x,n.y,0)).normalize();let s=a.dot(o),l=Math.acos(Math.min(Math.abs(s),1)),u=1-Math.min(l/i,1),d=s>0?`same`:`opposite`;return{parallelism:u,angle:l,angleDeg:c.MathUtils.radToDeg(l),isParallel:l<i,direction:d,vectors:{v1:a,v2:o}}},x=(e,t,n,r)=>{let i=new c.Vector3().subVectors(t,e),a=new c.Vector3().subVectors(r,n),o=i.length(),s=a.length();if(o===0||s===0)return{rate:NaN,angle:NaN,isPerpendicular:!1,isParallel:!1};i.normalize(),a.normalize();let l=Math.abs(i.dot(a)),u=Math.min(1,Math.max(0,l)),d=Math.acos(u),f=c.MathUtils.radToDeg(d),p=1-u;return{rate:p,percent:`${(p*100).toFixed(2)}%`,angle:f,isPerpendicular:Math.abs(f-90)<.01,isParallel:f<.01}},S=(e,t,n=!1)=>new c.Vector3((e.x+t.x)/2,(e.y+t.y)/2,n?0:(e.z+t.z)/2),C=(e,t,n,r,i={})=>{let{parallelAngleMax:a=c.MathUtils.degToRad(10),collinearAngleMax:o=c.MathUtils.degToRad(7),distanceThreshold:s=2,overlapThreshold:l=.01}=i,u=new c.Vector3().subVectors(t,e),d=new c.Vector3().subVectors(r,n),f=u.clone().normalize(),p=d.clone().normalize(),m=c.MathUtils.clamp(f.dot(p),-1,1),h=Math.acos(Math.abs(m)),g=c.MathUtils.radToDeg(h);if(h>a)return{type:`not_parallel`,angleDeg:g,avgPerpendicularDistance:null,maxPerpendicularDistance:null,gap:null,overlap:null,closestDistance:null};m<0&&p.negate();let _=new c.Vector3().addVectors(f,p).normalize(),v=new c.Vector3().addVectors(e,t).multiplyScalar(.5),y=w(n,v,f),b=w(r,v,f),x=(y+b)/2,S=Math.max(y,b),C=e.dot(_),E=t.dot(_),D=n.dot(_),O=r.dot(_),k=Math.min(C,E),A=Math.max(C,E),j=Math.min(D,O),M=Math.max(D,O),N=A-k,P=M-j,F=Math.min(N,P),I=Math.min(A,M)-Math.max(k,j),L=I<0?-I:0,R=I>0?I:0,z=F>0?R/F:0,B=T(e,t,n,r),V=h<=o&&x<s,H;return V?H=z>.5?`collinear_overlap`:`collinear_gap`:h<=a&&(H=`parallel_offset`),{type:H,angleDeg:g,avgPerpendicularDistance:x,maxPerpendicularDistance:S,gap:L,overlap:R,closestDistance:B}};function w(e,t,n){let r=new c.Vector3().subVectors(e,t),i=r.dot(n),a=n.clone().multiplyScalar(i);return new c.Vector3().subVectors(r,a).length()}function T(e,t,n,r){let i=new c.Vector3().subVectors(t,e),a=new c.Vector3().subVectors(r,n),o=new c.Vector3().subVectors(n,e),s=i.dot(i),l=i.dot(a),u=a.dot(a),d=i.dot(o),f=a.dot(o),p=s*u-l*l,m,h;p<1e-10?(m=0,h=u===0?0:f/u):(m=(l*f-u*d)/p,h=(s*f-l*d)/p),m=c.MathUtils.clamp(m,0,1),h=u===0?0:c.MathUtils.clamp((l*m+f)/u,0,1),m=s===0?0:c.MathUtils.clamp((l*h-d)/s,0,1);let g=e.clone().add(i.clone().multiplyScalar(m)),_=n.clone().add(a.clone().multiplyScalar(h));return g.distanceTo(_)}var E=(e,t,n,r=.05,i=.02)=>{let[a,o,s,l]=e,u=new c.Vector3().subVectors(o,a),d=new c.Vector3().subVectors(l,a),f=new c.Vector3().crossVectors(u,d).normalize(),p=u.length(),m=d.length(),h=u.clone().normalize(),g=d.clone().normalize(),_=n-r,v=n+r,y=new c.Vector3,b=[],x=Math.ceil(p/i),S=Math.ceil(m/i),C=p/x,w=m/S,T=new Uint8Array(x*S);for(let e=0;e<t.length;e++){y.subVectors(t[e],a);let n=Math.abs(y.dot(f));if(n<_||n>v)continue;let r=y.dot(h),i=y.dot(g);if(r<0||r>p||i<0||i>m)continue;b.push(new c.Vector3(t[e].x,t[e].y,t[e].z));let o=Math.min(Math.floor(r/C),x-1),s=Math.min(Math.floor(i/w),S-1);T[s*x+o]=1}let E=0;for(let e=0;e<T.length;e++)T[e]&&E++;let D=x*S,O=p*m,k=E==0||D==0?0:E/D*O;return{filteredPoints:b,coveragePercent:E==0||D==0?0:E/D*100,quadArea:O,coveredArea:k}},D=(e,t)=>Math.round(Math.max(5,Math.min(350,t*Math.sqrt(e)))),O=e=>{let t=new c.Vector3(e.start.x,e.start.y,e.start.z),n=new c.Vector3(e.end.x,e.end.y,e.end.z),r=t.distanceTo(n),i=e.rooftopPz-e.start.z,a=D(r,100),o=D(i,70),s=i/o,l=new Map;for(let e=0;e<o;e++)l.set((e+1)*s,{count:0,minZ:1/0,maxZ:-1/0});let u=new c.Line3(t,n),d=e.originalPoints,f=new c.Vector3;for(let e=0;e<d.length;e++){let t=d[e],n=u.closestPointToPoint(t,!0,f).distanceTo(t),r=Math.floor(n/s);if(r<o){let e=l.get((r+1)*s);e.count++,t.z<e.minZ&&(e.minZ=t.z),t.z>e.maxZ&&(e.maxZ=t.z)}}let p,m,h=a/2;for(let[e,t]of l)if(t.count>=h){p=t.minZ;break}for(let[e,t]of[...l.entries()].reverse())if(t.count>=h){m=t.maxZ;break}return{minZ:p,maxZ:m}},k=(e,t,n)=>{let r=new c.Plane,i=new c.Vector3(e.x,e.y,e.z),a=new c.Vector3(t.x,t.y,t.z),o=new c.Vector3(t.x,t.y,t.z+5);r.setFromCoplanarPoints(i,a,o);let s=[];n.forEach(e=>{let t=new c.Vector3;r.projectPoint(e,t),t.z=i.z,s.push(t)});let l=new c.Vector3,u=new c.Vector3;r.projectPoint(i,l),r.projectPoint(a,u);let d=new c.Line3(l,u),f=[],p=new c.Vector3;return s.forEach((e,t)=>{d.closestPointToPoint(e,!0,p).distanceTo(e)<.001&&f.push(n[t])}),f},A=e=>{function t(e,t,n,r,i,a,o,s,l){let u=new c.Line3(e,t),d=new Map,f=new c.Vector3,p=e.clone(),m=t.clone(),h=0;for(;;){let g=new Map,_=0;for(let e=0;e<l.checkResults.length;e++)if(!(l.checkResults[e].allCenterPoints.length/s*100<1))for(let t=0;t<l.checkResults[e].allCenterPoints.length;t++){if(d.has(e)&&d.get(e).removePtsIndex.includes(t))continue;let n=l.checkResults[e].allCenterPoints[t];n=new c.Vector3(n.x,n.y,n.z);let r=u.closestPointToPoint(n,!0,f),a=n.distanceTo(r);Math.abs(a-i)<.01&&(_++,g.has(e)?g.get(e).removePtsIndex.push(t):g.set(e,{index:e,removePtsIndex:[t]}))}if(h==o){e=p,t=m;break}if(_<a/20*19||_==0){g.clear(),o-h<5&&(e=p,t=m,d.clear());break}else{h++;for(let[e,t]of g)d.has(e)?d.get(e).removePtsIndex.push(...t.removePtsIndex):d.set(e,t);g.clear(),e=e.addScaledVector(n,r),t=t.addScaledVector(n,r),u.set(e,t)}}if(d.size>0&&h!=o)for(let[e,t]of d){let n=[],r=[];for(let i=0;i<l.checkResults[e].allCenterPoints.length;i++)t.removePtsIndex.includes(i)||(n.push(l.checkResults[e].allCenterPoints[i]),r.push(l.checkResults[e].originalVertices[i]));l.checkResults[e].allCenterPoints=n,l.checkResults[e].originalVertices=r}}for(let n=0;n<e.length;n++){let r=e[n];if(r.length<.5)continue;let i=-1,a=-1;if(!r.checkResults||r.checkResults.length<=0)continue;if(r.checkResults[0].originalVertices&&r.checkResults[0].originalVertices.length>0){let[e,t,n,o]=r.checkResults[0].originalVertices[0];e=new c.Vector3(e.x,e.y,e.z),t=new c.Vector3(t.x,t.y,t.z),n=new c.Vector3(n.x,n.y,n.z),o=new c.Vector3(o.x,o.y,o.z),i=e.distanceTo(t),a=e.distanceTo(o);let s=h(new c.Vector3().subVectors(e,t).normalize(),new c.Vector3(0,0,1));s&&s.parallel&&([a,i]=[i,a])}if(i<0||a<0)continue;let o=new c.Vector3(r.start.x,r.start.y,r.start.z),s=new c.Vector3(r.end.x,r.end.y,r.end.z),l=o.distanceTo(s),u=r.rooftopPz-r.start.z,d=Math.ceil(l/i),f=Math.ceil(u/a),p=o.clone(),m=s.clone(),g=m.clone().add(new c.Vector3(0,0,u)),_=p.clone().add(new c.Vector3(0,0,u)),v=new c.Vector3().subVectors(m,p).normalize(),y=v.clone().negate();new c.Vector3().subVectors(g,p).normalize().clone().negate();let b=i/2;a/2;let x=l*u/(i*a);t(p,_,v,i,b,f,d,x,r),t(m,g,y,i,b,f,d,x,r),r.start=p,r.end=m,r.originalPoints=k(p,m,r.originalPoints)}},j=(e,t)=>new c.Vector3(e.x,e.y,0).distanceTo(new c.Vector3(t.x,t.y,0)),M=class{results;clusterResults;constructor(){this.results=null}initLimits1(e,t){let n,r;return n=e<.3?5:e<.5?8:e<.8?10:e<1?15:e<2?30:e<3?35:e<4?40:e<5?45:e<6?50:e<7?60:e<8.5?70:e<10?80:e<15?100:e<20?120:e<25?140:e<30?160:e<35?180:e<40?200:e<45?230:e<50?250:350,t<1?r=30:t<2?r=40:t<2.5?r=45:t<3?r=60:t<3.6?r=70:t<4&&(r=80),{horizontalSubdivisions:n,verticalSubdivisions:r}}initLimits2(e,t){return{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,e/.08))),verticalSubdivisions:Math.round(Math.max(30,Math.min(80,t/.06)))}}initLimits4(e,t){return{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,25*Math.sqrt(e))))*1,verticalSubdivisions:Math.round(Math.max(30,Math.min(80,25*Math.sqrt(t))))*1}}initLimits3(e,t){let n;return n=e<2?.06:e<10?.1:.15,{horizontalSubdivisions:Math.round(Math.max(5,Math.min(350,e/n))),verticalSubdivisions:Math.round(Math.max(30,Math.min(80,t/.06)))}}createWallPlaneMeshFromFourPoints(e,t,n,r,i,a,o=16777215){let s=[e,t,n,r];for(let e=0;e<s.length;e++)this.isValidVector3(s[e])||(console.error(`点${e+1}包含无效数据:`,s[e]),s[e]=new c.Vector3(e,0,e));let l=new c.BufferGeometry,u=new Float32Array([s[0].x,s[0].y,s[0].z,s[1].x,s[1].y,s[1].z,s[2].x,s[2].y,s[2].z,s[3].x,s[3].y,s[3].z]),d=[0,1,2,0,2,3],f=new Float32Array([0,0,1,0,1,1,0,1]);l.setAttribute(`position`,new c.BufferAttribute(u,3)),l.setAttribute(`uv`,new c.BufferAttribute(f,2)),l.setIndex(d),l.computeVertexNormals();let p=new c.Mesh(l,i),m=new c.EdgesGeometry(l),h=new c.LineSegments(m,new c.LineBasicMaterial({color:o}));return a.add(h),p}createSubdividedWallPlane(e,t,n,r,i){let a=[];if(!e||!e.start||!e.end||isNaN(e.rooftopPz))return a;let o=new c.Vector3(e.start.x,e.start.y,e.start.z),s=new c.Vector3(e.end.x,e.end.y,e.end.z),l=[o,s,new c.Vector3(e.end.x,e.end.y,e.rooftopPz),new c.Vector3(e.start.x,e.start.y,e.rooftopPz)];for(let e=0;e<l.length;e++)if(!this.isValidVector3(l[e]))return console.error(`墙体基础点${e}无效:`,l[e]),a;let u=o.distanceTo(s),d=Math.abs(e.rooftopPz-e.start.z);if(u===0||d===0)return console.error(`墙体宽度或高度为0`),console.log(`line.rooftopPz`,e.rooftopPz),console.log(`bottomLeft`,o),console.log(`bottomRight`,s),console.log(e.length),a;let f=u/n,p=d/t,m=new c.Vector3().subVectors(s,o).normalize(),h=new c.Vector3(0,0,1);for(let e=0;e<t;e++)for(let t=0;t<n;t++)try{let n={points:[new c.Vector3().copy(o).add(m.clone().multiplyScalar(t*f)).add(h.clone().multiplyScalar(e*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar((t+1)*f)).add(h.clone().multiplyScalar(e*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar((t+1)*f)).add(h.clone().multiplyScalar((e+1)*p)),new c.Vector3().copy(o).add(m.clone().multiplyScalar(t*f)).add(h.clone().multiplyScalar((e+1)*p))],userData:{}};n.userData={type:`wallSegment`,row:e,col:t,originalMaterial:r,width:f,height:p},a.push(n)}catch(n){console.error(`创建墙体小平面(${e}, ${t})时出错:`,n)}return a}calculateMinRequiredPoints(e){let t=Math.floor(Math.log1p(e)*.5);return Math.max(1,t)}calculateExpectedDensity(e){return e<1?10:e<4?5:2}evaluateSegmentByArea(e,t,n,r){if(t===0)return!1;let i=e.area,a=e.minRequiredPoints,o=e.expectedDensity,s=t/Math.max(i,.001),c=t>=a,l=s>=o*.3,u=!0;return i<.5&&t>0&&(u=this.checkSmallAreaDistribution(e,n,r)),c&&l&&u}checkSmallAreaDistribution(e,t,n){if(t.length<2)return!0;let r=t.map(e=>n[e]);e.bounds;let i=e.center,a=0,o=Math.sqrt(e.area)*.3;return r.forEach(e=>{e.distanceTo(i)<=o&&a++}),a/r.length>=.3}getFailureReason(e,t){let n=e.area,r=e.minRequiredPoints,i=e.expectedDensity,a=t/Math.max(n,.001),o=[];return t===0?o.push(`无点`):(t<r&&o.push(`点数不足: ${t}/${r}`),a<i*.3&&o.push(`密度不足: ${a.toFixed(2)}/${i.toFixed(2)}`),n<.5&&t>0&&(this.checkSmallAreaDistribution(e,[],[])||o.push(`小平面分布不均`))),o.length>0?o.join(`, `):`未知原因`}calculateMedian(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==0?(t[n-1]+t[n])/2:t[n]}isPointInBoundingBox(e,t,n=.1){return e.x>=t.min[0]-n&&e.x<=t.max[0]+n&&e.y>=t.min[1]-n&&e.y<=t.max[1]+n&&e.z>=t.min[2]-n&&e.z<=t.max[2]+n}getSegmentPlane(e){let t=e.geometry;if(!t||!t.attributes.position)return null;let n=t.attributes.position;if(n.count<3)return null;let r=new c.Vector3().fromBufferAttribute(n,0),i=new c.Vector3().fromBufferAttribute(n,1),a=new c.Vector3().fromBufferAttribute(n,2);r.applyMatrix4(e.matrixWorld),i.applyMatrix4(e.matrixWorld),a.applyMatrix4(e.matrixWorld);let o=new c.Plane;return o.setFromCoplanarPoints(r,i,a),o}analyzePointDistribution(e,t,n=.01){this.results={totalSegments:0,segmentsWithPoints:0,segmentsWithoutPoints:0,missingSegments:[],pointsInSegments:new Map,segmentsByPoint:new Map,segmentDetails:new Map,tolerance:n,analysisTime:null};let r=performance.now(),i=[];e.forEach(e=>{if(e.userData&&e.userData.type===`wallSegment`){let t=this.getWorldVerticesNew(e.points);if(t.length<4)return;let n=new c.Vector3().add(t[0]).add(t[1]).add(t[2]).add(t[3]).multiplyScalar(.25);e.userData.center=n,e.vertices=t,i.push(e)}}),this.results.totalSegments=i.length;for(let e of i){if(e.vertices.length<4)continue;let r=e.userData.center,i=`row${e.userData.row}_col${e.userData.col}`,[a,o,s,l]=e.vertices,u=new c.Vector3().subVectors(o,a).normalize(),d=new c.Vector3().subVectors(l,a).normalize(),f=a.distanceTo(o),p=a.distanceTo(l),m=new c.Plane;m.setFromCoplanarPoints(a,o,l);let h=f/2,g=p/2;for(let e=0;e<t.length;e++)this.isPointInWallSegmentOptimized(t[e],r,m,a,u,d,f,p,h,g,n)&&(this.results.pointsInSegments.has(i)||this.results.pointsInSegments.set(i,[]),this.results.pointsInSegments.get(i).push(e))}return i.forEach(e=>{let t=`row${e.userData.row}_col${e.userData.col}`,n=this.results.pointsInSegments.has(t)?this.results.pointsInSegments.get(t).length:0;n>=1?this.results.segmentsWithPoints++:(this.results.segmentsWithoutPoints++,this.results.missingSegments.push({row:e.userData.row,col:e.userData.col,width:e.userData.width,height:e.userData.height,segmentKey:t,vertices:e.vertices,center:e.userData.center,mesh:e,pointCount:n,hasPointsButNotEnough:n>0&&n<1}))}),this.results.analysisTime=performance.now()-r,this.printAnalysisResults(),this.results}isPointInWallSegmentOptimized(e,t,n,r,i,a,o,s,l,u,d){if(Math.abs(n.distanceToPoint(e))>d)return!1;let f=new c.Vector3().subVectors(e,t),p=Math.abs(f.dot(i)),m=Math.abs(f.dot(a));if(p>l&&m>u)return!1;let h=new c.Vector3().subVectors(e,r),g=h.dot(i),_=h.dot(a),v=g>=-d&&g<=o+d,y=_>=-d&&_<=s+d;return v&&y}isPointInWallSegment(e,t,n,r=.1){if(!e.geometry)return!1;try{let i=this.getWorldVertices(e);return i.length<4?!1:this.isPointInRotatedWall(i,t,n,r)}catch(e){return console.error(`判断点是否在墙体平面内时出错:`,e),!1}}isPointInRotatedWall(e,t,n,r=.1){let[i,a,o,s]=e,l=new c.Plane;if(l.setFromCoplanarPoints(i,a,s),Math.abs(l.distanceToPoint(t))>r)return!1;let u=new c.Vector3().subVectors(a,i).normalize(),d=new c.Vector3().subVectors(s,i).normalize();new c.Vector3().crossVectors(u,d).normalize();let f=new c.Vector3().subVectors(t,i),p=f.dot(u),m=f.dot(d),h=i.distanceTo(a),g=i.distanceTo(s),_=p>=-r&&p<=h+r,v=m>=-r&&m<=g+r;return _&&v&&n.distanceTo(t)<h/2&&n.distanceTo(t)<g/2}getWorldVertices(e){if(e._cachedWorldVertices&&e.matrixWorld.equals(e._cachedMatrixWorld))return e._cachedWorldVertices;let t=e.geometry.getAttribute(`position`),n=[];for(let r=0;r<Math.min(4,t.count);r++){let i=new c.Vector3;i.fromBufferAttribute(t,r),i.applyMatrix4(e.matrixWorld),n.push(i)}return e._cachedWorldVertices=n,e._cachedMatrixWorld=e.matrixWorld.clone(),n}getWorldVerticesNew(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n].clone();t.push(r)}return t}getWallSegmentBounds(e){if(!e.geometry)return null;let t=e.geometry.getAttribute(`position`),n=new c.Box3;for(let r=0;r<t.count;r++){let i=new c.Vector3;i.fromBufferAttribute(t,r),i.applyMatrix4(e.matrixWorld),n.expandByPoint(i)}return{min:n.min.toArray(),max:n.max.toArray(),center:n.getCenter(new c.Vector3).toArray(),size:n.getSize(new c.Vector3).toArray()}}highlightEmptySegments(e,t,n,r=1){if(!this.results){console.warn(`请先运行分析函数`);return}let i=new Map,a=new Map;this.results.missingSegments.forEach(e=>{i.set(e.segmentKey,e),a.has(e.row)||a.set(e.row,new Map),a.get(e.row).set(e.col,{segmentKey:e.segmentKey,isEmpty:!0,visited:!1})}),e.forEach(e=>{if(e.userData&&e.userData.type===`wallSegment`){let t=`row${e.userData.row}_col${e.userData.col}`,n=i.has(t);a.has(e.userData.row)||a.set(e.userData.row,new Map),a.get(e.userData.row).has(e.userData.col)||a.get(e.userData.row).set(e.userData.col,{segmentKey:t,isEmpty:n,visited:!1})}});let o=[],s=[[0,1],[1,0],[0,-1],[-1,0]];for(let[e,t]of i){let e=a.get(t.row)?.get(t.col);if(e&&!e.visited){let n=[],c=[[t.row,t.col]];for(e.visited=!0;c.length>0;){let[e,t]=c.shift(),r=`row${e}_col${t}`;i.has(r)&&n.push(i.get(r));for(let[n,r]of s){let i=e+n,o=t+r;if(a.has(i)&&a.get(i).has(o)){let e=a.get(i).get(o);!e.visited&&e.isEmpty&&(e.visited=!0,c.push([i,o]))}}}n.length>=r&&o.push(n)}}let c=this.createClusterMaterials(o.length),l=[];return this.clusterResults={clusters:o.sort((e,t)=>t.length-e.length),highlightedMeshes:l,clusterMaterials:c,totalClusters:o.length,totalHighlighted:l.length},this.clusterResults}calculateBoundaryRegularity(e,t,n,r,i){let a=0,o=0,s=t,c=!0;for(let t=r;t<=i;t++)e.has(s)&&e.get(s).has(t)?o++:c=!1;c&&a++;let l=n,u=!0;for(let t=r;t<=i;t++)e.has(l)&&e.get(l).has(t)?o++:u=!1;u&&a++;let d=r,f=!0;for(let r=t;r<=n;r++)e.has(r)&&e.get(r).has(d)?o++:f=!1;f&&a++;let p=i,m=!0;for(let r=t;r<=n;r++)e.has(r)&&e.get(r).has(p)?o++:m=!1;return m&&a++,a/4}calculateClusterQualityScore(e){let t=1/Math.max(1,e.aspectRatio);return e.compactness*.4+e.boundaryRegularity*.4+t*.2}calculateStrictClusterBounds(e){if(e.length===0)return{width:0,height:0};let t=[];if(e.forEach(e=>{e.vertices&&e.vertices.length>0&&t.push(...e.vertices)}),t.length===0){let t=[...new Set(e.map(e=>e.row))];return{width:[...new Set(e.map(e=>e.col))].length*(e[0].bounds?.width||1),height:t.length*(e[0].bounds?.height||1)}}let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y)),o=Math.min(...t.map(e=>e.z)),s=Math.max(...t.map(e=>e.z));return{width:Math.abs(r-n),height:Math.max(Math.abs(a-i),Math.abs(s-o))}}createClusterMaterials(e){let t=[],n=[16711935,65535,16753920,16738740,9055202,3329330,`lavenderblush`,`lawngreen`,`lemonchiffon`,`lightblue`,`lightcoral`];for(let r=0;r<e;r++){let e=n[r%n.length],i=new c.MeshBasicMaterial({color:e,transparent:!0,opacity:.6,side:c.DoubleSide});t.push(i)}return t}clearHighlights(e){this.clusterResults&&this.clusterResults.highlightedMeshes&&(this.clusterResults.highlightedMeshes.forEach(t=>{e.remove(t),t.material&&t.material.dispose()}),this.results&&this.results.segmentDetails&&this.results.segmentDetails.forEach((e,t)=>{e.mesh&&e.mesh.userData.originalMaterial&&(e.mesh.material=e.mesh.userData.originalMaterial)}),this.clusterResults.highlightedMeshes=[])}getClusterInfo(){return this.clusterResults?{totalClusters:this.clusterResults.totalClusters,clusterSizes:this.clusterResults.clusters.map((e,t)=>({clusterIndex:t,size:e.length,segments:e.map(e=>e.segmentKey)})),largestCluster:Math.max(...this.clusterResults.clusters.map(e=>e.length)),smallestCluster:Math.min(...this.clusterResults.clusters.map(e=>e.length))}:null}restoreOriginalMaterials(e){let t=0;e.traverse(e=>{e.userData&&e.userData.originalMaterial&&(e.material=e.userData.originalMaterial,delete e.userData.originalMaterial,t++)}),console.log(`恢复了 ${t} 个平面的原始材质`)}createDebugHelpers(e){let t=new c.Group;return e.traverse(e=>{if(e.userData&&e.userData.type===`wallSegment`){let n=this.getWorldVertices(e);if(n.length<4)return;let r=new c.Vector3().add(n[0]).add(n[1]).add(n[2]).add(n[3]).multiplyScalar(.25),i=new c.Vector3().subVectors(n[1],n[0]).normalize(),a=new c.Vector3().subVectors(n[3],n[0]).normalize(),o=new c.Vector3().crossVectors(i,a).normalize(),s=new c.ArrowHelper(o,r,.3,16711680),l=new c.ArrowHelper(i,r,.2,65280),u=new c.ArrowHelper(a,r,.2,255);t.add(s),t.add(l),t.add(u)}}),t}printAnalysisResults(){if(!this.results){console.warn(`没有可用的分析结果`);return}this.results.missingSegments.length>0&&this.results.missingSegments.forEach(e=>{}),this.results.pointsInSegments.forEach((e,t)=>{})}isValidVector3(e){return e&&!isNaN(e.x)&&!isNaN(e.y)&&!isNaN(e.z)&&isFinite(e.x)&&isFinite(e.y)&&isFinite(e.z)}mergeWallGroupMeshes(e){let t=[];if(e.traverse(e=>{e.isMesh&&e.geometry&&t.push(e)}),t.length===0)return null;try{let e=t.map(e=>e.geometry);e.forEach((e,n)=>{e.applyMatrix4(t[n].matrixWorld)});let n=l(e),r=t[0].material.clone(),i=new c.Mesh(n,r);return i.name=`mergedWalls`,i}catch(e){return console.error(`合并网格时出错:`,e),null}}},N=e=>{let t={},n=[],r=[],i=[];return e[0].width,e[0].height,e.forEach(e=>{r.push(...e.vertices),i.push(e.center),n.push(e.vertices)}),t.originalVertices=n,t.allCenterPoints=i,t},P=e=>{let t=new c.Vector3().copy(e.start).add(e.end).multiplyScalar(.5),n=new c.Vector3().subVectors(new c.Vector3(t.x,t.y,t.z+1),t).normalize(),r=new c.Vector3(e.direction.x,e.direction.y,0);r.applyAxisAngle(n,Math.PI/2);let i=new c.Vector3().copy(t).add(r.clone().multiplyScalar(e.length)),a=new c.Vector3().copy(t).sub(r.clone().multiplyScalar(e.length));return t.z=e.start.z,i.z=e.start.z,a.z=e.start.z,{start:i,end:a,center:t,direction:r}},F=(e,t,n=!0)=>{let r=[];if(!e)return[];for(let i=0;i<e.length;i++){let a=e[i];if(!a)continue;let o=new c.Vector3(a.start.x,a.start.y,a.start.z);o.applyEuler(new c.Euler(-Math.PI/2,0,0));let s=new c.Vector3(a.end.x,a.end.y,a.end.z);if(s.applyEuler(new c.Euler(-Math.PI/2,0,0)),t.add(p(String(i),new c.Vector3((o.x+s.x)/2,(o.y+s.y)/2,(o.z+s.z)/2))),(a.isBayWindow||a.isWindow)&&n)continue;let l=new c.Plane().setFromCoplanarPoints(new c.Vector3(a.start.x,a.start.y,a.start.z),new c.Vector3(a.end.x,a.end.y,a.end.z),new c.Vector3(a.start.x,a.start.y,a.rooftopPz)),u=[];a.originalPoints.forEach((e,t)=>{let n=new c.Vector3;l.projectPoint(e,n),u.push(n)});let d=new c.Vector3(a.start.x,a.start.y,a.start.z).distanceTo(new c.Vector3(a.end.x,a.end.y,a.end.z)),f=Math.abs(a.rooftopPz-a.start.z),m=new c.MeshBasicMaterial({color:`red`,side:c.DoubleSide,wireframe:!1,transparent:!0,opacity:.5}),h=new c.Group,g=new M,{horizontalSubdivisions:_,verticalSubdivisions:v}=g.initLimits4(d,f),y=g.createSubdividedWallPlane(a,v,_,m,h);g.analyzePointDistribution(y,u,.01);let b=new c.MeshBasicMaterial({color:`black`,transparent:!0,opacity:.8,side:c.DoubleSide}),x=g.highlightEmptySegments(y,b,h),S=[];for(let e of x.clusters){let t=N(e);t&&S.push(t)}let C=P(a).direction;a.checkResults=S,a.verticalDirection=C,a.originaIndex=i,r.push(a)}return r},I=async(e,t,n,r)=>{let i=await fetch(e);if(!i)return;let a=await i.json();for(let e=0;e<a.length;e++){let t=a[e];if(!t)continue;let n=new c.Vector3(t.start.x,t.start.y,t.start.z);n.applyEuler(new c.Euler(-Math.PI/2,0,0));let i=new c.Vector3(t.end.x,t.end.y,t.end.z);i.applyEuler(new c.Euler(-Math.PI/2,0,0)),r.add(p(String(e),new c.Vector3((n.x+i.x)/2,(n.y+i.y)/2,(n.z+i.z)/2)))}a.sort((e,t)=>e.originalIndex-t.originalIndex),console.log(`lins`,a);let o=await fetch(t);if(!o)return;let s=await o.json(),u=Array.isArray(s)?s:Object.values(s),d=await fetch(n);if(console.log(`respcd`,d),!d)return;let f=await d.json();console.time(),a=await L(a,u,f,r),console.timeEnd();let m=new c.MeshBasicMaterial({color:`#cffd00`,transparent:!0,opacity:.4,side:c.DoubleSide}),h=new c.MeshBasicMaterial({color:`#ff0000`,transparent:!0,opacity:.4,side:c.DoubleSide});new c.LineBasicMaterial({color:`#cffd00`});let g=new c.PointsMaterial({color:65535,size:.01}),_=[],y=[];for(let e of a){if(!e.originalPoints||e.originalPoints.length===0)continue;let t=new Float32Array(e.originalPoints.length*3);e.originalPoints.forEach((e,n)=>{t[n*3]=e.x,t[n*3+1]=e.y,t[n*3+2]=e.z});let n=new c.BufferGeometry;n.setAttribute(`position`,new c.BufferAttribute(t,3)),_.push(n);let r=[];r.push(new c.Vector3(e.start.x,e.start.y,e.start.z)),r.push(new c.Vector3(e.end.x,e.end.y,e.end.z));let i=new c.BufferGeometry;i.setFromPoints(r),y.push(i)}if(_.length>0){let e=l(_,!1);e.rotateX(-Math.PI/2),r.add(new c.Points(e,g)),_.forEach(e=>e.dispose())}let b=[],x=[],S=new c.LineBasicMaterial({color:`#f30606`}),C=new c.MeshBasicMaterial({color:`#071ac4`});for(let e=0;e<u.length;e++){let t=new c.SphereGeometry(.05);t.translate(u[e].x,u[e].y,u[e].z);let n=[],r=new c.Vector3(u[e].x,u[e].y,u[e].z),i=new c.Quaternion(u[e].qx,u[e].qy,u[e].qz,u[e].qw),a=new c.Vector3(0,0,-1).applyQuaternion(i),o=r.clone().addScaledVector(a,.001);n.push(r),n.push(o);let s=new c.BufferGeometry;s.setFromPoints(n),x.push(s),b.push(t)}if(b.length>0){let e=l(b,!1);e.rotateX(-Math.PI/2),r.add(new c.Mesh(e,C)),b.forEach(e=>e.dispose())}if(x.length>0){let e=l(x,!1);e.rotateX(-Math.PI/2),r.add(new c.Line(e,S)),x.forEach(e=>e.dispose())}let w=v(f);w.rotateX(-Math.PI/2),r.add(w),console.log(`jsonpcdData`,f),a.forEach(e=>{if(e.doorAndBeamData&&e.doorAndBeamData.length>0){let t=new c.Group;e.doorAndBeamData.forEach(e=>{if(e.beamStart){let n=new c.BufferGeometry,r=new Float32Array([e.beamStart.x,e.beamStart.y,e.beamStart.z,e.beamEnd.x,e.beamEnd.y,e.beamEnd.z,e.beamEnd.x,e.beamEnd.y,e.beamEnd.z+e.beamHeight,e.beamStart.x,e.beamStart.y,e.beamStart.z+e.beamHeight]);n.setAttribute(`position`,new c.BufferAttribute(r,3)),n.setIndex([0,1,2,0,2,3]),n.computeVertexNormals(),n.rotateX(-Math.PI/2),t.add(new c.Mesh(n,m))}let n=new c.BufferGeometry,r=new Float32Array([e.doorStart.x,e.doorStart.y,e.doorStart.z,e.doorEnd.x,e.doorEnd.y,e.doorEnd.z,e.doorEnd.x,e.doorEnd.y,e.doorEnd.z+e.doorHeight,e.doorStart.x,e.doorStart.y,e.doorStart.z+e.doorHeight]);n.setAttribute(`position`,new c.BufferAttribute(r,3)),n.setIndex([0,1,2,0,2,3]),n.computeVertexNormals(),n.rotateX(-Math.PI/2),t.add(new c.Mesh(n,h));let i=`id:${e.id},Nid:${e.nearId}`,a=new c.Vector3((e.doorStart.x+e.doorEnd.x)/2,(e.doorStart.y+e.doorEnd.y)/2,e.doorStart.z+e.doorHeight);a.applyEuler(new c.Euler(-Math.PI/2,0,0)),t.add(p(i,a))}),r.add(t)}})},L=async(e,t,n)=>{if(e.length<=0||t.length<=0)return e;n||=[];for(let t of e){let e=[];if(!(!t.checkResults||t.checkResults.length<=0)){for(let n=0;n<t.checkResults.length;n++){let r=t.checkResults[n];if(r.isDoor=!1,!r.originalVertices||r.originalVertices.length==0)continue;let i=[];r.originalVertices.forEach(e=>{let t=[];e.forEach(e=>{t.push(new c.Vector3(e.x,e.y,e.z))}),i.push(t)});let a=i.length,o=Array.from({length:a},(e,t)=>t);function s(e){for(;o[e]!==e;)o[e]=o[o[e]],e=o[e];return e}for(let e=0;e<a;e++)for(let t=e+1;t<a;t++){let n=i[e],r=i[t];if(n.some(e=>r.some(t=>e.equals(t)))){let n=s(e),r=s(t);n!==r&&(o[n]=r)}}let l=new Map,u=-1,d=-1;for(let e=0;e<a;e++){let t=s(e);l.has(t)||l.set(t,{points:[],area:0,originalVertices:[],index:-1,gridWidth:-1,gridHeight:-1,centerPts:[]});let r=l.get(t),[a,o,f,p]=i[e],m=new c.Vector3().add(a).add(o).add(f).add(p).multiplyScalar(.25);if(r.points.push(...i[e]),r.area+=a.distanceTo(o)*a.distanceTo(p),r.originalVertices.push(i[e]),r.index=n,r.centerPts.push(m),u==-1||d==-1){let e=new c.Vector3().subVectors(a,o).normalize();d=a.distanceTo(p),u=a.distanceTo(o);let t=h(e,new c.Vector3(0,0,1));t&&t.parallel&&([d,u]=[u,d])}r.gridWidth=u,r.gridHeight=d}e.push(...l.values())}t.mergeCheckRegion=e}}let r=new Map;for(let t of e){let e=t.rooftopPz-t.start.z,n=Math.floor(t.rooftopPz-t.start.z);r.has(n)?r.set(n,{num:r.get(n).num+1,totalHeight:r.get(n).totalHeight+e}):r.set(n,{num:1,totalHeight:e})}let i=[...r.entries()].reduce((e,t)=>t[1].num>e[1].num?t:e),a=i[0];i[1].totalHeight/i[1].num;let o=[];for(let e=0;e<n.length;e++){let t=n[e];if(t.isFindBeam=!1,t.category==`door`){let n=[];t.coordinatesByArea.coordinates.forEach(e=>{n.push(new c.Vector3(e.x,e.y,e.z))}),n[0].equals(n[n.length-1])&&n.pop();let r=n[0].distanceTo(n[1]),i=n[0].distanceTo(n[3]);i>r&&([r,i]=[i,r],n=[n[0],n[3],n[2],n[1]]);let a=S(n[0],n[3],!0),s=S(n[1],n[2],!0);o.push({doorStartPt:a,doorEndPt:s,boxPoints:n,minZ:t.coordinatesByArea.heightData.minZ,maxZ:t.coordinatesByArea.heightData.maxZ,index:e,isFind:!1})}}for(let t=0;t<o.length;t++){let n=o[t];for(let t=0;t<e.length;t++){if(e[t].length<.8)continue;let r=[],i=S(e[t].start,e[t].end,!0);r.push(i),r.push(S(i,e[t].start,!0)),r.push(S(i,e[t].end,!0));let a=!1,o=n.boxPoints.length;for(let e=0;e<r.length;e++){let t=r[e].x,i=r[e].y;for(let e=0,r=o-1;e<o;r=e++){let o=n.boxPoints[e].x,s=n.boxPoints[e].y,c=n.boxPoints[r].x,l=n.boxPoints[r].y;s>i!=l>i&&t<(c-o)*(i-s)/(l-s)+o&&(a=!a)}if(a)break}if(a){let r=new c.Vector3(e[t].start.x,e[t].start.y,0),i=new c.Vector3(e[t].end.x,e[t].end.y,0),a=n.doorStartPt.distanceTo(n.doorEndPt),o=r.distanceTo(i),s=b(n.doorStartPt,n.doorEndPt,r,i);if(Math.abs(o-a)<.5&&s&&s.isParallel){n.doorStartPt=new c.Vector3(e[t].start.x,e[t].start.y,0),n.doorEndPt=new c.Vector3(e[t].end.x,e[t].end.y,0);break}}else continue}}let s=0,l=[];for(let r=0;r<e.length;r++){let i=e[r];if(!i.mergeCheckRegion||i.mergeCheckRegion.length==0)continue;i.doorAndBeamData=[],i.completePointAreaPercentage=-1;let u=new c.Box3;u.setFromPoints(i.originalPoints);let d=u.max.z,p=u.min.z,m=new c.Vector3(i.start.x,i.start.y,i.start.z),h=new c.Vector3(i.end.x,i.end.y,i.end.z),g=i.rooftopPz-i.start.z;if(g<a-.5||g>a+2)continue;let _=0;for(let a of i.mergeCheckRegion){let{facePoints:u,boxArea:v,totalInPlaneNum:w}=y(a.points,a.gridWidth,a.gridHeight,a.centerPts);if(!u||u.length<=0)continue;_+=a.area;let T=0;if(w!=0&&(T=a.gridHeight*a.gridWidth*w),(a.area-T)/v*100>85){let _=u[0].distanceTo(u[1]),v=_/i.length*100,y=u[0].distanceTo(u[3]),w=i.rooftopPz-u[2].z;if(p>i.start.z-.15&&i.length<1.5||i.length,y<.5||d<u[2].z||w>g/3)continue;let T=!1,E=!1,D=!1,O=-1,A=u[2].clone(),M=u[3].clone(),N=u[0].clone(),P=u[1].clone(),F=!1;if(Math.abs(u[0].z-i.start.z)<.25){if(_>.2&&i.length>.5){let t=j(m,N),n=j(m,P),a=j(h,N),o=j(h,P),s=.1;if(t<s||n<s){let n=k(N,P,i.originalPoints),a=[],o=[];if(n.forEach(e=>{e.z>=A.z?a.push(e):e.z<=N.z&&o.push(e)}),a.length>0){let n=new c.Vector3(i.start.x,i.start.y,0),a=new c.Vector3(i.end.x,i.end.y,0),o=new c.Vector3().subVectors(n,a).normalize(),l=new c.Vector3,u=1/0,d=-1;for(let t=0;t<e.length;t++){if(t==r||e[t].length<.5)continue;let i=new c.Vector3(e[t].start.x,e[t].start.y,0),s=new c.Vector3(e[t].end.x,e[t].end.y,0);if(f(n,a,i,s)!=null)continue;let p=x(n,a,i,s);if(p&&p.angle>85){let e=b(n,a,new c.Line3(i,s).closestPointToPoint(n,!0,l),n);if(!e||e.direction!=`same`)continue;let r=f(n.clone().addScaledVector(o,10),a.clone().addScaledVector(o.clone().negate(),10),i,s);if(r==null)continue;let p=n.distanceTo(r.point);p<u&&(u=p,d=t)}}u!=1/0&&u<2&&(F=!0,console.log(`333333`,u,r,d,_),t<s?(M=M.addScaledVector(o,u),N=N.addScaledVector(o,u)):(A=A.addScaledVector(o,u),P=P.addScaledVector(o,u)))}}else if(a<s||o<s){let t=k(N,P,i.originalPoints),n=[],o=[];if(t.forEach(e=>{e.z>=A.z?n.push(e):e.z<=N.z&&o.push(e)}),n.length>0){let t=new c.Vector3(i.start.x,i.start.y,0),n=new c.Vector3(i.end.x,i.end.y,0),o=new c.Vector3().subVectors(n,t).normalize(),l=new c.Vector3,u=1/0,d=-1;for(let i=0;i<e.length;i++){if(i==r||e[i].length<.5)continue;let a=new c.Vector3(e[i].start.x,e[i].start.y,0),s=new c.Vector3(e[i].end.x,e[i].end.y,0);if(f(t,n,a,s)!=null)continue;let p=x(t,n,a,s);if(p&&p.angle>85){let e=b(n,t,new c.Line3(a,s).closestPointToPoint(n,!0,l),n);if(!e||e.direction!=`same`)continue;let r=f(t.clone().addScaledVector(o,10),n.clone().addScaledVector(o.clone().negate(),10),a,s);if(r==null)continue;let p=n.distanceTo(r.point);p<u&&(u=p,d=i)}}u!=1/0&&u<2&&(console.log(u,r,d,_),F=!0,a<s?(M=M.addScaledVector(o,u),N=N.addScaledVector(o,u)):(A=A.addScaledVector(o,u),P=P.addScaledVector(o,u)))}}_=M.distanceTo(A)}if(v<85&&_>.35||_>.7&&y>g-g/3){let e=!1;for(let n=0;n<t.length;n++){let r=n+1;if(r>=t.length)continue;let i=new c.Vector3(t[n].x,t[n].y,t[n].z),a=new c.Vector3(t[r].x,t[r].y,t[r].z);if(f(new c.Vector3(i.x,i.y,0),new c.Vector3(a.x,a.y,0),new c.Vector3(u[0].x,u[0].y,0),new c.Vector3(u[1].x,u[1].y,0),.1)!=null){e=!0;break}}for(let e=0;e<o.length;e++){let t=new c.Vector3(o[e].doorStartPt.x,o[e].doorStartPt.y,0),r=new c.Vector3(o[e].doorEndPt.x,o[e].doorEndPt.y,0),a=new c.Vector3(u[0].x,u[0].y,0),s=new c.Vector3(u[1].x,u[1].y,0),l=new c.Vector3().subVectors(t,r).normalize(),d=new c.Vector3().subVectors(a,s).normalize(),p=.2,m=f(t.clone().addScaledVector(l,p),r.clone().addScaledVector(l.clone().negate(),p),a.clone().addScaledVector(d,p),s.clone().addScaledVector(d.clone().negate(),p)),h=u[2].z<o[e].maxZ||Math.abs(u[2].z-o[e].maxZ)<.3,g=b(t.clone(),r.clone(),a.clone(),s.clone());if(m&&h)n[o[e].index].isFindBeam=!0,E=!0,o[e].isFind=!0;else if(h&&g&&g.isParallel){let a=S(t,r),s=new c.Line3(new c.Vector3(i.start.x,i.start.y,0),new c.Vector3(i.end.x,i.end.y,0)),l=new c.Vector3,u=s.closestPointToPoint(a,!0,l);a.distanceTo(u)<.3&&(n[o[e].index].isFindBeam=!0)}}if(!E)for(let e=0;e<o.length;e++){let t=new c.Vector3(o[e].doorStartPt.x,o[e].doorStartPt.y,0),r=new c.Vector3(o[e].doorEndPt.x,o[e].doorEndPt.y,0),a=new c.Vector3(u[0].x,u[0].y,0),s=new c.Vector3(u[1].x,u[1].y,0),l=u[2].z<o[e].maxZ||Math.abs(u[2].z-o[e].maxZ)<.3,d=Math.abs(u[2].z-o[e].maxZ)>.2;if(l&&!d){let l=C(t.clone(),r.clone(),a.clone(),s.clone(),{distanceThreshold:2});if(l&&l.type==`collinear_gap`){let d=S(t,r),f=new c.Line3(new c.Vector3(i.start.x,i.start.y,0),new c.Vector3(i.end.x,i.end.y,0)),p=new c.Vector3,m=f.closestPointToPoint(d,!0,p);if(d.distanceTo(m)<.15){let i=a.distanceTo(t),d=s.distanceTo(t);if(i>.25&&d>.25){let e=a.distanceTo(r),t=s.distanceTo(r);if(e>.2&&t>.2)continue}E=!0,D=!0,O=o[e].index,o[e].isFind=!0,n[o[e].index].isFindBeam=!0;let f=new c.Vector3().subVectors(a,s).normalize(),p=t.distanceTo(r)-l.overlap;d<i&&f.negate(),i>d?(A=u[2].clone().addScaledVector(f,p),M=u[3].clone(),N=A.clone(),P=M.clone(),N.z=P.z=u[0].z):(A=u[2].clone(),M=u[3].clone().addScaledVector(f,p),N=A.clone(),P=M.clone(),N.z=P.z=u[0].z)}}else if(l&&l.type==`collinear_overlap`){let i=a.distanceTo(s),c=r.distanceTo(t);(Math.abs(i-l.overlap)<.25||Math.abs(c-l.overlap)<.25)&&(E=!0,D=!0,O=o[e].index,o[e].isFind=!0,n[o[e].index].isFindBeam=!0)}}}(E||e||y>g/2&&_>.8&&Math.abs(p-i.start.z)<.4)&&(T=!0)}}if(T){i.checkResults[a.index].isDoor=!0;let t={id:s,beamStart:A,beamEnd:M,beamHeight:i.rooftopPz-u[2].z,doorStart:N,doorEnd:P,doorHeight:y,nearId:-1,type:F?`extendBeam`:`doorBeam`,isDoor:E,isPullOutDoor:D,pcbDoorIndex:O};for(let n=0;n<l.length;n++){let r=e[l[n].linesIndex].doorAndBeamData[l[n].doorIndex];if(r.nearId!=-1)continue;let i=b(A.clone(),M.clone(),r.beamStart.clone(),r.beamEnd.clone());if(i&&i.isParallel){let e=A.distanceTo(M),n=r.beamStart.distanceTo(r.beamEnd),i=new c.Line3(A.clone(),M.clone());i.start.z=0,i.end.z=0;let a=S(r.beamStart,r.beamEnd,!0);n>e&&(i.start=new c.Vector3(r.beamStart.x,r.beamStart.y,0),i.end=new c.Vector3(r.beamEnd.x,r.beamEnd.y,0),a=S(A,M,!0));let o=new c.Vector3,l=i.closestPointToPoint(a,!0,o),u=l.distanceTo(a),d=new c.Vector3().subVectors(a,l).normalize(),p=d.clone().negate(),m=a.clone().addScaledVector(p,u+.1),h=f(i.start,i.end,a,m);if(u<.5&&h!=null){r.nearId=s,t.nearId=r.id;let i=.8;(r.isDoor||t.isDoor)&&(r.isDoor=!0,t.isDoor=!0),e<n?e>i&&!r.isPullOutDoor?(r.beamStart=A.clone().addScaledVector(p,u),r.beamEnd=M.clone().addScaledVector(p,u),r.doorStart=N.clone().addScaledVector(p,u),r.doorEnd=P.clone().addScaledVector(p,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):!D||D&&r.isPullOutDoor&&O==r.pcbDoorIndex?(t.beamStart=r.beamStart.clone().addScaledVector(d,u),t.beamEnd=r.beamEnd.clone().addScaledVector(d,u),t.doorStart=r.doorStart.clone().addScaledVector(d,u),t.doorEnd=r.doorEnd.clone().addScaledVector(d,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight):(r.beamStart=A.clone().addScaledVector(p,u),r.beamEnd=M.clone().addScaledVector(p,u),r.doorStart=N.clone().addScaledVector(p,u),r.doorEnd=P.clone().addScaledVector(p,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):e>n&&(n>i&&!D?(t.beamStart=r.beamStart.clone().addScaledVector(p,u),t.beamEnd=r.beamEnd.clone().addScaledVector(p,u),t.doorStart=r.doorStart.clone().addScaledVector(p,u),t.doorEnd=r.doorEnd.clone().addScaledVector(p,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight):!r.isPullOutDoor||D&&r.isPullOutDoor&&O==r.pcbDoorIndex?(r.beamStart=A.clone().addScaledVector(d,u),r.beamEnd=M.clone().addScaledVector(d,u),r.doorStart=N.clone().addScaledVector(d,u),r.doorEnd=P.clone().addScaledVector(d,u),r.doorHeight=t.doorHeight,r.beamStart.z=r.beamEnd.z=r.doorStart.z+r.doorHeight):(t.beamStart=r.beamStart.clone().addScaledVector(p,u),t.beamEnd=r.beamEnd.clone().addScaledVector(p,u),t.doorStart=r.doorStart.clone().addScaledVector(p,u),t.doorEnd=r.doorEnd.clone().addScaledVector(p,u),t.doorHeight=r.doorHeight,t.beamStart.z=t.beamEnd.z=t.doorStart.z+t.doorHeight));break}}}i.doorAndBeamData.push(t),l.push({linesIndex:r,doorIndex:i.doorAndBeamData.length-1}),s++}}}let v=i.length*(i.rooftopPz-i.start.z);i.completePointAreaPercentage=_/v*100}let u=.65,d=[],p=[],m=.2;for(let t=0;t<o.length;t++){if(o[t].isFind)continue;let r=new c.Vector3(o[t].doorStartPt.x,o[t].doorStartPt.y,0),i=new c.Vector3(o[t].doorEndPt.x,o[t].doorEndPt.y,0),a=new c.Vector3().subVectors(r,i).normalize();for(let l=0;l<e.length;l++){if(e[l].length<1||e[l].completePointAreaPercentage>60)continue;let h=new c.Vector3(e[l].start.x,e[l].start.y,0),g=new c.Vector3(e[l].end.x,e[l].end.y,0),_=new c.Vector3().subVectors(h,g).normalize(),v=.3,y=r.clone().addScaledVector(a,v),S=i.clone().addScaledVector(a.clone().negate(),v),w=h.clone().addScaledVector(_,v),T=g.clone().addScaledVector(_.clone().negate(),v);f(y,S,w,T);let E=b(y,S,w,T),D=r.distanceTo(h)>i.distanceTo(h)?i:r,O=D.distanceTo(h),k=D.distanceTo(g);if((O<m||k<m)&&E&&!E.isParallel){let i=r.distanceTo(h)<r.distanceTo(g)?h:g,a=!1;for(let r=0;r<e.length;r++){if(r==l||d.includes(r)||e[r].length<1)continue;let f=new c.Vector3(e[r].start.x,e[r].start.y,0),m=new c.Vector3(e[r].end.x,e[r].end.y,0),_=x(h,g,f,m);if(_&&_.angle>85){let _=new c.Line3(h,g),v=new c.Vector3,y=_.closestPointToPoint(f,!0,v),x=_.closestPointToPoint(m,!0,v),S=y.distanceTo(f),w=x.distanceTo(m),T,E;if(S>w&&w>u)T=m,E=x;else if(S<w&&S>u)T=f,E=y;else continue;if(S=i.distanceTo(f),w=i.distanceTo(m),S>2&&w>2)continue;let D=b(T,E,f,m);if(!D||!D.isParallel)continue;T.z=E.z=e[r].start.z;let O=!1;for(let e=0;e<p.length;e++){let t=C(p[e].start,p[e].end,T,E);if(t&&t.type==`collinear_overlap`){O=!0;break}}if(O)continue;p.push({start:T,end:E}),d.push(r);let k=e[r].rooftopPz-e[r].start.z,A=e[l].rooftopPz-e[l].start.z,j=k<A?k:A;e[r].doorAndBeamData.push({id:s,doorStart:T,doorEnd:E,doorHeight:j,nearId:-1,type:`onlyDoor`,isDoor:!0}),n[o[t].index].isFindBeam=!0,n[o[t].index].isFindOnlyDoor=!0,s++,a=!0;break}}if(a)break}}}let g=0;for(let t=0;t<e.length;t++){let n=e[t];n.mainBeamDataIds||=[],n.isMainBeam||=!1;let{minZ:r,maxZ:i}=O(n);if(r==null||i==null)continue;i-r;let o=n.rooftopPz-n.start.z;if(o<a-.5||o>a+2||Math.abs(r-n.start.z)>.3||n.length<1)continue;let s=new c.Vector3(n.start.x,n.start.y,0),l=new c.Vector3(n.end.x,n.end.y,0);for(let r=0;r<e.length;r++){if(r==t||e[r].length<1)continue;let a=e[r],o=new c.Vector3(a.start.x,a.start.y,0),u=new c.Vector3(a.end.x,a.end.y,0),d=b(s,l,o,u),f=S(s,l),p=new c.Line3(o,u).closestPointToPoint(f,!0,new c.Vector3),m=f.distanceTo(p),h=O(a);if(!(h.minZ===void 0||h.maxZ===void 0)&&!(h.maxZ-h.minZ>1)&&d&&d.isParallel&&m<.25&&Math.abs(i-h.minZ)<.1){let e=`mainBeamId${g}`;a.mainBeamDataIds||=[],a.isMainBeam||=!0,a.mainBeamDataIds.push(e),n.mainBeamDataIds.push(e),g++;break}}}return e},R=(e,t)=>{if(e.length<=0)return e;for(let t of e){let e=[];for(let n=0;n<t.checkResults.length;n++){let r=t.checkResults[n];if(r.isDoor=!1,!r.originalVertices||r.originalVertices.length==0)continue;let i=[];r.originalVertices.forEach(e=>{let t=[];e.forEach(e=>{t.push(new c.Vector3(e.x,e.y,e.z))}),i.push(t)});let a=i.length,o=Array.from({length:a},(e,t)=>t);function s(e){for(;o[e]!==e;)o[e]=o[o[e]],e=o[e];return e}for(let e=0;e<a;e++)for(let t=e+1;t<a;t++){let n=i[e],r=i[t];if(n.some(e=>r.some(t=>e.equals(t)))){let n=s(e),r=s(t);n!==r&&(o[n]=r)}}let l=new Map,u=-1,d=-1;for(let e=0;e<a;e++){let t=s(e);l.has(t)||l.set(t,{points:[],area:0,originalVertices:[],index:-1,gridWidth:-1,gridHeight:-1,centerPts:[]});let r=l.get(t),[a,o,f,p]=i[e],m=new c.Vector3().add(a).add(o).add(f).add(p).multiplyScalar(.25);if(r.points.push(...i[e]),r.area+=a.distanceTo(o)*a.distanceTo(p),r.originalVertices.push(i[e]),r.index=n,r.centerPts.push(m),u==-1||d==-1){let e=new c.Vector3().subVectors(a,o).normalize();d=a.distanceTo(p),u=a.distanceTo(o);let t=h(e,new c.Vector3(0,0,1));t&&t.parallel&&([d,u]=[u,d])}r.gridWidth=u,r.gridHeight=d}e.push(...l.values())}t.mergeCheckRegion=e}let n=new Map;for(let t of e){let e=t.rooftopPz-t.start.z,r=Math.floor(t.rooftopPz-t.start.z);n.has(r)?n.set(r,{num:n.get(r).num+1,totalHeight:n.get(r).totalHeight+e}):n.set(r,{num:1,totalHeight:e})}let r=[...n.entries()].reduce((e,t)=>t[1].num>e[1].num?t:e),i=r[0];r[1].totalHeight/r[1].num,new c.MeshBasicMaterial({color:`#cffd00`,transparent:!0,opacity:.4,side:c.DoubleSide}),new c.PointsMaterial({color:65535,size:.01});for(let n=0;n<e.length;n++){let r=e[n],{minZ:a,maxZ:o}=O(r);if(a==null||o==null)continue;r.doorAndBeamData=[],r.completePointAreaPercentage=-1,o-a;let s=r.rooftopPz-r.start.z;if(s<i-.5||s>i+2||Math.abs(a-r.start.z)>.3||r.length<1)continue;let l=new c.Vector3(r.start.x,r.start.y,0),u=new c.Vector3(r.end.x,r.end.y,0);for(let r=0;r<e.length;r++){if(r==n||e[r].length<1)continue;let i=e[r],a=new c.Vector3(i.start.x,i.start.y,0),s=new c.Vector3(i.end.x,i.end.y,0),d=b(l,u,a,s),f=S(l,u),m=new c.Line3(a,s).closestPointToPoint(f,!0,new c.Vector3),h=f.distanceTo(m),g=O(i);if(!(g.minZ===void 0||g.maxZ===void 0)&&!(g.maxZ-g.minZ>1)&&d&&d.isParallel&&h<.25&&Math.abs(o-g.minZ)<.1){let i=S(l,u),o=S(a,s);i.z=o.z=1,i.applyEuler(new c.Euler(-Math.PI/2,0,0)),o.applyEuler(new c.Euler(-Math.PI/2,0,0));let d=`w:${e[n].originaIndex},b:${e[r].originaIndex}`,f=`b:${e[r].originaIndex},w:${e[n].originaIndex}`;t.add(p(d,i,{textColor:`#fd0000`})),t.add(p(f,o,{textColor:`#fd0000`}))}}}return e};exports.classifySegments=C,exports.getAllGeometry=F,exports.getBeamLine=L,exports.getMainBeamLine=R,exports.getParallelism=b,exports.getPointCloudMinMax=O,exports.getPointCoverageOnQuad=E,exports.isParallel=h,exports.perpendicularInfo=x,exports.removeNoisePoints=A,exports.segmentsIntersect2D=f,exports.usegetBeamLine=I;
package/dist/index.js CHANGED
@@ -295,25 +295,27 @@ var g = class {
295
295
  v,
296
296
  y
297
297
  ], x = m(new e.Vector3().subVectors(g, _), new e.Vector3(0, 0, 1));
298
- if (x && x.parallel && (b = [
298
+ x && x.parallel && (b = [
299
299
  g,
300
300
  y,
301
301
  v,
302
302
  _
303
- ]), i.length > 0) {
303
+ ]);
304
+ let S = 0;
305
+ if (i.length > 0) {
304
306
  let t = new e.Vector3().subVectors(b[1], b[0]).normalize(), i = t.clone().negate(), a = new e.Vector3().subVectors(b[3], b[0]).normalize(), s = a.clone().negate(), c = b[0].distanceTo(b[1]), l = b[0].distanceTo(b[3]), u = c / n, d = l / r, f = .001;
305
307
  for (let i = 0; i < u; i++) {
306
308
  let i = b[0], s = 0;
307
309
  for (let c = 0; c < d; c++) {
308
310
  let c = i.clone().addScaledVector(t, n), l = c.clone().addScaledVector(a, r), u = i.clone().addScaledVector(a, r), d = new e.Vector3().add(i).add(c).add(l).add(u).multiplyScalar(.25);
309
311
  for (let e = 0; e < o.length; e++) if (o[e].distanceTo(d) < f) {
310
- s++, o.splice(e, 1);
312
+ s++;
311
313
  break;
312
314
  }
313
315
  i = u;
314
316
  }
315
317
  if (s >= d / 2) break;
316
- b[0] = b[0].addScaledVector(t, n), b[3] = b[3].addScaledVector(t, n);
318
+ S += s, b[0] = b[0].addScaledVector(t, n), b[3] = b[3].addScaledVector(t, n);
317
319
  }
318
320
  c = b[0].distanceTo(b[1]), u = c / n;
319
321
  for (let t = 0; t < u; t++) {
@@ -321,13 +323,13 @@ var g = class {
321
323
  for (let c = 0; c < d; c++) {
322
324
  let c = t.clone().addScaledVector(i, n), l = c.clone().addScaledVector(a, r), u = t.clone().addScaledVector(a, r), d = new e.Vector3().add(t).add(c).add(l).add(u).multiplyScalar(.25);
323
325
  for (let e = 0; e < o.length; e++) if (o[e].distanceTo(d) < f) {
324
- s++, o.splice(e, 1);
326
+ s++;
325
327
  break;
326
328
  }
327
329
  t = u;
328
330
  }
329
331
  if (s >= d / 2) break;
330
- b[1] = b[1].addScaledVector(i, n), b[2] = b[2].addScaledVector(i, n);
332
+ S += s, b[1] = b[1].addScaledVector(i, n), b[2] = b[2].addScaledVector(i, n);
331
333
  }
332
334
  c = b[0].distanceTo(b[1]), u = c / n;
333
335
  for (let i = 0; i < d; i++) {
@@ -335,19 +337,20 @@ var g = class {
335
337
  for (let c = 0; c < u; c++) {
336
338
  let c = i.clone().addScaledVector(t, n), l = c.clone().addScaledVector(s, r), u = i.clone().addScaledVector(s, r), d = new e.Vector3().add(i).add(c).add(l).add(u).multiplyScalar(.25);
337
339
  for (let e = 0; e < o.length; e++) if (o[e].distanceTo(d) < f) {
338
- a++, o.splice(e, 1);
340
+ a++;
339
341
  break;
340
342
  }
341
343
  i = c;
342
344
  }
343
345
  if (a >= u / 2) break;
344
- b[2] = b[2].addScaledVector(s, r), b[3] = b[3].addScaledVector(s, r);
346
+ S += a, b[2] = b[2].addScaledVector(s, r), b[3] = b[3].addScaledVector(s, r);
345
347
  }
346
348
  }
347
- let S = b[0].distanceTo(b[1]) * b[0].distanceTo(b[3]);
349
+ let C = b[0].distanceTo(b[1]) * b[0].distanceTo(b[3]);
348
350
  return {
349
351
  facePoints: b,
350
- boxArea: S
352
+ boxArea: C,
353
+ totalInPlaneNum: S
351
354
  };
352
355
  }, y = (t, n, r, i, a = e.MathUtils.degToRad(10)) => {
353
356
  let o = new e.Vector3(), s = new e.Vector3();
@@ -463,8 +466,22 @@ var T = (t, n, r, i = .05, a = .02) => {
463
466
  minZ: p,
464
467
  maxZ: m
465
468
  };
466
- }, O = (t, n) => {
467
- function r(t, n, r, i, a, o, s, c, l) {
469
+ }, O = (t, n, r) => {
470
+ let i = new e.Plane(), a = new e.Vector3(t.x, t.y, t.z), o = new e.Vector3(n.x, n.y, n.z), s = new e.Vector3(n.x, n.y, n.z + 5);
471
+ i.setFromCoplanarPoints(a, o, s);
472
+ let c = [];
473
+ r.forEach((t) => {
474
+ let n = new e.Vector3();
475
+ i.projectPoint(t, n), n.z = a.z, c.push(n);
476
+ });
477
+ let l = new e.Vector3(), u = new e.Vector3();
478
+ i.projectPoint(a, l), i.projectPoint(o, u);
479
+ let d = new e.Line3(l, u), f = [], p = new e.Vector3();
480
+ return c.forEach((e, t) => {
481
+ d.closestPointToPoint(e, !0, p).distanceTo(e) < .001 && f.push(r[t]);
482
+ }), f;
483
+ }, k = (t) => {
484
+ function n(t, n, r, i, a, o, s, c, l) {
468
485
  let u = new e.Line3(t, n), d = /* @__PURE__ */ new Map(), f = new e.Vector3(), p = t.clone(), m = n.clone(), h = 0;
469
486
  for (;;) {
470
487
  let g = /* @__PURE__ */ new Map(), _ = 0;
@@ -497,8 +514,8 @@ var T = (t, n, r, i = .05, a = .02) => {
497
514
  l.checkResults[e].allCenterPoints = n, l.checkResults[e].originalVertices = r;
498
515
  }
499
516
  }
500
- for (let n = 0; n < t.length; n++) {
501
- let i = t[n];
517
+ for (let r = 0; r < t.length; r++) {
518
+ let i = t[r];
502
519
  if (i.length < .5) continue;
503
520
  let a = -1, o = -1;
504
521
  if (!i.checkResults || i.checkResults.length <= 0) continue;
@@ -514,22 +531,9 @@ var T = (t, n, r, i = .05, a = .02) => {
514
531
  let b = a / 2;
515
532
  o / 2;
516
533
  let x = l * u / (a * o);
517
- r(p, _, v, a, b, f, d, x, i), r(h, g, y, a, b, f, d, x, i), i.start = p, i.end = h;
518
- let S = new e.Plane();
519
- S.setFromCoplanarPoints(p, h, g);
520
- let C = [];
521
- i.originalPoints.forEach((t) => {
522
- let n = new e.Vector3();
523
- S.projectPoint(t, n), n.z = p.z, C.push(n);
524
- });
525
- let w = new e.Vector3(), T = new e.Vector3();
526
- S.projectPoint(p, w), S.projectPoint(h, T);
527
- let E = new e.Line3(w, T), D = [], O = new e.Vector3();
528
- C.forEach((e, t) => {
529
- E.closestPointToPoint(e, !0, O).distanceTo(e) < .001 && D.push(i.originalPoints[t]);
530
- }), i.originalPoints = D;
531
- }
532
- }, k = class {
534
+ n(p, _, v, a, b, f, d, x, i), n(h, g, y, a, b, f, d, x, i), i.start = p, i.end = h, i.originalPoints = O(p, h, i.originalPoints);
535
+ }
536
+ }, A = (t, n) => new e.Vector3(t.x, t.y, 0).distanceTo(new e.Vector3(n.x, n.y, 0)), j = class {
533
537
  results;
534
538
  clusterResults;
535
539
  constructor() {
@@ -961,12 +965,12 @@ var T = (t, n, r, i = .05, a = .02) => {
961
965
  return console.error("合并网格时出错:", e), null;
962
966
  }
963
967
  }
964
- }, A = (e) => {
968
+ }, M = (e) => {
965
969
  let t = {}, n = [], r = [], i = [];
966
970
  return e[0].width, e[0].height, e.forEach((e) => {
967
971
  r.push(...e.vertices), i.push(e.center), n.push(e.vertices);
968
972
  }), t.originalVertices = n, t.allCenterPoints = i, t;
969
- }, j = (e) => {
973
+ }, N = (e) => {
970
974
  let t = new s().copy(e.start).add(e.end).multiplyScalar(.5), n = new s().subVectors(new s(t.x, t.y, t.z + 1), t).normalize(), r = new s(e.direction.x, e.direction.y, 0);
971
975
  r.applyAxisAngle(n, Math.PI / 2);
972
976
  let i = new s().copy(t).add(r.clone().multiplyScalar(e.length)), a = new s().copy(t).sub(r.clone().multiplyScalar(e.length));
@@ -976,7 +980,7 @@ var T = (t, n, r, i = .05, a = .02) => {
976
980
  center: t,
977
981
  direction: r
978
982
  };
979
- }, M = (t, n, r = !0) => {
983
+ }, P = (t, n, r = !0) => {
980
984
  let i = [];
981
985
  if (!t) return [];
982
986
  for (let o = 0; o < t.length; o++) {
@@ -997,7 +1001,7 @@ var T = (t, n, r, i = .05, a = .02) => {
997
1001
  wireframe: !1,
998
1002
  transparent: !0,
999
1003
  opacity: .5
1000
- }), _ = new e.Group(), v = new k(), { horizontalSubdivisions: y, verticalSubdivisions: b } = v.initLimits4(m, h), x = v.createSubdividedWallPlane(c, b, y, g, _);
1004
+ }), _ = new e.Group(), v = new j(), { horizontalSubdivisions: y, verticalSubdivisions: b } = v.initLimits4(m, h), x = v.createSubdividedWallPlane(c, b, y, g, _);
1001
1005
  v.analyzePointDistribution(x, p, .01);
1002
1006
  let S = new e.MeshBasicMaterial({
1003
1007
  color: "black",
@@ -1006,14 +1010,14 @@ var T = (t, n, r, i = .05, a = .02) => {
1006
1010
  side: e.DoubleSide
1007
1011
  }), C = v.highlightEmptySegments(x, S, _), w = [];
1008
1012
  for (let e of C.clusters) {
1009
- let t = A(e);
1013
+ let t = M(e);
1010
1014
  t && w.push(t);
1011
1015
  }
1012
- let T = j(c).direction;
1016
+ let T = N(c).direction;
1013
1017
  c.checkResults = w, c.verticalDirection = T, c.originaIndex = o, i.push(c);
1014
1018
  }
1015
1019
  return i;
1016
- }, N = async (t, n, r, i) => {
1020
+ }, F = async (t, n, r, i) => {
1017
1021
  let a = await fetch(t);
1018
1022
  if (!a) return;
1019
1023
  let o = await a.json();
@@ -1031,7 +1035,7 @@ var T = (t, n, r, i = .05, a = .02) => {
1031
1035
  let l = await s.json(), u = Array.isArray(l) ? l : Object.values(l), d = await fetch(r);
1032
1036
  if (console.log("respcd", d), !d) return;
1033
1037
  let p = await d.json();
1034
- console.time(), o = await P(o, u, p, i), console.timeEnd();
1038
+ console.time(), o = await I(o, u, p, i), console.timeEnd();
1035
1039
  let m = new e.MeshBasicMaterial({
1036
1040
  color: "#cffd00",
1037
1041
  transparent: !0,
@@ -1138,7 +1142,7 @@ var T = (t, n, r, i = .05, a = .02) => {
1138
1142
  }), i.add(n);
1139
1143
  }
1140
1144
  });
1141
- }, P = async (t, n, r) => {
1145
+ }, I = async (t, n, r) => {
1142
1146
  if (t.length <= 0 || n.length <= 0) return t;
1143
1147
  r ||= [];
1144
1148
  for (let n of t) {
@@ -1214,12 +1218,12 @@ var T = (t, n, r, i = .05, a = .02) => {
1214
1218
  r.push(new e.Vector3(t.x, t.y, t.z));
1215
1219
  }), r[0].equals(r[r.length - 1]) && r.pop();
1216
1220
  let i = r[0].distanceTo(r[1]), a = r[0].distanceTo(r[3]);
1217
- if (a > i && ([i, a] = [a, i], r = [
1221
+ a > i && ([i, a] = [a, i], r = [
1218
1222
  r[0],
1219
1223
  r[3],
1220
1224
  r[2],
1221
1225
  r[1]
1222
- ]), i < .5) continue;
1226
+ ]);
1223
1227
  let o = x(r[0], r[3], !0), c = x(r[1], r[2], !0);
1224
1228
  s.push({
1225
1229
  doorStartPt: o,
@@ -1263,88 +1267,142 @@ var T = (t, n, r, i = .05, a = .02) => {
1263
1267
  a.doorAndBeamData = [], a.completePointAreaPercentage = -1;
1264
1268
  let u = new e.Box3();
1265
1269
  u.setFromPoints(a.originalPoints);
1266
- let f = u.max.z, p = u.min.z, m = a.rooftopPz - a.start.z;
1267
- if (m < o - .5 || m > o + 2) continue;
1268
- let h = 0;
1270
+ let f = u.max.z, p = u.min.z, m = new e.Vector3(a.start.x, a.start.y, a.start.z), h = new e.Vector3(a.end.x, a.end.y, a.end.z), g = a.rooftopPz - a.start.z;
1271
+ if (g < o - .5 || g > o + 2) continue;
1272
+ let _ = 0;
1269
1273
  for (let o of a.mergeCheckRegion) {
1270
- let { facePoints: u, boxArea: g } = v(o.points, o.gridWidth, o.gridHeight, o.centerPts);
1271
- if (!(!u || u.length <= 0) && (h += o.area, o.area / g * 100 > 60)) {
1272
- let h = u[0].distanceTo(u[1]), g = h / a.length * 100, _ = u[0].distanceTo(u[3]), v = a.rooftopPz - u[2].z, b = p > a.start.z - .15 && a.length < 1.5 || a.length > 1.5;
1273
- if (_ < .5 || !b || f < u[2].z || v > m / 2) continue;
1274
- let C = !1, w = !1, T = !1, E = -1, D = u[2].clone(), O = u[3].clone(), k = u[0].clone(), A = u[1].clone();
1275
- if (Math.abs(u[0].z - a.start.z) < .1 && (g < 85 && h > .4 || h > .7 && _ > m - m / 3)) {
1276
- let t = !1;
1277
- for (let r = 0; r < n.length; r++) {
1278
- let i = r + 1;
1279
- if (i >= n.length) continue;
1280
- let a = new e.Vector3(n[r].x, n[r].y, n[r].z), o = new e.Vector3(n[i].x, n[i].y, n[i].z);
1281
- if (d(new e.Vector3(a.x, a.y, 0), new e.Vector3(o.x, o.y, 0), new e.Vector3(u[0].x, u[0].y, 0), new e.Vector3(u[1].x, u[1].y, 0), .1) != null) {
1282
- t = !0;
1283
- break;
1274
+ let { facePoints: u, boxArea: C, totalInPlaneNum: w } = v(o.points, o.gridWidth, o.gridHeight, o.centerPts);
1275
+ if (!u || u.length <= 0) continue;
1276
+ _ += o.area;
1277
+ let T = 0;
1278
+ if (w != 0 && (T = o.gridHeight * o.gridWidth * w), (o.area - T) / C * 100 > 85) {
1279
+ let _ = u[0].distanceTo(u[1]), v = _ / a.length * 100, C = u[0].distanceTo(u[3]), w = a.rooftopPz - u[2].z;
1280
+ if (p > a.start.z - .15 && a.length < 1.5 || a.length, C < .5 || f < u[2].z || w > g / 3) continue;
1281
+ let T = !1, E = !1, D = !1, k = -1, j = u[2].clone(), M = u[3].clone(), N = u[0].clone(), P = u[1].clone(), F = !1;
1282
+ if (Math.abs(u[0].z - a.start.z) < .25) {
1283
+ if (_ > .2 && a.length > .5) {
1284
+ let n = A(m, N), r = A(m, P), o = A(h, N), s = A(h, P), c = .1;
1285
+ if (n < c || r < c) {
1286
+ let r = O(N, P, a.originalPoints), o = [], s = [];
1287
+ if (r.forEach((e) => {
1288
+ e.z >= j.z ? o.push(e) : e.z <= N.z && s.push(e);
1289
+ }), o.length > 0) {
1290
+ let r = new e.Vector3(a.start.x, a.start.y, 0), o = new e.Vector3(a.end.x, a.end.y, 0), s = new e.Vector3().subVectors(r, o).normalize(), l = new e.Vector3(), u = Infinity, f = -1;
1291
+ for (let n = 0; n < t.length; n++) {
1292
+ if (n == i || t[n].length < .5) continue;
1293
+ let a = new e.Vector3(t[n].start.x, t[n].start.y, 0), c = new e.Vector3(t[n].end.x, t[n].end.y, 0);
1294
+ if (d(r, o, a, c) != null) continue;
1295
+ let p = b(r, o, a, c);
1296
+ if (p && p.angle > 85) {
1297
+ let t = y(r, o, new e.Line3(a, c).closestPointToPoint(r, !0, l), r);
1298
+ if (!t || t.direction != "same") continue;
1299
+ let i = d(r.clone().addScaledVector(s, 10), o.clone().addScaledVector(s.clone().negate(), 10), a, c);
1300
+ if (i == null) continue;
1301
+ let p = r.distanceTo(i.point);
1302
+ p < u && (u = p, f = n);
1303
+ }
1304
+ }
1305
+ u != Infinity && u < 2 && (F = !0, console.log("333333", u, i, f, _), n < c ? (M = M.addScaledVector(s, u), N = N.addScaledVector(s, u)) : (j = j.addScaledVector(s, u), P = P.addScaledVector(s, u)));
1306
+ }
1307
+ } else if (o < c || s < c) {
1308
+ let n = O(N, P, a.originalPoints), r = [], s = [];
1309
+ if (n.forEach((e) => {
1310
+ e.z >= j.z ? r.push(e) : e.z <= N.z && s.push(e);
1311
+ }), r.length > 0) {
1312
+ let n = new e.Vector3(a.start.x, a.start.y, 0), r = new e.Vector3(a.end.x, a.end.y, 0), s = new e.Vector3().subVectors(r, n).normalize(), l = new e.Vector3(), u = Infinity, f = -1;
1313
+ for (let a = 0; a < t.length; a++) {
1314
+ if (a == i || t[a].length < .5) continue;
1315
+ let o = new e.Vector3(t[a].start.x, t[a].start.y, 0), c = new e.Vector3(t[a].end.x, t[a].end.y, 0);
1316
+ if (d(n, r, o, c) != null) continue;
1317
+ let p = b(n, r, o, c);
1318
+ if (p && p.angle > 85) {
1319
+ let t = y(r, n, new e.Line3(o, c).closestPointToPoint(r, !0, l), r);
1320
+ if (!t || t.direction != "same") continue;
1321
+ let i = d(n.clone().addScaledVector(s, 10), r.clone().addScaledVector(s.clone().negate(), 10), o, c);
1322
+ if (i == null) continue;
1323
+ let p = r.distanceTo(i.point);
1324
+ p < u && (u = p, f = a);
1325
+ }
1326
+ }
1327
+ u != Infinity && u < 2 && (console.log(u, i, f, _), F = !0, o < c ? (M = M.addScaledVector(s, u), N = N.addScaledVector(s, u)) : (j = j.addScaledVector(s, u), P = P.addScaledVector(s, u)));
1328
+ }
1284
1329
  }
1330
+ _ = M.distanceTo(j);
1285
1331
  }
1286
- for (let t = 0; t < s.length; t++) {
1287
- let n = new e.Vector3(s[t].doorStartPt.x, s[t].doorStartPt.y, 0), i = new e.Vector3(s[t].doorEndPt.x, s[t].doorEndPt.y, 0), o = new e.Vector3(u[0].x, u[0].y, 0), c = new e.Vector3(u[1].x, u[1].y, 0), l = new e.Vector3().subVectors(n, i).normalize(), f = new e.Vector3().subVectors(o, c).normalize(), p = .2, m = d(n.clone().addScaledVector(l, p), i.clone().addScaledVector(l.clone().negate(), p), o.clone().addScaledVector(f, p), c.clone().addScaledVector(f.clone().negate(), p)), h = u[2].z < s[t].maxZ || Math.abs(u[2].z - s[t].maxZ) < .3, g = y(n.clone(), i.clone(), o.clone(), c.clone());
1288
- if (m && h) r[s[t].index].isFindBeam = !0, w = !0, s[t].isFind = !0;
1289
- else if (h && g && g.isParallel) {
1290
- let o = x(n, i), c = new e.Line3(new e.Vector3(a.start.x, a.start.y, 0), new e.Vector3(a.end.x, a.end.y, 0)), l = new e.Vector3(), u = c.closestPointToPoint(o, !0, l);
1291
- o.distanceTo(u) < .3 && (r[s[t].index].isFindBeam = !0);
1332
+ if (v < 85 && _ > .35 || _ > .7 && C > g - g / 3) {
1333
+ let t = !1;
1334
+ for (let r = 0; r < n.length; r++) {
1335
+ let i = r + 1;
1336
+ if (i >= n.length) continue;
1337
+ let a = new e.Vector3(n[r].x, n[r].y, n[r].z), o = new e.Vector3(n[i].x, n[i].y, n[i].z);
1338
+ if (d(new e.Vector3(a.x, a.y, 0), new e.Vector3(o.x, o.y, 0), new e.Vector3(u[0].x, u[0].y, 0), new e.Vector3(u[1].x, u[1].y, 0), .1) != null) {
1339
+ t = !0;
1340
+ break;
1341
+ }
1292
1342
  }
1293
- }
1294
- if (!w) for (let t = 0; t < s.length; t++) {
1295
- let n = new e.Vector3(s[t].doorStartPt.x, s[t].doorStartPt.y, 0), i = new e.Vector3(s[t].doorEndPt.x, s[t].doorEndPt.y, 0), o = new e.Vector3(u[0].x, u[0].y, 0), l = new e.Vector3(u[1].x, u[1].y, 0), d = u[2].z < s[t].maxZ || Math.abs(u[2].z - s[t].maxZ) < .3, f = Math.abs(u[2].z - s[t].maxZ) > .2;
1296
- if (d && !f) {
1297
- let d = S(n.clone(), i.clone(), o.clone(), l.clone(), { distanceThreshold: 2 });
1298
- if (c == 4 && console.log(s[t], d), d && d.type == "collinear_gap") {
1299
- let c = x(n, i), f = new e.Line3(new e.Vector3(a.start.x, a.start.y, 0), new e.Vector3(a.end.x, a.end.y, 0)), p = new e.Vector3(), m = f.closestPointToPoint(c, !0, p);
1300
- if (c.distanceTo(m) < .15) {
1301
- let a = o.distanceTo(n), c = l.distanceTo(n);
1302
- if (a > .25 && c > .25) {
1303
- let e = o.distanceTo(i), t = l.distanceTo(i);
1304
- if (e > .2 && t > .2) continue;
1343
+ for (let t = 0; t < s.length; t++) {
1344
+ let n = new e.Vector3(s[t].doorStartPt.x, s[t].doorStartPt.y, 0), i = new e.Vector3(s[t].doorEndPt.x, s[t].doorEndPt.y, 0), o = new e.Vector3(u[0].x, u[0].y, 0), c = new e.Vector3(u[1].x, u[1].y, 0), l = new e.Vector3().subVectors(n, i).normalize(), f = new e.Vector3().subVectors(o, c).normalize(), p = .2, m = d(n.clone().addScaledVector(l, p), i.clone().addScaledVector(l.clone().negate(), p), o.clone().addScaledVector(f, p), c.clone().addScaledVector(f.clone().negate(), p)), h = u[2].z < s[t].maxZ || Math.abs(u[2].z - s[t].maxZ) < .3, g = y(n.clone(), i.clone(), o.clone(), c.clone());
1345
+ if (m && h) r[s[t].index].isFindBeam = !0, E = !0, s[t].isFind = !0;
1346
+ else if (h && g && g.isParallel) {
1347
+ let o = x(n, i), c = new e.Line3(new e.Vector3(a.start.x, a.start.y, 0), new e.Vector3(a.end.x, a.end.y, 0)), l = new e.Vector3(), u = c.closestPointToPoint(o, !0, l);
1348
+ o.distanceTo(u) < .3 && (r[s[t].index].isFindBeam = !0);
1349
+ }
1350
+ }
1351
+ if (!E) for (let t = 0; t < s.length; t++) {
1352
+ let n = new e.Vector3(s[t].doorStartPt.x, s[t].doorStartPt.y, 0), i = new e.Vector3(s[t].doorEndPt.x, s[t].doorEndPt.y, 0), o = new e.Vector3(u[0].x, u[0].y, 0), c = new e.Vector3(u[1].x, u[1].y, 0), l = u[2].z < s[t].maxZ || Math.abs(u[2].z - s[t].maxZ) < .3, d = Math.abs(u[2].z - s[t].maxZ) > .2;
1353
+ if (l && !d) {
1354
+ let l = S(n.clone(), i.clone(), o.clone(), c.clone(), { distanceThreshold: 2 });
1355
+ if (l && l.type == "collinear_gap") {
1356
+ let d = x(n, i), f = new e.Line3(new e.Vector3(a.start.x, a.start.y, 0), new e.Vector3(a.end.x, a.end.y, 0)), p = new e.Vector3(), m = f.closestPointToPoint(d, !0, p);
1357
+ if (d.distanceTo(m) < .15) {
1358
+ let a = o.distanceTo(n), d = c.distanceTo(n);
1359
+ if (a > .25 && d > .25) {
1360
+ let e = o.distanceTo(i), t = c.distanceTo(i);
1361
+ if (e > .2 && t > .2) continue;
1362
+ }
1363
+ E = !0, D = !0, k = s[t].index, s[t].isFind = !0, r[s[t].index].isFindBeam = !0;
1364
+ let f = new e.Vector3().subVectors(o, c).normalize(), p = n.distanceTo(i) - l.overlap;
1365
+ d < a && f.negate(), a > d ? (j = u[2].clone().addScaledVector(f, p), M = u[3].clone(), N = j.clone(), P = M.clone(), N.z = P.z = u[0].z) : (j = u[2].clone(), M = u[3].clone().addScaledVector(f, p), N = j.clone(), P = M.clone(), N.z = P.z = u[0].z);
1305
1366
  }
1306
- w = !0, T = !0, E = s[t].index, s[t].isFind = !0, r[s[t].index].isFindBeam = !0;
1307
- let f = new e.Vector3().subVectors(o, l).normalize(), p = n.distanceTo(i) - d.overlap;
1308
- c < a && f.negate(), a > c ? (D = u[2].clone().addScaledVector(f, p), O = u[3].clone(), k = D.clone(), A = O.clone(), k.z = A.z = u[0].z) : (D = u[2].clone(), O = u[3].clone().addScaledVector(f, p), k = D.clone(), A = O.clone(), k.z = A.z = u[0].z);
1367
+ } else if (l && l.type == "collinear_overlap") {
1368
+ let e = o.distanceTo(c), a = i.distanceTo(n);
1369
+ (Math.abs(e - l.overlap) < .25 || Math.abs(a - l.overlap) < .25) && (E = !0, D = !0, k = s[t].index, s[t].isFind = !0, r[s[t].index].isFindBeam = !0);
1309
1370
  }
1310
- } else if (d && d.type == "collinear_overlap") {
1311
- let e = o.distanceTo(l), a = i.distanceTo(n);
1312
- (Math.abs(e - d.overlap) < .25 || Math.abs(a - d.overlap) < .25) && (w = !0, T = !0, E = s[t].index, s[t].isFind = !0, r[s[t].index].isFindBeam = !0);
1313
1371
  }
1314
1372
  }
1373
+ (E || t || C > g / 2 && _ > .8 && Math.abs(p - a.start.z) < .4) && (T = !0);
1315
1374
  }
1316
- (w || t || _ > m / 2 && h > .8 && Math.abs(p - a.start.z) < .4) && (C = !0);
1317
1375
  }
1318
- if (C) {
1376
+ if (T) {
1319
1377
  a.checkResults[o.index].isDoor = !0;
1320
1378
  let n = {
1321
1379
  id: c,
1322
- beamStart: D,
1323
- beamEnd: O,
1380
+ beamStart: j,
1381
+ beamEnd: M,
1324
1382
  beamHeight: a.rooftopPz - u[2].z,
1325
- doorStart: k,
1326
- doorEnd: A,
1327
- doorHeight: _,
1383
+ doorStart: N,
1384
+ doorEnd: P,
1385
+ doorHeight: C,
1328
1386
  nearId: -1,
1329
- type: "doorBeam",
1330
- isDoor: w,
1331
- isPullOutDoor: T,
1332
- pcbDoorIndex: E
1387
+ type: F ? "extendBeam" : "doorBeam",
1388
+ isDoor: E,
1389
+ isPullOutDoor: D,
1390
+ pcbDoorIndex: k
1333
1391
  };
1334
1392
  for (let r = 0; r < l.length; r++) {
1335
1393
  let i = t[l[r].linesIndex].doorAndBeamData[l[r].doorIndex];
1336
1394
  if (i.nearId != -1) continue;
1337
- let a = y(D.clone(), O.clone(), i.beamStart.clone(), i.beamEnd.clone());
1395
+ let a = y(j.clone(), M.clone(), i.beamStart.clone(), i.beamEnd.clone());
1338
1396
  if (a && a.isParallel) {
1339
- let t = D.distanceTo(O), r = i.beamStart.distanceTo(i.beamEnd), a = new e.Line3(D.clone(), O.clone());
1397
+ let t = j.distanceTo(M), r = i.beamStart.distanceTo(i.beamEnd), a = new e.Line3(j.clone(), M.clone());
1340
1398
  a.start.z = 0, a.end.z = 0;
1341
1399
  let o = x(i.beamStart, i.beamEnd, !0);
1342
- r > t && (a.start = new e.Vector3(i.beamStart.x, i.beamStart.y, 0), a.end = new e.Vector3(i.beamEnd.x, i.beamEnd.y, 0), o = x(D, O, !0));
1400
+ r > t && (a.start = new e.Vector3(i.beamStart.x, i.beamStart.y, 0), a.end = new e.Vector3(i.beamEnd.x, i.beamEnd.y, 0), o = x(j, M, !0));
1343
1401
  let s = new e.Vector3(), l = a.closestPointToPoint(o, !0, s), u = l.distanceTo(o), f = new e.Vector3().subVectors(o, l).normalize(), p = f.clone().negate(), m = o.clone().addScaledVector(p, u + .1), h = d(a.start, a.end, o, m);
1344
1402
  if (u < .5 && h != null) {
1345
1403
  i.nearId = c, n.nearId = i.id;
1346
1404
  let e = .8;
1347
- (i.isDoor || n.isDoor) && (i.isDoor = !0, n.isDoor = !0), t < r ? t > e && !i.isPullOutDoor ? (i.beamStart = D.clone().addScaledVector(p, u), i.beamEnd = O.clone().addScaledVector(p, u), i.doorStart = k.clone().addScaledVector(p, u), i.doorEnd = A.clone().addScaledVector(p, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : !T || T && i.isPullOutDoor && E == i.pcbDoorIndex ? (n.beamStart = i.beamStart.clone().addScaledVector(f, u), n.beamEnd = i.beamEnd.clone().addScaledVector(f, u), n.doorStart = i.doorStart.clone().addScaledVector(f, u), n.doorEnd = i.doorEnd.clone().addScaledVector(f, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight) : (i.beamStart = D.clone().addScaledVector(p, u), i.beamEnd = O.clone().addScaledVector(p, u), i.doorStart = k.clone().addScaledVector(p, u), i.doorEnd = A.clone().addScaledVector(p, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : t > r && (r > e && !T ? (n.beamStart = i.beamStart.clone().addScaledVector(p, u), n.beamEnd = i.beamEnd.clone().addScaledVector(p, u), n.doorStart = i.doorStart.clone().addScaledVector(p, u), n.doorEnd = i.doorEnd.clone().addScaledVector(p, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight) : !i.isPullOutDoor || T && i.isPullOutDoor && E == i.pcbDoorIndex ? (i.beamStart = D.clone().addScaledVector(f, u), i.beamEnd = O.clone().addScaledVector(f, u), i.doorStart = k.clone().addScaledVector(f, u), i.doorEnd = A.clone().addScaledVector(f, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : (n.beamStart = i.beamStart.clone().addScaledVector(p, u), n.beamEnd = i.beamEnd.clone().addScaledVector(p, u), n.doorStart = i.doorStart.clone().addScaledVector(p, u), n.doorEnd = i.doorEnd.clone().addScaledVector(p, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight));
1405
+ (i.isDoor || n.isDoor) && (i.isDoor = !0, n.isDoor = !0), t < r ? t > e && !i.isPullOutDoor ? (i.beamStart = j.clone().addScaledVector(p, u), i.beamEnd = M.clone().addScaledVector(p, u), i.doorStart = N.clone().addScaledVector(p, u), i.doorEnd = P.clone().addScaledVector(p, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : !D || D && i.isPullOutDoor && k == i.pcbDoorIndex ? (n.beamStart = i.beamStart.clone().addScaledVector(f, u), n.beamEnd = i.beamEnd.clone().addScaledVector(f, u), n.doorStart = i.doorStart.clone().addScaledVector(f, u), n.doorEnd = i.doorEnd.clone().addScaledVector(f, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight) : (i.beamStart = j.clone().addScaledVector(p, u), i.beamEnd = M.clone().addScaledVector(p, u), i.doorStart = N.clone().addScaledVector(p, u), i.doorEnd = P.clone().addScaledVector(p, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : t > r && (r > e && !D ? (n.beamStart = i.beamStart.clone().addScaledVector(p, u), n.beamEnd = i.beamEnd.clone().addScaledVector(p, u), n.doorStart = i.doorStart.clone().addScaledVector(p, u), n.doorEnd = i.doorEnd.clone().addScaledVector(p, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight) : !i.isPullOutDoor || D && i.isPullOutDoor && k == i.pcbDoorIndex ? (i.beamStart = j.clone().addScaledVector(f, u), i.beamEnd = M.clone().addScaledVector(f, u), i.doorStart = N.clone().addScaledVector(f, u), i.doorEnd = P.clone().addScaledVector(f, u), i.doorHeight = n.doorHeight, i.beamStart.z = i.beamEnd.z = i.doorStart.z + i.doorHeight) : (n.beamStart = i.beamStart.clone().addScaledVector(p, u), n.beamEnd = i.beamEnd.clone().addScaledVector(p, u), n.doorStart = i.doorStart.clone().addScaledVector(p, u), n.doorEnd = i.doorEnd.clone().addScaledVector(p, u), n.doorHeight = i.doorHeight, n.beamStart.z = n.beamEnd.z = n.doorStart.z + n.doorHeight));
1348
1406
  break;
1349
1407
  }
1350
1408
  }
@@ -1356,8 +1414,8 @@ var T = (t, n, r, i = .05, a = .02) => {
1356
1414
  }
1357
1415
  }
1358
1416
  }
1359
- let g = a.length * (a.rooftopPz - a.start.z);
1360
- a.completePointAreaPercentage = h / g * 100;
1417
+ let C = a.length * (a.rooftopPz - a.start.z);
1418
+ a.completePointAreaPercentage = _ / C * 100;
1361
1419
  }
1362
1420
  let u = .65, f = [], p = [], h = .2;
1363
1421
  for (let n = 0; n < s.length; n++) {
@@ -1433,7 +1491,7 @@ var T = (t, n, r, i = .05, a = .02) => {
1433
1491
  }
1434
1492
  }
1435
1493
  return t;
1436
- }, F = (t, n) => {
1494
+ }, L = (t, n) => {
1437
1495
  if (t.length <= 0) return t;
1438
1496
  for (let n of t) {
1439
1497
  let t = [];
@@ -1526,4 +1584,4 @@ var T = (t, n, r, i = .05, a = .02) => {
1526
1584
  return t;
1527
1585
  };
1528
1586
  //#endregion
1529
- export { S as classifySegments, M as getAllGeometry, P as getBeamLine, F as getMainBeamLine, y as getParallelism, D as getPointCloudMinMax, T as getPointCoverageOnQuad, m as isParallel, b as perpendicularInfo, O as removeNoisePoints, d as segmentsIntersect2D, N as usegetBeamLine };
1587
+ export { S as classifySegments, P as getAllGeometry, I as getBeamLine, L as getMainBeamLine, y as getParallelism, D as getPointCloudMinMax, T as getPointCoverageOnQuad, m as isParallel, b as perpendicularInfo, k as removeNoisePoints, d as segmentsIntersect2D, F as usegetBeamLine };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rm-graphical-computing",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Three.js wall segment processing utilities.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -34,11 +34,12 @@
34
34
  "dependencies": {
35
35
  "axios": "^1.14.0",
36
36
  "dotenv": "^17.3.1",
37
- "express": "^5.2.1"
37
+ "express": "^5.2.1",
38
+ "rm-graphical-computing": "^1.0.0"
38
39
  },
39
40
  "devDependencies": {
40
41
  "nodemon": "^3.1.14",
41
42
  "three": "^0.183.2",
42
43
  "vite": "^8.0.2"
43
44
  }
44
- }
45
+ }