From 1567c341aeb2159ddd7e91c01bfd5bac9bd56528 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Thu, 13 May 2021 18:48:47 +0100 Subject: [PATCH] feat(viewer): adds pointcloud support --- packages/viewer/src/modules/Converter.js | 39 ++++++++++++++++ .../viewer/src/modules/SceneObjectManager.js | 45 +++++++++++++++++-- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/packages/viewer/src/modules/Converter.js b/packages/viewer/src/modules/Converter.js index ae189eb25..4bafcffd1 100644 --- a/packages/viewer/src/modules/Converter.js +++ b/packages/viewer/src/modules/Converter.js @@ -163,6 +163,45 @@ export default class Coverter { return type } + async PointcloudToBufferGeometry( obj ) { + + console.log( obj ) + let conversionFactor = getConversionFactor( obj.units ) + let buffer = new THREE.BufferGeometry( ) + + let vertices = await this.dechunk( obj.points ) + + buffer.setAttribute( + 'position', + new THREE.Float32BufferAttribute( conversionFactor === 1 ? vertices : vertices.map( v => v * conversionFactor ), 3 ) ) + + // TODO: checkout colours + let colorsRaw = await this.dechunk( obj.colors ) + + if ( colorsRaw && colorsRaw.length !== 0 ) { + + if ( colorsRaw.length !== buffer.attributes.position.count ) { + console.warn( `Mesh (id ${obj.id}) colours are mismatched with vertice counts. The number of colours must equal the number of vertices.` ) + } + + buffer.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( buffer.attributes.position.count * 3 ), 3 ) ) + + for ( let i = 0; i < buffer.attributes.position.count; i++ ) { + let color = colorsRaw[i] + let r = color >> 16 & 0xFF + let g = color >> 8 & 0xFF + let b = color & 0xFF + buffer.attributes.color.setXYZ( i, r/255, g/255, b/255 ) + } + } + + delete obj.points + delete obj.colors + delete obj.sizes // note, these might be used in the future + + return new ObjectWrapper( buffer, obj, 'pointcloud' ) + } + async BrepToBufferGeometry( obj ) { try { if ( !obj ) return diff --git a/packages/viewer/src/modules/SceneObjectManager.js b/packages/viewer/src/modules/SceneObjectManager.js index 9c437ce85..3e26e0e31 100644 --- a/packages/viewer/src/modules/SceneObjectManager.js +++ b/packages/viewer/src/modules/SceneObjectManager.js @@ -50,7 +50,13 @@ export default class SceneObjectManager { } ) this.lineMaterial = new THREE.LineBasicMaterial( { color: 0x7F7F7F } ) - this.pointMaterial = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false, color: 0x7F7F7F } ) + this.pointMaterial = new THREE.PointsMaterial( + { size: 2, sizeAttenuation: false, color: 0x7F7F7F } + ) + + this.pointVertexColorsMaterial = new THREE.PointsMaterial( { + size: 2, sizeAttenuation: false, vertexColors: true + } ) this.objectIds = [] this.postLoad = debounce( () => { this._postLoadFunction() }, 200 ) @@ -64,7 +70,7 @@ export default class SceneObjectManager { } get materials() { - return [ this.lineMaterial, this.pointMaterial, this.transparentMaterial, this.solidMaterial, this.solidVertexMaterial ] + return [ this.lineMaterial, this.pointMaterial, this.transparentMaterial, this.solidMaterial, this.solidVertexMaterial, this.pointVertexColorsMaterial ] } // Note: we might switch later down the line from cloning materials to solely @@ -130,6 +136,10 @@ export default class SceneObjectManager { case 'point': this.addPoint( wrapper ) break + + case 'pointcloud': + this.addPointCloud( wrapper ) + break } this.postLoad() @@ -160,13 +170,42 @@ export default class SceneObjectManager { } addPoint( wrapper ){ - var dot = new THREE.Points( wrapper.bufferGeometry, this.pointMaterial ) + let dot = new THREE.Points( wrapper.bufferGeometry, this.pointMaterial ) dot.userData = wrapper.meta dot.uuid = wrapper.meta.id this.objectIds.push( dot.uuid ) this.pointObjects.add( dot ) } + addPointCloud( wrapper ) { + + let clouds + + if ( wrapper.bufferGeometry.attributes.color ) { + + clouds = new THREE.Points( wrapper.bufferGeometry, this.pointVertexColorsMaterial ) + } else if ( wrapper.meta.renderMaterial ) { + let renderMat = wrapper.meta.renderMaterial + let color = new THREE.Color( this._argbToRGB( renderMat.diffuse ) ) + + this._normaliseColor( color ) + let material = this.pointMaterial.clone() + material.clippingPlanes = this.viewer.interactions.sectionBox.planes + + material.color = color + + clouds = new THREE.Points( wrapper.bufferGeometry, material ) + } else { + clouds = new THREE.Points( wrapper.bufferGeometry, this.pointMaterial ) + } + + + clouds.userData = wrapper.meta + clouds.uuid = wrapper.meta.id + this.objectIds.push( clouds.uuid ) + this.pointObjects.add( clouds ) + } + removeObject( id ) { // TODO }