New method:
![](https://cdn.statically.io/img/i.sstatic.net/fzNOnMS6.png)
Explanation:
(A) – For each vertex, get two edges that are boundaries (they are the ones relevant for calculating the offset), then remember the index of these two edges, and also get the index of the opposite vertex for the edge.
(B) – To resolve uncertainties in (C) step, it is important to obtain an unambiguous definition of the "outward" direction.
Use the Faces normal to define the direction for edge, and then use the direction from the center of the edge to face to ensure the direction of the edge is "out."
(C) – For each vertex, obtain the average direction from its two edges.
There are two problems with this:
1. The average direction is always between a short angle, which can be directed "inward" of the surface. To fix this, reflect the direction using the additional information from (B).
2. The edges of a vertex can be parallel. For each vertex for which this is true, use the "out" direction from (B) instead of the mean direction.
Now for each vertex there is a correct direction to offset.
(D) – To be able to offset on non-planar faces, you need to get the angle information between the faces for the vertex for the (E) step.
Using the vertex edge index, read the face normal through it, then dot product. If the normals are parallel and pointing in opposite directions, force rewrite to one.
There is a problem with this if the normals have different directions
(see gif 1).
To fix this, use the average position of the two faces to reverse the sign for cases where the normals are point in different directions.
(E) – Using cosine of angle (dot product) between edges for a vertex, calculate the "factor" of distance the vertex must travel for the offset to be "uniform".
There is one problem with this: for non-planar faces, the angle between the edges for the vertex will not correspond to reality (see gif 2).
To fix this, multiply the distance factor by the similarly adjusted cosine of (D).
Now for each vertex there is a correct distance for offset.
(F) – Vertices "inside" the surface were processed as is. Since they are not relevant for the offset, just ignore them, and move all other vertices on the final offset.
gif 1:
![](https://cdn.statically.io/img/i.sstatic.net/GA8Z13QE.gif)
gif 2:
![](https://cdn.statically.io/img/i.sstatic.net/g0j3QoIz.gif)
![](https://cdn.statically.io/img/blend-exchange.com/embedImage.png?bid=R0NYzOaa)