I have a ASCII PCD file I want to show with Three.Js.
The files can be around 20 MB - 30 MB.
So that isn’t really big.
I found an example that shows a PCD file. But that PCD file is Binary so I found the ASCII file in your repo. So I first tried with that one. But it’s very small. So that worked. So I tried with my PCD file.
I don’t get any error’s, but I don’t see it.
I tried to make the points bigger, but that did’t even worked.
So I thought maybe is the file to big, but I found that you can even use PCD files thatare around 64MB.
So I tried to use a smaller part of the PCD files only 233 points instead of 655000 points before.
But I don’t see even that.
If you want to try here is my 233 points example.
test.pcd (11.3 KB)
The problem is that your PCD file contains values like 5.1507448e+37
in order to represent the vertex color.
The loader interprets this value as zero which means your points have a black color. If I set material.vertexColors = THREE.NoColors;
, the points show up with a default white color.
Since values like 5.5162769e+37
look wrong, there seems to be a problem with your PCD exporter.
Did you do something special with the material.vertexColor = THREE.NoColors
because I still don’t see anything.
I added material.vertexColor = THREE.NoColors
like you said.
I consoled logged the mesh.material
after it was added to the scene and the value says material.vertexColor = 0
loader.load( 'test.pcd', function ( mesh ) {
mesh.material.vertexColors = THREE.NoColors;
scene.add( mesh );
console.log(mesh.material);
var center = mesh.geometry.boundingSphere.center;
controls.target.set( center.x, center.y, center.z );
controls.update();
} );
My complete code
const WEBGL = require('../lib/webgl');
const Stats = require('../lib/lib.stats.min');
if (!WEBGL.WEBGL.isWebGLAvailable()) {
let warning = WEBGL.WEBGL.getWebGLErrorMessage();
document.getElementById('container').appendChild(warning);
}
let container, stats, material;
let camera, controls, scene, renderer;
init();
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
camera = new THREE.PerspectiveCamera( 15, window.innerWidth / window.innerHeight, 0.01, 40 );
camera.position.x = 0.4;
camera.position.z = - 2;
camera.up.set( 0, 0, 1 );
controls = new THREE.TrackballControls( camera );
scene.add( camera );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var loader = new THREE.PCDLoader();
loader.load( 'test.pcd', function ( mesh ) {
mesh.material.vertexColors = THREE.NoColors;
scene.add( mesh );
console.log(mesh.material);
var center = mesh.geometry.boundingSphere.center;
controls.target.set( center.x, center.y, center.z );
controls.update();
} );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'keypress', keyboard );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function keyboard( ev ) {
var ZaghettoMesh = scene.getObjectByName( 'test.pcd' );
switch ( ev.key || String.fromCharCode( ev.keyCode || ev.charCode ) ) {
case '+':
ZaghettoMesh.material.size *= 1.2;
ZaghettoMesh.material.needsUpdate = true;
break;
case '-':
ZaghettoMesh.material.size /= 1.2;
ZaghettoMesh.material.needsUpdate = true;
break;
case 'c':
ZaghettoMesh.material.color.setHex( Math.random() * 0xffffff );
ZaghettoMesh.material.needsUpdate = true;
break;
}
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
stats.update();
}
I recommend you inspect the geometry data of your point cloud. You will see that the scale of the geometry exceeds the scale of your scene. So you might want to scale down the object (something like points.scale.multiplyScalar( 0.1 )
) and also increase the far plane of your camera.
It makes also sense to center the geometry since it seems to have an offset from the origin. You can do this by calling geometry.center()
.
BTW: I see you are using the code from the official PCD example. You should be aware that the settings of the scene are not universal. The demo is not a PCD viewer. So you have to make changes depending on the characteristic of your geometry.
Thank you very much! For helping me out, it worked.
I have one other question my pointclouds have around 655 000 points. Is there a faster way to update the current pointcloud instead of doing this:
var CurrentPCD= scene.getObjectByName('Perrine.pcd');
loader = new THREE.PCDLoader();
await loader.load('Perry.pcd', function (mesh) {
mesh.material.vertexColors = THREE.NoColors;
CurrentPCD.geometry = mesh.geometry;
CurrentPCD.geometry.center();
});
Because that way will around 12 seconds to update and the screen will freeze for like 2 seconds.
As you can see at the following example, the scene contains a point cloud with 500.000 points. The setup is very fast but the rendering is not optimal (at least on my iMac where I have around 43 FPS). So the mentioned delay might be caused by the parsing overhead of PCDLoader
. You can try to convert the PCD file to glTF
or you try to load your point cloud data in a worker.
https://threejs.org/examples/webgl_buffergeometry_points.html
Thanks I tried to use glTF then I have bigger files almost pcd size * 2, and it’s slower. I will look in to the worker. Thanks for the tips.