Ensure that the normal phase of the normal is outward

20 views (last 30 days)
I have taken normals for each boundary surface and after unitization they point to the outside of the geometry, but a small portion of the normals are wrong, what is the reason for this and how can I correct it?
function faceNormals = patchnormals(vertices,faces)
normals = zeros(size(faces));
for i=1:size(faces,1)
v1 = vertices(faces(i,1),:);
v2 = vertices(faces(i,2),:);
v3 = vertices(faces(i,3),:);
edge1 = v2 - v1;
edge2 = v3 - v1;
normal = cross(edge1, edge2);
normal = normal / norm(normal);
normals(i,:) = normal;
end
centers = calculateCenters(vertices,faces);
if dot(normals,centers) > 0
normal = -normal;
end
faceNormals = normals;
end
function centers = calculateCenters(vertices,faces)
num_faces = size(faces, 1);
centers = zeros(num_faces, 3);
for i = 1:num_faces
idx1 = faces(i, 1);
idx2 = faces(i, 2);
idx3 = faces(i, 3);
v1 = vertices(idx1, :);
v2 = vertices(idx2, :);
v3 = vertices(idx3, :);
center = (v1 + v2 + v3) / 3;
centers(i, :) = center;
end
end

Accepted Answer

Hassaan
Hassaan on 16 Jan 2024
There seems to be a mistake in the conditional check where you determine the direction of the normal. You're only flipping the normal of the last face computed in the loop, not all the faces that have normals pointing in the wrong direction.
The check for flipping the normals should occur within the loop where you're iterating over each face. Also, you should be comparing the dot product of each normal with the corresponding face center, not all the centers at once.
function faceNormals = patchnormals(vertices,faces)
normals = zeros(size(faces, 1), 3);
centers = calculateCenters(vertices,faces);
for i = 1:size(faces, 1)
v1 = vertices(faces(i, 1), :);
v2 = vertices(faces(i, 2), :);
v3 = vertices(faces(i, 3), :);
edge1 = v2 - v1;
edge2 = v3 - v1;
normal = cross(edge1, edge2);
normal = normal / norm(normal);
% Check the direction of the normal against the center
if dot(normal, centers(i, :) - v1) > 0
normal = -normal;
end
normals(i, :) = normal;
end
faceNormals = normals;
end
function centers = calculateCenters(vertices,faces)
num_faces = size(faces, 1);
centers = zeros(num_faces, 3);
for i = 1:num_faces
idx1 = faces(i, 1);
idx2 = faces(i, 2);
idx3 = faces(i, 3);
v1 = vertices(idx1, :);
v2 = vertices(idx2, :);
v3 = vertices(idx3, :);
center = (v1 + v2 + v3) / 3;
centers(i, :) = center;
end
end
  • The direction check if dot(normal, centers(i, :) - v1) > 0 is inside the loop. This check calculates the dot product of the normal and the vector from the first vertex of the triangle to the center of the face. If the dot product is positive, it means the normal is pointing towards the outside, and if it's negative, it points towards the inside.
  • If the normal points towards the outside (which is not what you want), it gets flipped by multiplying by -1.
The code assumes that the mesh is consistently oriented, meaning all the triangles are wound in the same order (clockwise or counter-clockwise). If the mesh is not consistently oriented, the above method won't work correctly, and you would need to preprocess the mesh to ensure consistent orientation or use a more advanced algorithm to determine the correct direction of the normals.
Additionally, it's important to note that if your geometry is not closed (i.e., it has boundaries), the approach of flipping normals based on the center might not work as expected, because there isn't a clear inside or outside.
If you're dealing with a closed surface and you find that the normals are still not consistently pointing outward, you might be dealing with a non-manifold geometry or other issues with the mesh that are causing the inconsistencies. In such cases, you may need to clean up the mesh or use mesh repair tools before recalculating normals.
If you have a visualization tool or software, it's often helpful to visually inspect the normals after computation to verify their directions. If only a few normals are incorrect and you know their indices, you can flip them manually. However, if the issue is widespread, you should check for mesh consistency and consider using a mesh processing library that can handle these issues more robustly.
------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.
  1 Comment
Chenglin Li
Chenglin Li on 22 Jan 2024
Thank you very much! the previous error was because the mesh was not oriented in the same way and all the triangles did not wrap around in the same order, but I still had a small portion of the normals pointing inwards after the change.I'm working with a closed surface, how do I work with the surface instead of the geometry?

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!