Fast-Quadric-Mesh-Simplification
Fast-Quadric-Mesh-Simplification copied to clipboard
Dealing with normals
From what I can see from the OBJ example, normals appear to be lost in the conversion process. I can see they are generated in update_mesh
, but that's per triangle, and the original normals aren't used.
I even saw that the THREE.JS example looses its smooth shading in the process of decimation.
So how are we supposed to get back a mesh with smooth normals? Do we have to take those from Triangle, average (how to do fast?) and renormalize them so we can store them per vertex?
I can branch and choose either smooth generation or flat generation, but that means any mix of the two from the original mesh would be lost (i.e if I decimate a cylinder, how do I make the round part smooth and the caps flat?). Note: I don't necessarily know which mesh I decimate, I'd like to use this with user-made and procedurally generated meshes.
- Initialize an array with one normal (3D vector) for each vertex where all components (X,Y,Z) are set to zero.
- For each face (triangle with 3 vertices), compute the surface normal (merely the cross-product) assuming CCW winding. Add this vector to each of the three vertices that contributed to the triangle.
- For each vertex, normalize the normal length to 1.
Here is my pascal code:
setlength(vNorm, length(vertices) );
//compute vertex normals
fNorm := ptf(0,0,0);
for i := 0 to (length(vertices)-1) do
vNorm[i] := fNorm;
for i := 0 to (length(faces)-1) do begin //compute the normal for each face
fNorm := getSurfaceNormal(vertices[faces[i].X], vertices[faces[i].Y], vertices[faces[i].Z]);
vectorAdd(vNorm[faces[i].X] , fNorm);
vectorAdd(vNorm[faces[i].Y] , fNorm);
vectorAdd(vNorm[faces[i].Z] , fNorm);
end;
for i := 0 to (length(vertices)-1) do
vectorNormalize(vNorm[i]);
See here for a Python solution. I am not familiar with three.js, but I think BufferGeometry.computeVertexNormals can re-generate normals. Does this resolve your issue?