4
votes

Adding new vertices to a three.js mesh goes by mesh.geometry.vertices.push(new THREE.Vector3(x, y, z)), but how do I remove them?

"geometry" is an array, so I thought, I could remove vertices with:

mesh.geometry.vertices.splice(vertexIndex, 1)

mesh.geometry.verticesNeedUpdate = true;

But when I do that, that whole thing breaks with three.js internal error messages that say: "Uncaught TypeError: Cannot read property 'x' of undefined" inside three.min.js.

I searched their wiki, their github issues. And can't find an answer to this. The mesh is a simple BoxGeometry, so not even a custom one.

1
probaly this question might help stackoverflow.com/questions/15384078/… I guess its the good old verticesNeedUpdate flag?philipp
@philipp: I forgot to mention that i already use this flag. Question is edited. The scene breaks immedieately after removing the vertex.nora
does the anwser solve your problem ?Atrahasis

1 Answers

4
votes

In threejs each face is made of 3 vertices. Here is an example to make it clearer. Here is how you create a geometry in r71 :

 geometry=new THREE.Geometry();

 geometry.vertices.push(// few vertices with random coordinates
     new THREE.Vector3(12,15,5),//index:0 -- the numbers are (x,y,z) coordinates
     new THREE.Vector3(10,15,5),//index:1
     new THREE.Vector3(12,10,2),//index:2
     new THREE.Vector3(10,10,2)//index:3
 );

 geometry.faces.push(
     new THREE.Face3(0,1,2),//those numbers are indices of vertices in the previous array
     new THREE.Face3(0,3,2)
 );

 geometry.computeFaceNormals();// we won't care about this here

(I did not care about the values so i do not know which shape it can give)

What you can see is that two arrays are built : vertices and faces. Now what happens at each frame is that each face is 'drawed' with the position of its vertices.

You ask what is wrong by deleting a vertex in the geometry.vertices array : let's imagine the second vertex above is deleted. The array now looks like this :

 geometry.vertices=[
     THREE.Vector3(12,15,5),//index:0
     THREE.Vector3(12,10,2),//new index:1
     THREE.Vector3(10,10,2)//new index:2
 ];

There is no more vertex at index 3. So when the GPU will draw the next frame, if a face points to it (here the second face) it will try to access its coordinates (first x before y and z). That is why the console returns that it cannot read x of undefined.

Here was a long explanation of the error. You can see the vertex deletion also shifted the array so faces do not have the correct shape, and their normals do not correspond anymore. The worst is that the buffer will have to change and that is simply not allowed, as stated there for example :

Dynamically Adding Vertices to a Line in Three.js

Adding geometry to a three.js mesh after render

The solution is to use tricks, as quoted : modify your vertex coordinates, hide faces... this depends on what you want to do.

If your scene has not much vertices you can also remove the previous mesh and create a new one with a new geometry, without one vertex and with a corrected face array.