Shrinkwrap: use polygon normals for flat faces in Align To Normal.
authorAlexander Gavrilov <angavrilov@gmail.com>
Wed, 5 Dec 2018 17:24:05 +0000 (20:24 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Sat, 8 Dec 2018 05:27:37 +0000 (08:27 +0300)
Hit normal originates from tesselated triangles and isn't the
actual normal used for shading of flat faces. Thus, it is better
to use the actual polygon normals when available.

source/blender/blenkernel/BKE_shrinkwrap.h
source/blender/blenkernel/intern/shrinkwrap.c

index d703e8819d707665d38c8e9eaf4cdba87a1fe595..0959e8a72f02ac9ac571ba89b9884e45000e8f66 100644 (file)
@@ -90,6 +90,7 @@ typedef struct ShrinkwrapTreeData {
        BVHTree *bvh;
        BVHTreeFromMesh treeData;
 
+       float (*pnors)[3];
        float (*clnors)[3];
        ShrinkwrapBoundaryData *boundary;
 } ShrinkwrapTreeData;
index ee35876f2a3dce8aed258d485590172aa3eb0642..06e5cc9e8494075ff17768c841cefe3f573c3030 100644 (file)
@@ -144,6 +144,7 @@ bool BKE_shrinkwrap_init_tree(ShrinkwrapTreeData *data, Mesh *mesh, int shrinkTy
                }
 
                if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
+                       data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
                        if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
                                data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
                        }
@@ -1164,7 +1165,11 @@ void BKE_shrinkwrap_compute_smooth_normal(
                        normalize_v3(r_no);
                }
        }
-       /* Use the looptri normal if flat. */
+       /* Use the polygon normal if flat. */
+       else if (tree->pnors != NULL) {
+               copy_v3_v3(r_no, tree->pnors[tri->poly]);
+       }
+       /* Finally fallback to the looptri normal. */
        else {
                copy_v3_v3(r_no, hit_no);
        }