Using of THREE.Triangle() can be helpful.
Something like this:
var pos = geometry.attributes.position;
var tri = new THREE.Triangle(); // for re-use
var a = new THREE.Vector3(); // for re-use
var b = new THREE.Vector3(); // for re-use
var c = new THREE.Vector3(); // for re-use
var normals = [];
var faces = pos.count / 3;
for (let i = 0; i < faces; i++){
a.fromBufferAttribute(pos, i * 3 + 0);
b.fromBufferAttribute(pos, i * 3 + 1);
c.fromBufferAttribute(pos, i * 3 + 2);
tri.set(a, b, c);
let n = new THREE.Vector3();
tri.getNormal(n);
normals.push(n);
}
There has to be something wrong with this code. a, b and c are on every loop cycle the same.
I tested with:
if (i==0 |i==5 | i==123 || i==227 ā¦)
console.log(tri);
Everytime the same numbers for a, b and c (f.e. for a.x = 1, a.y=2 a.z=3, b.x=4, b.y = 5ā¦). Same for every i
EDIT:
Ok i found itā¦ it works when the triangle is declared inside the for loop like this:
let tri = new THREE.Triangle();
Probably something strange happens when a triangles a,b and c is already declared and set to new vectorsā¦
I guess that all the logged values are equal to the values of the last triangle.
And I hope you didnāt put instantiating of triangle inside the loop.
This code doesnt work:
var pos = geometry.attributes.position; var tri = new THREE.Triangle(); // for re-use
var a = new THREE.Vector3(); // for re-use
var b = new THREE.Vector3(); // for re-use
var c = new THREE.Vector3(); // for re-use
var normals = [];
var faces = pos.count / 3;
for (let i = 0; i < faces; i++){
a.fromBufferAttribute(pos, i * 3 + 0);
b.fromBufferAttribute(pos, i * 3 + 1);
c.fromBufferAttribute(pos, i * 3 + 2);
tri.set(a, b, c);
let n = new THREE.Vector3();
tri.getNormal(n);
normals.push(n);
}
But this code does:
var pos = geometry.attributes.position;
var a = new THREE.Vector3(); // for re-use
var b = new THREE.Vector3(); // for re-use
var c = new THREE.Vector3(); // for re-use
var normals = [];
var faces = pos.count / 3;
for (let i = 0; i < faces; i++){ let tri = new THREE.Triangle(); // for re-use
a.fromBufferAttribute(pos, i * 3 + 0);
b.fromBufferAttribute(pos, i * 3 + 1);
c.fromBufferAttribute(pos, i * 3 + 2);
tri.set(a, b, c);
let n = new THREE.Vector3();
tri.getNormal(n);
normals.push(n);
}
@anon81599084
This code is indended to calculate normals. Have you tried to log result normals?
When you log the triangle, when itās outside of the loop, you log the same object.
@yombo i comes from the number of faces, which is amount of vertices (.count) divided by 3. But maybe Iām wrong with my suggestion as I wrote that code from the scratch, thus itās not tested
@prisoner849 i know its intended to calculate normals, but if all triangles are the same, all normal are the same, too. It actually doesnāt matter that much anymore, because i just use the second code where every triangle is defined in the loop (let tri) and it works like this for me. I was just unsure if its normal when you code: tri.set(v1,v2,v3) and log that and then tri.set(v4, v5, v6) and log that again, its always the same.
@yombo the code works almost like prisoner849 said. yes every face has 9 floats, but here you just want the 3 vectors
my code atm works without errors, i have to code colors now and then debug. (already debugged some parts) and i think it looks quite good. I will keep you up to date
Yes i tried. All normals were the same and all triangles until i changed āvar triā to ālet triā and put it in the loop. After that i was curious about it, why this happens and tried the code on post 24 and i still donāt understand why it works like that (maybe a bug or maybe iām a stupid, both could be true) but whatever, its working now x)
I want to thank all of you guys very much!! It works perfectly. A big surface takes some time (max. 20sec.) but i will try to maximize code effiency now, refactor and i will probably show the loading progress somehow. Thank you very much!
The actual problem is solved but i have one more little thing with this solution where you guys maybe also can help me: When i have two objects now and i computed for both of them a surface, i want these surfaces to get together. So thereās alot of possibilities now. I could put a 3d Box around them and match them together or a more complex approach would be: I calculate the distance of every obj1.vertex.position to every other obj2.vertex.position and find the closest one and translate an object in the direction of the other object this far. It would have a bad calculation time, but it would be stupid to calculate these surfaces to then put a 3d box around it and make it inaccurate again. Do you guys have other ideas then the 2 i described?
EDIT: Calculating the midpoint of the surfaces would be very interesting.
To calculate the midpoint of a mesh you just sum up all the vertices and finally divide the result by the number of points. I.E., you get the average of all .x, .y and .z
This was super helpful for me, is there a way to use this function with the geometry.index instead? Iām having trouble getting values for each of instance.
var triangles = [];
var pos = threeMesh1.geometry.index;
var a = new THREE.Vector3(); // for re-use
// var b = new THREE.Vector3(); // for re-use
// var c = new THREE.Vector3(); // for re-use
var faces = pos.count / 3;
function makeTriangle() {
for (let i = 0; i < faces; i++){
var tri = new THREE.Triangle(); // for re-use
tri.setFromPointsAndIndices(pos i * 3 + 0, i * 3 + 1, i * 3 + 2);
let area_sum = tri.getArea();
// Add new triangle to initial "triangles" array
triangles.push(tri);
console.log(area_sum);
}
}
makeTriangle(triangles);
console.log(triangles); // returns [Triangle, Triangle, Triangle]