Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distance based addition of points to vertices (mesh geometry)

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!

like image 733
Lju Avatar asked Oct 16 '22 11:10

Lju


1 Answers

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>
like image 179
prisoner849 Avatar answered Oct 19 '22 01:10

prisoner849