Commit: c1af648c33dd9d830bcbfd78540ae5e13e209e60
Author: Rohan Rathi
Date:   Thu Aug 3 19:21:35 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rBc1af648c33dd9d830bcbfd78540ae5e13e209e60

Fixed the following for weighted modifier:

1) Now correctly splits loop normal according to sharp edges
2) Modifier now only acts on active vertex group
3) Added a check to use smooth/sharp flags as boolean weights

===================================================================

M       release/scripts/startup/bl_ui/properties_data_modifier.py
M       source/blender/makesdna/DNA_modifier_types.h
M       source/blender/makesrna/intern/rna_modifier.c
M       source/blender/modifiers/intern/MOD_weighted_normal.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py 
b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 749d3efc58d..a2af2b5e43e 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1543,6 +1543,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         row.active = has_vgroup
         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
         layout.prop(md, "keep_sharp")
+        layout.prop(md, "boolean_weights")
 
 
 classes = (
diff --git a/source/blender/makesdna/DNA_modifier_types.h 
b/source/blender/makesdna/DNA_modifier_types.h
index 67ae41f0300..f4e6e3dbb82 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1633,6 +1633,7 @@ enum {
 enum {
        MOD_WEIGHTEDNORMAL_KEEP_SHARP = (1 << 0),
        MOD_WEIGHTEDNORMAL_INVERT_VGROUP = (1 << 1),
+       MOD_WEIGHTEDNORMAL_BOOL_WEIGHTS = (1 << 2),
 };
 
 #define MOD_MESHSEQ_READ_ALL \
diff --git a/source/blender/makesrna/intern/rna_modifier.c 
b/source/blender/makesrna/intern/rna_modifier.c
index a69809308c6..fd61b162659 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4806,6 +4806,11 @@ static void rna_def_modifier_weightednormal(BlenderRNA 
*brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 
MOD_WEIGHTEDNORMAL_INVERT_VGROUP);
        RNA_def_property_ui_text(prop, "Invert", "Invert vertex group 
influence");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop = RNA_def_property(srna, "boolean_weights", PROP_BOOLEAN, 
PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", 
MOD_WEIGHTEDNORMAL_BOOL_WEIGHTS);
+       RNA_def_property_ui_text(prop, "Boolean Weights", "Use Smooth/Sharp 
flags as boolean weights");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 void RNA_def_modifier(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c 
b/source/blender/modifiers/intern/MOD_weighted_normal.c
index d0fa31ee22c..15933a8038c 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -32,6 +32,8 @@
 #include "BKE_deform.h"
 #include "BKE_mesh.h"
 
+#include "BLI_bitmap.h"
+#include "BLI_linklist_stack.h"
 #include "BLI_math.h"
 
 #include "bmesh_class.h"
@@ -78,8 +80,9 @@ static void 
apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
                        for (; ml_index < ml_index_end; ml_index++) {
 
                                int mv_index = mloop[ml_index].v;
+                               const bool vert_of_group = has_vgroup && 
dvert[mv_index].dw != NULL && dvert[mv_index].dw->def_nr == defgrp_index;
 
-                               if ( ((dvert && dvert[mv_index].dw) ^ 
use_invert_vgroup) || !dvert/* && keep_sharp)*/) {
+                               if ( ((vert_of_group) ^ use_invert_vgroup) || 
!dvert) {
                                        float wnor[3];
 
                                        if (!cur_val[mv_index]) {               
        /* if cur_val is 0 init it to present value */
@@ -103,8 +106,9 @@ static void 
apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
                        float wnor[3];
                        int ml_index = mode_pair[i].index;
                        int mv_index = mloop[ml_index].v;
+                       const bool vert_of_group = has_vgroup && 
dvert[mv_index].dw != NULL && dvert[mv_index].dw->def_nr == defgrp_index;
 
-                       if (((dvert && dvert[mv_index].dw) ^ use_invert_vgroup) 
|| (!dvert && keep_sharp)) {
+                       if (((vert_of_group) ^ use_invert_vgroup) || !dvert) {
                                if (!cur_val[mv_index]) {
                                        cur_val[mv_index] = mode_pair[i].val;
                                }
@@ -133,36 +137,156 @@ static void 
apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
        }
        else {
                float(*loop_normal)[3] = MEM_callocN(sizeof(*loop_normal) * 
numLoops, "__func__");
+               int *loops_to_poly = MEM_mallocN(sizeof(*loops_to_poly) * 
numLoops, "__func__");
+               int numSharpVerts = 0;
+
+               BLI_bitmap *sharp_verts = BLI_BITMAP_NEW(numVerts, "__func__");
+               int *loops_per_vert = MEM_callocN(sizeof(*loops_per_vert) * 
numVerts, "__func__");
 
                for (int mp_index = 0; mp_index < numPoly; mp_index++) {
                        int ml_index = mpoly[mp_index].loopstart;
                        const int ml_index_end = ml_index + 
mpoly[mp_index].totloop;
 
                        for (int i = ml_index; i < ml_index_end; i++) {
+                               if ((medge[mloop[i].e].flag & ME_SHARP) && 
!BLI_BITMAP_TEST(sharp_verts, mloop[i].v)) {
+                                       numSharpVerts++;
+                                       BLI_BITMAP_ENABLE(sharp_verts, 
mloop[i].v);
+                               }
+                               loops_per_vert[mloop[i].v]++;
+                               loops_to_poly[i] = mp_index;
                                copy_v3_v3(loop_normal[i], 
custom_normal[mloop[i].v]);
                        }
                }
 
                if (keep_sharp) {
+                       void **loops_of_vert = 
MEM_mallocN(sizeof(loops_of_vert) * numSharpVerts, "__func__");
+                       int cur = 0;
+
                        for (int mp_index = 0; mp_index < numPoly; mp_index++) {
                                int ml_index = mpoly[mp_index].loopstart;
                                const int ml_index_end = ml_index + 
mpoly[mp_index].totloop;
 
-                               for (int i = ml_index; i < ml_index_end; i++) {
-                                       if (medge[mloop[i].e].flag & ME_SHARP) {
-                                               int other_v = 
BKE_mesh_edge_other_vert(&medge[mloop[i].e], mloop[i].v);
+                               for (int i = ml_index, k = 0; i < ml_index_end; 
i++) {
 
-                                               int other_loop_index = 
poly_find_loop_from_vert(&mpoly[mp_index], &mloop[ml_index], other_v);
-                                               if (other_loop_index != -1) {
-                                                       zero_v3(loop_normal[i]);
-                                                       
zero_v3(loop_normal[ml_index + other_loop_index]);
+                                       if (BLI_BITMAP_TEST(sharp_verts, 
mloop[i].v)) {
+
+                                               bool found = false;
+                                               for (k = 0; k < cur; k++) {
+                                                       int v_index = *(int 
*)loops_of_vert[k];
+                                                       if (mloop[i].v == 
v_index) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (found) {
+                                                       int *loops = 
loops_of_vert[k];
+                                                       while (*loops != -1) {
+                                                               loops++;
+                                                       }
+                                                       *loops = i;
+                                               }
+                                               else {
+                                                       int *loops;
+                                                       loops_of_vert[k] = 
loops = MEM_callocN(sizeof(*loops) * (loops_per_vert[mloop[i].v] + 1), 
"__func__");
+                                                       memset(loops, -1, 
sizeof(*loops) * (loops_per_vert[mloop[i].v] + 1));
+                                                       loops[0] = mloop[i].v;
+                                                       loops[1] = i;
+                                                       cur++;
+                                               }
+                                       }
+                               }
+                       }
+                       MEM_freeN(sharp_verts);
+                       for (int i = 0; i < numSharpVerts; i++) {
+                               int *loops = loops_of_vert[i];
+                               int totloop = loops_per_vert[*loops];
+                               loops++;
+                               int *base_loop = loops;
+
+                               BLI_SMALLSTACK_DECLARE(loop_nors, float *);
+
+                               float avg_normal[3] = { 0 }, min_normal[3] = { 
0 };
+                               int min = 0, stack = 0, sharp_edges = 0;
+                               bool check = (medge[mloop[*loops].e].flag & 
ME_SHARP) ? false : true;
+
+                               for (int k = 0; k < totloop; k++) {
+                                       MPoly mp = mpoly[loops_to_poly[*loops]];
+                                       MLoop *prev_loop = (*loops - 1 >= 
mp.loopstart ? &mloop[*loops - 1] : &mloop[mp.loopstart + mp.totloop - 1]),
+                                               *next_loop = (*loops + 1 <= 
mp.loopstart + mp.totloop ? &mloop[*loops + 1] : &mloop[mp.loopstart]),
+                                               *vert_loop;
+
+                                       int other_v1 = 
BKE_mesh_edge_other_vert(&medge[prev_loop->e], prev_loop->v),
+                                               other_v2 = 
BKE_mesh_edge_other_vert(&medge[next_loop->e], next_loop->v);
+
+                                       if (other_v1 == mloop[*loops].v) {
+                                               vert_loop = prev_loop;
+                                       }
+                                       else if (other_v2 == mloop[*loops].v) {
+                                               vert_loop = next_loop;
+                                       }
+                                       if (medge[mloop[*loops].e].flag & 
ME_SHARP) {
+                                               sharp_edges++;
+                                               check = false;
+                                       }
+                                       if (check) {
+                                               stack++;
+                                               BLI_SMALLSTACK_PUSH(loop_nors, 
loop_normal[*loops]);
+                                               add_v3_v3(min_normal, 
polynors[loops_to_poly[*loops]]);
+                                               min = stack;
+                                       }
+                                       else {
+                                               if 
((medge[mloop[*loops].e].flag & ME_SHARP)) {
+                                                       
normalize_v3(avg_normal);
+                                                       while (stack > min) {
+                                                               float *normal = 
BLI_SMALLSTACK_POP(loop_nors);
+                                                               
copy_v3_v3(normal, avg_normal);
+                                                               stack--;
+                                                       }
+                                                       zero_v3(avg_normal);
+                                               }
+                                               stack++;
+                                               BLI_SMALLSTACK_PUSH(loop_nors, 
loop_normal[*loops]);
+                                               add_v3_v3(avg_normal, 
polynors[loops_to_poly[*loops]]);
+                                       }
+                                       
+                                       for (int j = 0, *l_index = base_loop; j 
< totloop; j++, l_index++) {
+                                               if (loops == l_index || 
*l_index == -1)
+                                                       continue;
+                                               MPoly *mp = 
&mpoly[loops_to_poly[*l_index]];
+                                               bool has_poly = false;
+
+                                               for (int ml_index = 
mp->loopstart; ml_index < mp->loopstart + mp->totloop; ml_index++) {
+                                                       if (mloop[ml_index].e 
== vert_loop->e) {
+                                                               *loops = -1;
+                                                               loops = l_index;
+                                                               has_poly = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (has_poly) {
+                                                       break;
                                                }
                                        }
                                }
+                               if (!BLI_SMALLSTACK_IS_EMPTY(loop_nors)) {
+                                       float *normal;
+                                       add_v3_v3(avg_normal, min_normal);
+                                       normalize_v3(avg_normal);
+                                       while ((normal = 
BLI_SMALLSTACK_POP(loop_nors))) {
+                                               copy_v3_v3(normal, avg_normal);
+                                       }
+                               }
+                       }
+                       for (int i = 0; i < numSharpVerts; i++) {
+                               MEM_freeN(loops_of_vert[i]);
                        }
+                       MEM_freeN(loops_of_vert);
                }
                BKE_mesh_normals_loop_custom_set(mvert, numVerts, medge, 
numEdges,
                        mloop, loop_normal, numLoops, mpoly, polynors, numPoly, 
clnors);
+               MEM_freeN(loops_to_poly);
+               MEM_freeN(loop_normal);
+               MEM_freeN(loops_per_vert);
        }
                
        MEM_freeN(custom_normal);
@@ -176,10 +300,11 @@ static void WeightedNormal_FaceArea(
        int defgrp_index, const bool use_invert_vgroup, const float weight)
 {
        pair *face_area = MEM_mallocN(sizeof(*face_area) * numPoly, "__func__");
+       const bool bool_weights = (wnmd->flag & 
MOD_WEIGHTEDNORMAL_BOOL_WEIGHTS) != 0;
 
        for (int mp_index = 0; mp_index < numPoly; mp_index++) {
                face_area[mp_index].val = 
BKE_mesh_calc_poly_area(&mpoly[mp_index], &mloop[mpoly[mp_index].loopstart], 
mvert);
-               if (mpoly[mp_index].flag & ME_SMOOTH) {
+               if (bool_weights && (mpoly[mp_index].flag & ME_SMOOTH)) {
                        face_area[mp_index].val = 0;
                }
                face_area[mp_index].index = mp_index;
@@ -200,6 +325,7 @@ static void 
WeightedNormal_CornerAngle(WeightedNormalModifierData *wnmd, Object
 {
        pair *corner_angle = MEM_mallocN(sizeof(*corner_angle) * numLoops, 
"__func__");
        float *index_angle = MEM_mallocN(sizeof(*index_angle) * numLoops, 
"__func__");
+       const bool bool_weights = (wnmd->flag & 
MOD_WEIGHTEDNORMAL_BOOL_WEIGHTS) != 0;
        /* index_angle is first used to calculate corner angle and is then used 
to store poly index for each loop */
 
        for (int mp_index = 0; mp_index < numPoly; mp_index++) {
@@ -20

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to