weijielyu commited on
Commit
465f735
·
1 Parent(s): 226b07f
Files changed (1) hide show
  1. app.py +182 -105
app.py CHANGED
@@ -437,114 +437,191 @@ void main () {
437
  }\`;
438
 
439
  function createWorker() {
440
- const code = \`
441
- let buffer, vertexCount = 0;
442
- const rowLength = 32;
443
- var _floatView = new Float32Array(1), _int32View = new Int32Array(_floatView.buffer);
444
- function floatToHalf(float) {
445
- _floatView[0] = float; var f = _int32View[0];
446
- var sign = (f >> 31) & 0x0001, exp = (f >> 23) & 0x00ff, frac = f & 0x007fffff, newExp;
447
- if (exp == 0) newExp = 0;
448
- else if (exp < 113) { newExp = 0; frac |= 0x00800000; frac = frac >> (113 - exp); if (frac & 0x01000000) { newExp = 1; frac = 0; }}
449
- else if (exp < 142) newExp = exp - 112; else { newExp = 31; frac = 0; }
450
- return (sign << 15) | (newExp << 10) | (frac >> 13);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  }
452
- function packHalf2x16(x, y) { return (floatToHalf(x) | (floatToHalf(y) << 16)) >>> 0; }
453
- function processPlyBuffer(inputBuffer) {
454
- const ubuf = new Uint8Array(inputBuffer);
455
- const header = new TextDecoder().decode(ubuf.slice(0, 10240));
456
- const header_end = "end_header\\\\n", header_end_index = header.indexOf(header_end);
457
- if (header_end_index < 0) throw new Error("Unable to read .ply file header");
458
- const vertexCount = parseInt(/element vertex (\\\\d+)\\\\n/.exec(header)[1]);
459
- console.log("Vertex Count:", vertexCount);
460
- let row_offset = 0, offsets = {}, types = {};
461
- const TYPE_MAP = {double: "getFloat64", int: "getInt32", uint: "getUint32", float: "getFloat32", short: "getInt16", ushort: "getUint16", uchar: "getUint8"};
462
- for (let prop of header.slice(0, header_end_index).split("\\\\n").filter(k => k.startsWith("property "))) {
463
- const [p, type, name] = prop.split(" ");
464
- const arrayType = TYPE_MAP[type] || "getInt8";
465
- types[name] = arrayType; offsets[name] = row_offset;
466
- row_offset += parseInt(arrayType.replace(/[^\\\\d]/g, "")) / 8;
467
- }
468
- let dataView = new DataView(inputBuffer, header_end_index + header_end.length), row = 0;
469
- const attrs = new Proxy({}, {
470
- get(target, prop) {
471
- if (!types[prop]) throw new Error(prop + " not found");
472
- return dataView[types[prop]](row * row_offset + offsets[prop], true);
473
- }
474
- });
475
- let sizeList = new Float32Array(vertexCount), sizeIndex = new Uint32Array(vertexCount);
476
- for (row = 0; row < vertexCount; row++) {
477
- sizeIndex[row] = row;
478
- if (!types["scale_0"]) continue;
479
- const size = Math.exp(attrs.scale_0) * Math.exp(attrs.scale_1) * Math.exp(attrs.scale_2);
480
- const opacity = 1 / (1 + Math.exp(-attrs.opacity));
481
- sizeList[row] = size * opacity;
482
- }
483
- sizeIndex.sort((b, a) => sizeList[a] - sizeList[b]);
484
- const buffer = new ArrayBuffer(rowLength * vertexCount);
485
- for (let j = 0; j < vertexCount; j++) {
486
- row = sizeIndex[j];
487
- const position = new Float32Array(buffer, j * rowLength, 3);
488
- const scales = new Float32Array(buffer, j * rowLength + 12, 3);
489
- const rgba = new Uint8ClampedArray(buffer, j * rowLength + 24, 4);
490
- const rot = new Uint8ClampedArray(buffer, j * rowLength + 28, 4);
491
- if (types["scale_0"]) {
492
- const qlen = Math.sqrt(attrs.rot_0 ** 2 + attrs.rot_1 ** 2 + attrs.rot_2 ** 2 + attrs.rot_3 ** 2);
493
- rot[0] = (attrs.rot_0 / qlen) * 128 + 128; rot[1] = (attrs.rot_1 / qlen) * 128 + 128;
494
- rot[2] = (attrs.rot_2 / qlen) * 128 + 128; rot[3] = (attrs.rot_3 / qlen) * 128 + 128;
495
- scales[0] = Math.exp(attrs.scale_0); scales[1] = Math.exp(attrs.scale_1); scales[2] = Math.exp(attrs.scale_2);
496
- } else { scales[0] = scales[1] = scales[2] = 0.01; rot[0] = 255; rot[1] = rot[2] = rot[3] = 0; }
497
- position[0] = attrs.x; position[1] = attrs.y; position[2] = attrs.z;
498
- if (types["f_dc_0"]) {
499
- const SH_C0 = 0.28209479177387814;
500
- rgba[0] = (0.5 + SH_C0 * attrs.f_dc_0) * 255; rgba[1] = (0.5 + SH_C0 * attrs.f_dc_1) * 255; rgba[2] = (0.5 + SH_C0 * attrs.f_dc_2) * 255;
501
- } else { rgba[0] = attrs.red; rgba[1] = attrs.green; rgba[2] = attrs.blue; }
502
- rgba[3] = types["opacity"] ? (1 / (1 + Math.exp(-attrs.opacity))) * 255 : 255;
503
- }
504
- return buffer;
505
  }
506
- function generateTexture() {
507
- if (!buffer) return;
508
- const f_buffer = new Float32Array(buffer), u_buffer = new Uint8Array(buffer);
509
- const texwidth = 2048, texheight = Math.ceil((2 * vertexCount) / texwidth);
510
- const texdata = new Uint32Array(texwidth * texheight * 4);
511
- const texdata_c = new Uint8Array(texdata.buffer), texdata_f = new Float32Array(texdata.buffer);
512
- for (let i = 0; i < vertexCount; i++) {
513
- texdata_f[8 * i + 0] = f_buffer[8 * i + 0]; texdata_f[8 * i + 1] = f_buffer[8 * i + 1]; texdata_f[8 * i + 2] = f_buffer[8 * i + 2];
514
- texdata_c[4 * (8 * i + 7) + 0] = u_buffer[32 * i + 24 + 0]; texdata_c[4 * (8 * i + 7) + 1] = u_buffer[32 * i + 24 + 1];
515
- texdata_c[4 * (8 * i + 7) + 2] = u_buffer[32 * i + 24 + 2]; texdata_c[4 * (8 * i + 7) + 3] = u_buffer[32 * i + 24 + 3];
516
- let scale = [f_buffer[8 * i + 3], f_buffer[8 * i + 4], f_buffer[8 * i + 5]];
517
- let rot = [(u_buffer[32 * i + 28] - 128) / 128, (u_buffer[32 * i + 29] - 128) / 128, (u_buffer[32 * i + 30] - 128) / 128, (u_buffer[32 * i + 31] - 128) / 128];
518
- const M = [1.0 - 2.0 * (rot[2] * rot[2] + rot[3] * rot[3]), 2.0 * (rot[1] * rot[2] + rot[0] * rot[3]), 2.0 * (rot[1] * rot[3] - rot[0] * rot[2]),
519
- 2.0 * (rot[1] * rot[2] - rot[0] * rot[3]), 1.0 - 2.0 * (rot[1] * rot[1] + rot[3] * rot[3]), 2.0 * (rot[2] * rot[3] + rot[0] * rot[1]),
520
- 2.0 * (rot[1] * rot[3] + rot[0] * rot[2]), 2.0 * (rot[2] * rot[3] - rot[0] * rot[1]), 1.0 - 2.0 * (rot[1] * rot[1] + rot[2] * rot[2])].map((k, i) => k * scale[Math.floor(i / 3)]);
521
- const sigma = [M[0]*M[0]+M[3]*M[3]+M[6]*M[6], M[0]*M[1]+M[3]*M[4]+M[6]*M[7], M[0]*M[2]+M[3]*M[5]+M[6]*M[8],
522
- M[1]*M[1]+M[4]*M[4]+M[7]*M[7], M[1]*M[2]+M[4]*M[5]+M[7]*M[8], M[2]*M[2]+M[5]*M[5]+M[8]*M[8]];
523
- texdata[8 * i + 4] = packHalf2x16(4 * sigma[0], 4 * sigma[1]);
524
- texdata[8 * i + 5] = packHalf2x16(4 * sigma[2], 4 * sigma[3]);
525
- texdata[8 * i + 6] = packHalf2x16(4 * sigma[4], 4 * sigma[5]);
526
- }
527
- self.postMessage({ texdata, texwidth, texheight, vertexCount }, [texdata.buffer]);
 
 
 
 
 
 
 
 
 
 
 
528
  }
529
- self.onmessage = (e) => {
530
- console.log('[Worker] Message received:', e.data);
531
- if (e.data.ply) {
532
- try {
533
- console.log('[Worker] Processing PLY buffer...');
534
- buffer = processPlyBuffer(e.data.ply);
535
- vertexCount = Math.floor(buffer.byteLength / rowLength);
536
- console.log('[Worker] Buffer processed, vertex count:', vertexCount);
537
- console.log('[Worker] Generating texture...');
538
- generateTexture();
539
- console.log('[Worker] Texture generated and sent');
540
- } catch (error) {
541
- console.error('[Worker] Error:', error);
542
- console.error('[Worker] Stack:', error.stack);
543
- }
544
- }
545
- };
546
- \`;
547
- return new Worker(URL.createObjectURL(new Blob([code], { type: 'application/javascript' })));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  }
549
 
550
  const invert4 = (a) => {
 
437
  }\`;
438
 
439
  function createWorker() {
440
+ const workerCode = `
441
+ let buffer, vertexCount = 0;
442
+ const rowLength = 32;
443
+ var _floatView = new Float32Array(1), _int32View = new Int32Array(_floatView.buffer);
444
+
445
+ function floatToHalf(float) {
446
+ _floatView[0] = float;
447
+ var f = _int32View[0];
448
+ var sign = (f >> 31) & 0x0001, exp = (f >> 23) & 0x00ff, frac = f & 0x007fffff, newExp;
449
+ if (exp == 0) newExp = 0;
450
+ else if (exp < 113) {
451
+ newExp = 0; frac |= 0x00800000; frac = frac >> (113 - exp);
452
+ if (frac & 0x01000000) { newExp = 1; frac = 0; }
453
+ } else if (exp < 142) newExp = exp - 112;
454
+ else { newExp = 31; frac = 0; }
455
+ return (sign << 15) | (newExp << 10) | (frac >> 13);
456
+ }
457
+
458
+ function packHalf2x16(x, y) {
459
+ return (floatToHalf(x) | (floatToHalf(y) << 16)) >>> 0;
460
+ }
461
+
462
+ function processPlyBuffer(inputBuffer) {
463
+ const ubuf = new Uint8Array(inputBuffer);
464
+ const header = new TextDecoder().decode(ubuf.slice(0, 10240));
465
+ const header_end = "end_header\\n";
466
+ const header_end_index = header.indexOf(header_end);
467
+ if (header_end_index < 0) throw new Error("Unable to read PLY header");
468
+
469
+ const match = /element vertex (\\d+)\\n/.exec(header);
470
+ const vertexCount = parseInt(match[1]);
471
+ console.log("Vertex Count:", vertexCount);
472
+
473
+ let row_offset = 0, offsets = {}, types = {};
474
+ const TYPE_MAP = {
475
+ double: "getFloat64", int: "getInt32", uint: "getUint32",
476
+ float: "getFloat32", short: "getInt16", ushort: "getUint16", uchar: "getUint8"
477
+ };
478
+
479
+ const lines = header.slice(0, header_end_index).split("\\n");
480
+ for (let line of lines) {
481
+ if (line.startsWith("property ")) {
482
+ const parts = line.split(" ");
483
+ const type = parts[1];
484
+ const name = parts[2];
485
+ const arrayType = TYPE_MAP[type] || "getInt8";
486
+ types[name] = arrayType;
487
+ offsets[name] = row_offset;
488
+ row_offset += parseInt(arrayType.replace(/[^\\d]/g, "")) / 8;
489
  }
490
+ }
491
+
492
+ let dataView = new DataView(inputBuffer, header_end_index + header_end.length);
493
+ let row = 0;
494
+ const attrs = new Proxy({}, {
495
+ get(target, prop) {
496
+ if (!types[prop]) throw new Error(prop + " not found");
497
+ return dataView[types[prop]](row * row_offset + offsets[prop], true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  }
499
+ });
500
+
501
+ let sizeList = new Float32Array(vertexCount);
502
+ let sizeIndex = new Uint32Array(vertexCount);
503
+ for (row = 0; row < vertexCount; row++) {
504
+ sizeIndex[row] = row;
505
+ if (!types["scale_0"]) continue;
506
+ const size = Math.exp(attrs.scale_0) * Math.exp(attrs.scale_1) * Math.exp(attrs.scale_2);
507
+ const opacity = 1 / (1 + Math.exp(-attrs.opacity));
508
+ sizeList[row] = size * opacity;
509
+ }
510
+ sizeIndex.sort((b, a) => sizeList[a] - sizeList[b]);
511
+
512
+ const buffer = new ArrayBuffer(rowLength * vertexCount);
513
+ for (let j = 0; j < vertexCount; j++) {
514
+ row = sizeIndex[j];
515
+ const position = new Float32Array(buffer, j * rowLength, 3);
516
+ const scales = new Float32Array(buffer, j * rowLength + 12, 3);
517
+ const rgba = new Uint8ClampedArray(buffer, j * rowLength + 24, 4);
518
+ const rot = new Uint8ClampedArray(buffer, j * rowLength + 28, 4);
519
+
520
+ if (types["scale_0"]) {
521
+ const qlen = Math.sqrt(attrs.rot_0 ** 2 + attrs.rot_1 ** 2 + attrs.rot_2 ** 2 + attrs.rot_3 ** 2);
522
+ rot[0] = (attrs.rot_0 / qlen) * 128 + 128;
523
+ rot[1] = (attrs.rot_1 / qlen) * 128 + 128;
524
+ rot[2] = (attrs.rot_2 / qlen) * 128 + 128;
525
+ rot[3] = (attrs.rot_3 / qlen) * 128 + 128;
526
+ scales[0] = Math.exp(attrs.scale_0);
527
+ scales[1] = Math.exp(attrs.scale_1);
528
+ scales[2] = Math.exp(attrs.scale_2);
529
+ } else {
530
+ scales[0] = scales[1] = scales[2] = 0.01;
531
+ rot[0] = 255; rot[1] = rot[2] = rot[3] = 0;
532
  }
533
+
534
+ position[0] = attrs.x;
535
+ position[1] = attrs.y;
536
+ position[2] = attrs.z;
537
+
538
+ if (types["f_dc_0"]) {
539
+ const SH_C0 = 0.28209479177387814;
540
+ rgba[0] = (0.5 + SH_C0 * attrs.f_dc_0) * 255;
541
+ rgba[1] = (0.5 + SH_C0 * attrs.f_dc_1) * 255;
542
+ rgba[2] = (0.5 + SH_C0 * attrs.f_dc_2) * 255;
543
+ } else {
544
+ rgba[0] = attrs.red;
545
+ rgba[1] = attrs.green;
546
+ rgba[2] = attrs.blue;
547
+ }
548
+ rgba[3] = types["opacity"] ? (1 / (1 + Math.exp(-attrs.opacity))) * 255 : 255;
549
+ }
550
+ return buffer;
551
+ }
552
+
553
+ function generateTexture() {
554
+ if (!buffer) return;
555
+ const f_buffer = new Float32Array(buffer);
556
+ const u_buffer = new Uint8Array(buffer);
557
+ const texwidth = 2048;
558
+ const texheight = Math.ceil((2 * vertexCount) / texwidth);
559
+ const texdata = new Uint32Array(texwidth * texheight * 4);
560
+ const texdata_c = new Uint8Array(texdata.buffer);
561
+ const texdata_f = new Float32Array(texdata.buffer);
562
+
563
+ for (let i = 0; i < vertexCount; i++) {
564
+ texdata_f[8 * i + 0] = f_buffer[8 * i + 0];
565
+ texdata_f[8 * i + 1] = f_buffer[8 * i + 1];
566
+ texdata_f[8 * i + 2] = f_buffer[8 * i + 2];
567
+ texdata_c[4 * (8 * i + 7) + 0] = u_buffer[32 * i + 24 + 0];
568
+ texdata_c[4 * (8 * i + 7) + 1] = u_buffer[32 * i + 24 + 1];
569
+ texdata_c[4 * (8 * i + 7) + 2] = u_buffer[32 * i + 24 + 2];
570
+ texdata_c[4 * (8 * i + 7) + 3] = u_buffer[32 * i + 24 + 3];
571
+
572
+ let scale = [f_buffer[8 * i + 3], f_buffer[8 * i + 4], f_buffer[8 * i + 5]];
573
+ let rot = [
574
+ (u_buffer[32 * i + 28] - 128) / 128,
575
+ (u_buffer[32 * i + 29] - 128) / 128,
576
+ (u_buffer[32 * i + 30] - 128) / 128,
577
+ (u_buffer[32 * i + 31] - 128) / 128
578
+ ];
579
+
580
+ const M = [
581
+ 1.0 - 2.0 * (rot[2] * rot[2] + rot[3] * rot[3]),
582
+ 2.0 * (rot[1] * rot[2] + rot[0] * rot[3]),
583
+ 2.0 * (rot[1] * rot[3] - rot[0] * rot[2]),
584
+ 2.0 * (rot[1] * rot[2] - rot[0] * rot[3]),
585
+ 1.0 - 2.0 * (rot[1] * rot[1] + rot[3] * rot[3]),
586
+ 2.0 * (rot[2] * rot[3] + rot[0] * rot[1]),
587
+ 2.0 * (rot[1] * rot[3] + rot[0] * rot[2]),
588
+ 2.0 * (rot[2] * rot[3] - rot[0] * rot[1]),
589
+ 1.0 - 2.0 * (rot[1] * rot[1] + rot[2] * rot[2])
590
+ ].map((k, idx) => k * scale[Math.floor(idx / 3)]);
591
+
592
+ const sigma = [
593
+ M[0]*M[0] + M[3]*M[3] + M[6]*M[6],
594
+ M[0]*M[1] + M[3]*M[4] + M[6]*M[7],
595
+ M[0]*M[2] + M[3]*M[5] + M[6]*M[8],
596
+ M[1]*M[1] + M[4]*M[4] + M[7]*M[7],
597
+ M[1]*M[2] + M[4]*M[5] + M[7]*M[8],
598
+ M[2]*M[2] + M[5]*M[5] + M[8]*M[8]
599
+ ];
600
+
601
+ texdata[8 * i + 4] = packHalf2x16(4 * sigma[0], 4 * sigma[1]);
602
+ texdata[8 * i + 5] = packHalf2x16(4 * sigma[2], 4 * sigma[3]);
603
+ texdata[8 * i + 6] = packHalf2x16(4 * sigma[4], 4 * sigma[5]);
604
+ }
605
+ self.postMessage({ texdata, texwidth, texheight, vertexCount }, [texdata.buffer]);
606
+ }
607
+
608
+ self.onmessage = (e) => {
609
+ console.log('[Worker] Message received');
610
+ if (e.data.ply) {
611
+ try {
612
+ console.log('[Worker] Processing PLY buffer...');
613
+ buffer = processPlyBuffer(e.data.ply);
614
+ vertexCount = Math.floor(buffer.byteLength / rowLength);
615
+ console.log('[Worker] Vertex count:', vertexCount);
616
+ generateTexture();
617
+ console.log('[Worker] Texture sent');
618
+ } catch (error) {
619
+ console.error('[Worker] Error:', error);
620
+ }
621
+ }
622
+ };
623
+ `;
624
+ return new Worker(URL.createObjectURL(new Blob([workerCode], { type: 'application/javascript' })));
625
  }
626
 
627
  const invert4 = (a) => {