feat: 增加点云显示和打包下载功能

This commit is contained in:
2025-10-28 16:50:20 +08:00
parent 68de09f1da
commit c8e9c4a031
11 changed files with 6356 additions and 1 deletions

8
static/js/OrbitControls.min.js vendored Normal file

File diff suppressed because one or more lines are too long

8
static/js/PCDLoader.min.js vendored Normal file
View File

@@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.37.0.
* Original file: /npm/three@0.128.0/examples/js/loaders/PCDLoader.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(){class t extends THREE.Loader{constructor(t){super(t),this.littleEndian=!0}load(t,e,i,n){const s=this,r=new THREE.FileLoader(s.manager);r.setPath(s.path),r.setResponseType("arraybuffer"),r.setRequestHeader(s.requestHeader),r.setWithCredentials(s.withCredentials),r.load(t,(function(i){try{e(s.parse(i,t))}catch(e){n?n(e):console.error(e),s.manager.itemError(t)}}),i,n)}parse(t,e){const i=THREE.LoaderUtils.decodeText(new Uint8Array(t)),n=function(t){const e={},i=t.search(/[\r\n]DATA\s(\S*)\s/i),n=/[\r\n]DATA\s(\S*)\s/i.exec(t.substr(i-1));if(e.data=n[1],e.headerLen=n[0].length+i,e.str=t.substr(0,e.headerLen),e.str=e.str.replace(/\#.*/gi,""),e.version=/VERSION (.*)/i.exec(e.str),e.fields=/FIELDS (.*)/i.exec(e.str),e.size=/SIZE (.*)/i.exec(e.str),e.type=/TYPE (.*)/i.exec(e.str),e.count=/COUNT (.*)/i.exec(e.str),e.width=/WIDTH (.*)/i.exec(e.str),e.height=/HEIGHT (.*)/i.exec(e.str),e.viewpoint=/VIEWPOINT (.*)/i.exec(e.str),e.points=/POINTS (.*)/i.exec(e.str),null!==e.version&&(e.version=parseFloat(e.version[1])),null!==e.fields&&(e.fields=e.fields[1].split(" ")),null!==e.type&&(e.type=e.type[1].split(" ")),null!==e.width&&(e.width=parseInt(e.width[1])),null!==e.height&&(e.height=parseInt(e.height[1])),null!==e.viewpoint&&(e.viewpoint=e.viewpoint[1]),null!==e.points&&(e.points=parseInt(e.points[1],10)),null===e.points&&(e.points=e.width*e.height),null!==e.size&&(e.size=e.size[1].split(" ").map((function(t){return parseInt(t,10)}))),null!==e.count)e.count=e.count[1].split(" ").map((function(t){return parseInt(t,10)}));else{e.count=[];for(let t=0,i=e.fields.length;t<i;t++)e.count.push(1)}e.offset={};let s=0;for(let t=0,i=e.fields.length;t<i;t++)"ascii"===e.data?e.offset[e.fields[t]]=t:(e.offset[e.fields[t]]=s,s+=e.size[t]*e.count[t]);return e.rowSize=s,e}(i),s=[],r=[],o=[];if("ascii"===n.data){const t=n.offset,e=i.substr(n.headerLen).split("\n");for(let i=0,n=e.length;i<n;i++){if(""===e[i])continue;const n=e[i].split(" ");if(void 0!==t.x&&(s.push(parseFloat(n[t.x])),s.push(parseFloat(n[t.y])),s.push(parseFloat(n[t.z]))),void 0!==t.rgb){const e=parseFloat(n[t.rgb]),i=e>>16&255,s=e>>8&255,r=255&e;o.push(i/255,s/255,r/255)}void 0!==t.normal_x&&(r.push(parseFloat(n[t.normal_x])),r.push(parseFloat(n[t.normal_y])),r.push(parseFloat(n[t.normal_z])))}}if("binary_compressed"===n.data){const e=new Uint32Array(t.slice(n.headerLen,n.headerLen+8)),i=e[0],l=e[1],a=function(t,e){const i=t.length,n=new Uint8Array(e);let s,r,o,l=0,a=0;do{if(s=t[l++],s<32){if(s++,a+s>e)throw new Error("Output buffer is not large enough");if(l+s>i)throw new Error("Invalid compressed data");do{n[a++]=t[l++]}while(--s)}else{if(r=s>>5,o=a-((31&s)<<8)-1,l>=i)throw new Error("Invalid compressed data");if(7===r&&(r+=t[l++],l>=i))throw new Error("Invalid compressed data");if(o-=t[l++],a+r+2>e)throw new Error("Output buffer is not large enough");if(o<0)throw new Error("Invalid compressed data");if(o>=a)throw new Error("Invalid compressed data");do{n[a++]=n[o++]}while(2+--r)}}while(l<i);return n}(new Uint8Array(t,n.headerLen+8,i),l),p=new DataView(a.buffer),h=n.offset;for(let t=0;t<n.points;t++)void 0!==h.x&&(s.push(p.getFloat32(n.points*h.x+n.size[0]*t,this.littleEndian)),s.push(p.getFloat32(n.points*h.y+n.size[1]*t,this.littleEndian)),s.push(p.getFloat32(n.points*h.z+n.size[2]*t,this.littleEndian))),void 0!==h.rgb&&(o.push(p.getUint8(n.points*h.rgb+n.size[3]*t+0)/255),o.push(p.getUint8(n.points*h.rgb+n.size[3]*t+1)/255),o.push(p.getUint8(n.points*h.rgb+n.size[3]*t+2)/255)),void 0!==h.normal_x&&(r.push(p.getFloat32(n.points*h.normal_x+n.size[4]*t,this.littleEndian)),r.push(p.getFloat32(n.points*h.normal_y+n.size[5]*t,this.littleEndian)),r.push(p.getFloat32(n.points*h.normal_z+n.size[6]*t,this.littleEndian)))}if("binary"===n.data){const e=new DataView(t,n.headerLen),i=n.offset;for(let t=0,l=0;t<n.points;t++,l+=n.rowSize)void 0!==i.x&&(s.push(e.getFloat32(l+i.x,this.littleEndian)),s.push(e.getFloat32(l+i.y,this.littleEndian)),s.push(e.getFloat32(l+i.z,this.littleEndian))),void 0!==i.rgb&&(o.push(e.getUint8(l+i.rgb+2)/255),o.push(e.getUint8(l+i.rgb+1)/255),o.push(e.getUint8(l+i.rgb+0)/255)),void 0!==i.normal_x&&(r.push(e.getFloat32(l+i.normal_x,this.littleEndian)),r.push(e.getFloat32(l+i.normal_y,this.littleEndian)),r.push(e.getFloat32(l+i.normal_z,this.littleEndian)))}const l=new THREE.BufferGeometry;s.length>0&&l.setAttribute("position",new THREE.Float32BufferAttribute(s,3)),r.length>0&&l.setAttribute("normal",new THREE.Float32BufferAttribute(r,3)),o.length>0&&l.setAttribute("color",new THREE.Float32BufferAttribute(o,3)),l.computeBoundingSphere();const a=new THREE.PointsMaterial({size:.005});o.length>0?a.vertexColors=!0:a.color.setHex(16777215*Math.random());const p=new THREE.Points(l,a);let h=e.split("").reverse().join("");return h=/([^\/]*)/.exec(h),h=h[1].split("").reverse().join(""),p.name=h,p}}THREE.PCDLoader=t}();
//# sourceMappingURL=/sm/8ce4feda329ae6ffa4a8ab906318e4470c0a2ccdcb9f200b1f33cc79763deb1a.map

6046
static/js/socket.io.js Normal file

File diff suppressed because it is too large Load Diff

6
static/js/three.min.js vendored Normal file

File diff suppressed because one or more lines are too long

0
static/pcd/.gitkeep Normal file
View File

BIN
static/pcd/desample.pcd Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB