5

I have a THREE.Geometry in my scene that contains over 5,000 vertices. What I want to do is to add THREE.Points to the scene for only 3 vertices of the mesh containing the geometry. I want to achieve something like this:

enter image description here

I took the 3 vertices of the first face of the existing geometry and added them to the vertices of my new geometry, which is supposed to contain the 3 vertices. I used THREE.Points and THREE.PointsMaterial but I have tried out the same thing with THREE.LineSegments and THREE.LineBasicMaterial and the result is the same. (with the exception that instead of points there are lines).

var vertices = [
  mesh.geometry.faces[0].a,
  mesh.geometry.faces[0].b,
  mesh.geometry.faces[0].c
];


vertices.forEach( function(vId,i){
  vertices[i].index = i;
  vertices[i] = mesh.geometry.vertices[vId].clone();
  vertices[i].l2w = mesh.localToWorld(vertices[i].clone());
  vertices[i].id = vId;
  vertices[i].distance = vertices[i].l2w.distanceTo(camera.position);

})


var plane_geom = new THREE.Geometry();
plane_geom.vertices.push(vertices[0]);
plane_geom.vertices.push(vertices[1]);
plane_geom.vertices.push(vertices[2]);


plane_geom.verticesNeedUpdate = true;
plane_geom.elementsNeedUpdate = true;
plane_geom.computeVertexNormals();


var pointsMaterial2 = new THREE.PointsMaterial({
  size: 2,
  color: "red"
});

var plane_mesh =  new THREE.Points( plane_geom, pointsMaterial2 );
 scene.add( plane_mesh );


mesh.geometry.dispose();
mesh.material.dispose();
scene.remove( mesh);

and my initial geometry is globally defined, is the geometry of the loaded STL-object and is of type THREE.Geometry. The mesh with this geometry is added to the scene in the init function. The geometry object looks as follows:

__directGeometry: Object { vertices: (30006) […], normals: (30006) […], 
colors: (30006) […], … }
__bufferGeometry: Object { uuid: "10EE834D-B19E-4C27-B831-F484D908DB06",                   
name: "", type: "BufferGeometry", … }
_listeners: Object { dispose: (1) […] }
boundingBox: Object { min: {…}, max: {…} }
boundingSphere: Object { center: {…}, radius: 135.73491999459804 }
colors: Array []
colorsNeedUpdate: false
elementsNeedUpdate: false
faceVertexUvs: Array [ [] ]
faces: Array(10002) [ {…}, {…}, {…}, … ]
groupsNeedUpdate: false
id: 2
lineDistances: Array []
lineDistancesNeedUpdate: false
morphNormals: Array []
morphTargets: Array []
name: ""
normalsNeedUpdate: false
skinIndices: Array []
skinWeights: Array []
type: "Geometry"
uuid: "0EB01FF3-E9BF-4CAD-AA97-5EC2933F0D9C"
uvsNeedUpdate: false
vertices: Array(5003) [ {…}, {…}, {…}, … ]
verticesNeedUpdate: false

After adding the new mesh plane_mesh with the new geometry to the scene, all the points (on each vertex) of the geometry are displayed (over 5,000 points). However, if I dispose the initial mesh from the scene, I can see just the 3 points. When printing out plane_mesh everything seems normal and the mesh contains only the 3 vertices... After a lot of trial and error, I realized that all of the operations are performed on the initial mesh. Only after disposing of the mesh, plane_mesh is added to the scene.

Any help would be greatly appreciated!

1 Answer 1

3
+25

You can create a geometry for a triangle once and then just change values of its vertices by copying them from the original geometry. Here is just a concept (r108):

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var geom = new THREE.PlaneBufferGeometry(10, 10, 4, 4);
var mat = new THREE.MeshBasicMaterial({
  color: "aqua",
  wireframe: true
});
var mesh = new THREE.Mesh(geom, mat);
scene.add(mesh);

var pointsGeom = new THREE.BufferGeometry().setFromPoints([
  new THREE.Vector3(),
  new THREE.Vector3(),
  new THREE.Vector3()
]);
var pointsMat = new THREE.PointsMaterial({
  size: 1,
  color: "red"
});
var points = new THREE.Points(pointsGeom, pointsMat);
scene.add(points);

setInterval(() => {
  let faces = geom.index.count / 3;
  let face = THREE.Math.randInt(0, faces - 1);

  setTriangle(face);

}, 1000);

var v3 = new THREE.Vector3(); // temp vector

function setTriangle(face) {

  for (let i = 0; i < 3; i++) {
    v3.fromBufferAttribute(geom.attributes.position, geom.index.getX(face * 3 + i));
    pointsGeom.attributes.position.setXYZ(i, v3.x, v3.y, v3.z);
  }

  pointsGeom.attributes.position.needsUpdate = true;

}

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera)
});
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.