Tyler
Tyler

Reputation: 283

How do I translate vertices in a THREE.PointCloud object?

I am trying to:

MayaVi surface render

The problem is that:


Example server response (I have included sample data at the bottom of this post):

{'geometry': [[-156, 65, 89],
              [268, 84, 337],
              [-205, 68, 170],
              [-87, 69, 52],
              ...
              [289, 81, 143],
              [141, 78, 280],
              [403, 75, 351]],
 'metadata': {'max': {'x': 421, 'y': 105, 'z': 458},
          'min': {'x': -335, 'y': 63, 'z': 39}}}

The three.js code used to create the point cloud:

  var container;
  var scene, camera, renderer, controls;
  var geometry, material, mesh;

  init();
  animate();

  function init() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 5000);
    camera.position.z = 2750;

    //Add a buffer geometry for particle system
    var geometry = new THREE.BufferGeometry();
    var particles = {{ len(topology['geometry']) }};
    var geometry = new THREE.BufferGeometry();
    var positions = new Float32Array(particles * 3);
    var colors = new Float32Array(particles * 3);
    var color = new THREE.Color();

    var i = 0;
    {% for point in topology['geometry'] %}
      var x = {{ point[0] }};
      var y = {{ point[1] }};
      var z = {{ point[2] }};

      //Store the position of the point
      positions[i]     = x;
      positions[i + 1] = y;
      positions[i + 2] = z;

      //Assign a colour to the point
      color.setRGB(0.42, 0.42, 0.42);
      colors[i]     = color.r;
      colors[i + 1] = color.g;
      colors[i + 2] = color.b;
      i+=1;
    {% end %}

    geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
    geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
    geometry.computeBoundingSphere();

    var material = new THREE.PointCloudMaterial({ size: 15, vertexColors: THREE.VertexColors });
    particleSystem = new THREE.PointCloud(geometry, material);
    scene.add(particleSystem);

    //Lights
    light = new THREE.DirectionalLight(0xffffff);
    light.position.set(1, 1, 1);
    scene.add(light);

    //Set up renderer
    renderer = new THREE.WebGLRenderer({ antialias:false });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);

    //Attach renderer to #container DOM element
    container = document.getElementById('container');
    container.appendChild(renderer.domElement);

    //Add window listener for resize events
    window.addEventListener('resize', onWindowResize, false);

    //Call render loop
    animate();
  }

  function onWindowResize(){
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    render();
  }

  function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  }

  function render(){
    renderer.render(scene, camera);
  }

The scene ends up looking like this:

three.js

Any suggestions? I've used the following example code, but I'm having difficulty properly implementing scaling for the points in my dataset: http://threejs.org/examples/#webgl_buffergeometry_particles

Link to a sample of data that I am working with (2MB, 180k lines): https://gist.githubusercontent.com/TylerJFisher/659e3e233f8aa458feee/raw/889c0dd0093fd0476094af48488aab62c8666271/topology.asc

Upvotes: 5

Views: 4008

Answers (1)

prisoner849
prisoner849

Reputation: 17596

I used your sample data. Put it in an array, like this:

var data = [
"-156 65 89",
"268 84 337",
"-205 68 170",
"-87 69 52",
...
];

and used THREE.Geometry() for PointCloud:

            var geometry = new THREE.Geometry();
            var colors = [];

            for ( var x = 0; x < data.length; x++){
                    var pointCoord = data[ x ].split(" ");
                    if ( pointCoord.length != 3 ) continue;
                    var currentColor = new THREE.Color( 0.5, 1, 0.5 );
                    colors.push( currentColor );
                    geometry.vertices.push(
                        new THREE.Vector3(
                            pointCoord[2],
                            pointCoord[1],
                            pointCoord[0]
                        )
                    );
                };
            //

            console.log( geometry.vertices.length );

            geometry.colors = colors;

            var material = new THREE.PointCloudMaterial( { size: 1, vertexColors: THREE.VertexColors } );

            particleSystem = new THREE.PointCloud( geometry, material );
            scene.add( particleSystem );

Also, in geodata, coordinates x and y are always swapped (in this case, there are x and z). If you won't do it, you'll get mirrored object then. That's why I put it as

                        new THREE.Vector3(
                            pointCoord[2],
                            pointCoord[1],
                            pointCoord[0]
                        )

instead of

                        new THREE.Vector3(
                            pointCoord[0],
                            pointCoord[1],
                            pointCoord[2]
                        )

The result is here: geodata

And yes, some lines in your sample data seem incorrect. Means they have 1 or 2 values instead of 3.

Upvotes: 5

Related Questions