[Bf-blender-cvs] [448c61b8610] soc-2017-normal-tools: Added Split/Merge normals.

Rohan Rathi noreply at git.blender.org
Sat Jul 1 08:36:28 CEST 2017


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




More information about the Bf-blender-cvs mailing list