Commit: 448c61b8610b7ae4d9056411762cc21afafe1667
Author: Rohan Rathi
Date:   Sat Jul 1 12:03:08 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rB448c61b8610b7ae4d9056411762cc21afafe1667

Added Split/Merge normals.

Doesn't work on the basis of any weighting mode. Will have to implement that 
first. I'll add more methods as I progress in other areas.

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

M       release/scripts/startup/bl_ui/space_view3d_toolbar.py
M       source/blender/bmesh/intern/bmesh_mesh.c
M       source/blender/bmesh/intern/bmesh_opdefines.c
M       source/blender/editors/mesh/editmesh_tools.c
M       source/blender/editors/mesh/mesh_intern.h
M       source/blender/editors/mesh/mesh_ops.c
M       source/blender/editors/transform/transform.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py 
b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 86be68de043..177c558f5c5 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -447,6 +447,12 @@ class VIEW3D_PT_tools_normal(View3DPanel, Panel):
                col.operator("transform.rotate_normal", text = "Rotate Normal")
                col.operator("mesh.point_normals")
 
+               col = layout.column(align=True)
+               col.label(text="Split/Merge: ")
+
+               col.operator_menu_enum("mesh.merge_loop_normals", "merge_type")
+               col.operator_menu_enum("mesh.split_loop_normals", "split_type")
+
 
 class VIEW3D_PT_tools_uvs(View3DPanel, Panel):
     bl_category = "Shading / UVs"
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c 
b/source/blender/bmesh/intern/bmesh_mesh.c
index 47105ffb601..e2d584a517f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -814,7 +814,12 @@ static void bm_mesh_loops_calc_normals(
 
                                        if (r_lnors_spacearr) {
                                                /* Assign current lnor space to 
current 'vertex' loop. */
-                                               
BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true);
+
+                                               /* weak fix, need to look out 
if breaks something. Without this 'if', wrongly builds the lnor spaces
+                                                  if loops are merged. */
+                                               if (!rebuild || 
!BM_elem_flag_test(lfan_pivot->v, BM_ELEM_TAG) || (bm->spacearr_dirty & 
BM_SPACEARR_DIRTY_ALL)) {
+                                                       
BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true);
+                                               }
                                                if (e_next != e_org) {
                                                        /* We store here all 
edges-normalized vectors processed. */
                                                        
BLI_stack_push(edge_vectors, vec_next);
@@ -853,7 +858,10 @@ static void bm_mesh_loops_calc_normals(
                                                                clnors_avg[0] 
/= clnors_nbr;
                                                                clnors_avg[1] 
/= clnors_nbr;
                                                                /* Fix/update 
all clnors of this fan with computed average value. */
-                                                               printf("Invalid 
clnors in this fan!\n");
+                                                               
+                                                               /* Prints 
continuously when merge custom normals, so commenting -Rohan
+                                                               printf("Invalid 
clnors in this fan!\n");*/
+
                                                                while ((clnor = 
BLI_SMALLSTACK_POP(clnors))) {
                                                                        
//print_v2("org clnor", clnor);
                                                                        
clnor[0] = (short)clnors_avg[0];
@@ -1073,6 +1081,7 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
                        }
                }
        }
+
        BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, r_lnors, 
bm->lnor_spacearr, NULL, cd_loop_clnors_offset, true);
        MEM_freeN(r_lnors);
 
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c 
b/source/blender/bmesh/intern/bmesh_opdefines.c
index c4e0511bf26..1b8879e27ee 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -208,8 +208,7 @@ static BMOpDefine bmo_region_extend_def = {
        },
        bmo_region_extend_exec,
        (BMO_OPTYPE_FLAG_SELECT_FLUSH |
-        BMO_OPTYPE_FLAG_SELECT_VALIDATE |
-        BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL),
+        BMO_OPTYPE_FLAG_SELECT_VALIDATE),
 };
 
 /*
diff --git a/source/blender/editors/mesh/editmesh_tools.c 
b/source/blender/editors/mesh/editmesh_tools.c
index 9f439b3f598..de9085effdf 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -42,6 +42,8 @@
 #include "DNA_scene_types.h"
 
 #include "BLI_listbase.h"
+#include "BLI_linklist.h"
+#include "BLI_linklist_stack.h"
 #include "BLI_noise.h"
 #include "BLI_math.h"
 #include "BLI_rand.h"
@@ -6442,4 +6444,204 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
 
        prop = RNA_def_property(ot->srna, "selected", PROP_INT, PROP_NONE);
        RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+
+/********************** Split/Merge Loop Normals **********************/
+
+enum {
+       MERGE_LOOP_AVERAGE = 1,
+       SPLIT_LOOP_TO_FACE = 2,
+       SPLIT_LOOP_KEEP = 3
+};
+
+static EnumPropertyItem merge_loop_method_items[] = {
+       { MERGE_LOOP_AVERAGE, "Average", 0, "Average", "Take Average of Loop 
Normals" },
+       { 0, NULL, 0, NULL, NULL }
+};
+
+static EnumPropertyItem split_loop_method_items[] = {
+       { SPLIT_LOOP_TO_FACE, "Set to face", 0, "Set to face", "Set loop normal 
to respective faces" },
+       { SPLIT_LOOP_KEEP, "Keep Normal", 0, "Keep Normal", "Keep normal value 
after splitting" },
+       { 0, NULL, 0, NULL, NULL }
+};
+
+static bool merge_loop_average(bContext *C, wmOperator *op, LoopNormalData *ld)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = BKE_editmesh_from_object(obedit);
+       BMesh *bm = em->bm;
+
+       TransDataLoopNormal *tld = ld->normal;
+
+       for (int i = 0; i < ld->totloop; i++, tld++) {
+               MLoopNorSpace *lnor_space = 
bm->lnor_spacearr->lspacearr[tld->loop_index];
+
+               if (lnor_space->loops) {
+
+                       LinkNode *loops = lnor_space->loops;
+                       float avg_normal[3] = { 0, 0, 0 };
+                       BLI_SMALLSTACK_DECLARE(clnors, short *);
+                       short *clnors_data;
+
+                       while (loops) {
+                               const int loop_index = 
GET_INT_FROM_POINTER(loops->link);
+
+                               TransDataLoopNormal *temp = ld->normal;
+                               for (int j = 0; j < ld->totloop; j++, temp++) {
+                                       if (loop_index == temp->loop_index) {
+                                               add_v3_v3(avg_normal, 
temp->nloc);
+                                               BLI_SMALLSTACK_PUSH(clnors, 
tld->clnors_data);
+                                       }
+                               }
+                               loops = loops->next;
+                       }
+                       if (len_squared_v3(avg_normal) < 1e-4f) {               
/* if avg normal is nearly 0, set clnor to default value */
+                               while ((clnors_data = 
BLI_SMALLSTACK_POP(clnors))) {
+                                       copy_v2_v2_short(clnors_data, 
(short[2]) { 0, 0 });
+                               }
+                       }
+                       else {
+                               normalize_v3(avg_normal);                       
                /* else set all clnors to this avg */
+                               while ((clnors_data = 
BLI_SMALLSTACK_POP(clnors))) {
+                                       
BKE_lnor_space_custom_normal_to_data(lnor_space, avg_normal, clnors_data);
+                                       printf("hi");
+                               }
+                       }
+               }
+       }
+       return true;
+}
+
+static bool split_loop(bContext *C, wmOperator *op, LoopNormalData *ld)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = BKE_editmesh_from_object(obedit);
+       BMesh *bm = em->bm;
+       BMFace *f;
+       BMLoop *l;
+       BMIter fiter, liter;
+
+       TransDataLoopNormal *tld = ld->normal;
+
+       const int type = RNA_enum_get(op->ptr, "split_type");
+
+       for (int i = 0; i < ld->totloop; i++, tld++) {
+               if (type == SPLIT_LOOP_TO_FACE) {                               
                /* set loop to face normal if split to faces */
+                       BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+                               if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+                                       BM_ITER_ELEM(l, &liter, f, 
BM_LOOPS_OF_FACE) {
+                                               if (tld->loop_index == 
BM_elem_index_get(l)) {
+                                                       
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[tld->loop_index],
 f->no, tld->clnors_data);
+                                               }
+                                       }
+                               }
+                       }
+               }
+               else if (type == SPLIT_LOOP_KEEP) {                             
                /* else set to transdata normal computed */
+                       
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[tld->loop_index],
 tld->nloc, tld->clnors_data);
+                       printf("hi");
+               }
+       }
+       return true;
+}
+
+static int edbm_split_merge_loop_normals_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = BKE_editmesh_from_object(obedit);
+       BMesh *bm = em->bm;
+       BMEdge *e;
+       BMIter eiter;
+
+       if ((((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH) == 0) {
+               return OPERATOR_CANCELLED;
+       }
+
+       BM_lnorspace_update(bm);
+       LoopNormalData *ld = BM_loop_normal_init(bm);
+
+       const bool merge = RNA_struct_find_property(op->ptr, "merge_type") != 
NULL;
+       const int type = merge ? RNA_enum_get(op->ptr, "merge_type") : 
RNA_enum_get(op->ptr, "split_type");
+
+       mesh_set_smooth_faces(em, merge);
+
+       BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
+               if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+                       BM_elem_flag_set(e, BM_ELEM_SMOOTH, merge);
+               }
+       }
+
+       bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+       BM_lnorspace_update(bm);
+
+       bool handled = false;
+       
+       if (merge) {
+               switch (type) {
+                       case MERGE_LOOP_AVERAGE:
+                               handled = merge_loop_average(C, op, ld);
+                               break;
+
+                       default:
+                               BLI_assert(0);
+                               break;
+               }
+       }
+       else {
+               switch (type) {
+                       case SPLIT_LOOP_TO_FACE:
+                               handled = split_loop(C, op, ld);
+                               break;
+
+                       case SPLIT_LOOP_KEEP:
+                               handled = split_loop(C, op, ld);
+                               break;
+
+                       default:
+                               BLI_assert(0);
+                               break;
+               }
+       }
+       if (!handled) {
+               return OPERATOR_CANCELLED;
+       }
+
+       BKE_reportf(op->reports, RPT_INFO, "Finished");
+       EDBM_update_generic(em, true, false);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_merge_loop_normals(struct wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Merge Loop";
+       ot->description = "Merge loop normals of selected vertices";
+       ot->idname = "MESH_OT_merge_loop_normals";
+
+       /* api callbacks */
+       ot->exec = edbm_split_merge_loop_normals_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       ot->prop = RNA_def_enum(ot->srna, "merge_type", 
merge_loop_method_items, MERGE_LOOP_AVERAGE, "Type", "Merge method");
+}
+
+void MESH_OT_split_loop_normals(struct wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Split Loop";
+       ot->description = "Split loop normals of selected vertices";
+       ot->idname = "MESH_OT_split_loop_normals";
+
+       /* api callbacks */
+       ot->exec = edbm_split_merge_loop_normals_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       ot->prop = RNA_def_enum(ot->srna, "split_type", 
split_loop_method_items, SPLIT_LOOP_TO_FACE, "Type", "Split method");
 }
\ No newline at end of file
diff --git a/source/blender/editors/mesh/mesh_intern.h 
b/source/blender/editors/mesh/mesh_intern.h
index 5a141f29607..fbad0a5d5f1 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -230,6 +230,8 @@ void MESH_OT_merge(struct wmOperatorType *ot);
 void MESH_OT_remove_doubles(struct wmOperatorType *ot);
 void MESH_OT_poke(struct wmOperatorType *ot);
 void MESH_OT_point_normals(struct wmOperatorType *ot);
+void MESH_OT_merge_loop_normals(struct wmOperatorType *ot);
+void MESH_OT_split_loop_normals(struct wmOperatorType *ot);
 
 #ifdef WITH_FREESTYLE
 void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c 
b/source/blender/editors/mesh/mesh_ops.c
index 6ed2453c86e..66a39b30594 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/sourc

@@ 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