File Exchange

## Compute STL Vertex Normals

version 1.0.0.0 (1.73 KB) by Francis Esmonde-White

### Francis Esmonde-White (view profile)

Find the per-vertex normals for a tesselated surface.

Updated 11 Oct 2011

The default normal vectors associated with tesselated surfaces are computed for each triangle face. Some purposes (like nice rendering) require per-vertex normals instead. These are typically calculated by averaging the face normals. This function offers two methods, first, an average normal weighted by triangle area, and second the normal as an average of the surrounding triangle faces. The second option is faster (because it uses the pre-computed unit-normals), but the first method generates nicer surface-normals, particularly at regions with sharp edges or small triangles.

This should do essentially the same thing as Dirk-Jan Kroon's 'Patch Normals' submission #24330, and my code is probably slower because it is not compiled. However, it's a bit simpler to read and (hopefully) to use.

### Cite As

Francis Esmonde-White (2020). Compute STL Vertex Normals (https://www.mathworks.com/matlabcentral/fileexchange/33226-compute-stl-vertex-normals), MATLAB Central File Exchange. Retrieved .

Han Chen

### Han Chen (view profile)

The correct vertex normal should be angle weighted normal, i.e. average of unit normals in each face weighted by the angle made by the two edges (with the same vertex).

Matthew Sheen

### Matthew Sheen (view profile)

There is a condition where this produces the wrong result. If the same vertex index appears more than once in a column of the face matrix, then only the first face normal is added to that index. To illustrate, if we have: `a = 1:5; a([1,1]) = a([1,1]) + [5,5];` then index 1 of `a` will only be incremented by 5, not 10. This could be fixed by replacing the three `vn(f(:,1),:)` lines with: `vn = accumarray([f(:),ones(size(f(:)));f(:),2*ones(size(f(:))); f(:),3*ones(size(f(:)))], [repmat(fn(:,1),[3,1]);repmat(fn(:,2),[3,1]);repmat(fn(:,3),[3,1])]);` I'm sure there is a much easier way to do this, but I was trying to avoid a loop.

Mohsin Shah

### Mohsin Shah (view profile)

Francesco Buonamici

### Francesco Buonamici (view profile)

##### MATLAB Release Compatibility
Created with R2011b
Compatible with any release
##### Platform Compatibility
Windows macOS Linux