[Bf-blender-cvs] [5c8a38a8588] soc-2017-normal-tools: Added ability to edit individual normal.

Rohan Rathi noreply at git.blender.org
Fri Jun 23 08:06:13 CEST 2017


Commit: 5c8a38a8588e6acf34ad175b580a2d007db6c95d
Author: Rohan Rathi
Date:   Fri Jun 23 11:35:45 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rB5c8a38a8588e6acf34ad175b580a2d007db6c95d

Added ability to edit individual normal.

Works by using multiple selection modes, so if yo
works by using multiple selection modes, so if you select vert then face. Th
Works by using multiple selection modes.
So, if you select vert then face, only clnor linked with
both vert and face will be edited.

Has some issues though, as vert + edge selection can
be associated to either of 2 clnors. Need to fix.

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/bmesh/bmesh_class.h
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/bmesh/intern/bmesh_mesh.h
M	source/blender/editors/mesh/editmesh_tools.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 2e291d3d471..86be68de043 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -435,6 +435,19 @@ class VIEW3D_PT_tools_shading(View3DPanel, Panel):
         col.operator("mesh.set_normals_from_faces", text="Set From Faces")
 
 
+class VIEW3D_PT_tools_normal(View3DPanel, Panel):
+	bl_category = "Shading / UVs"
+	bl_context = "mesh_edit"
+	bl_label = "Normal Tools"
+
+	def draw(self, context):
+		layout = self.layout
+
+		col = layout.column(align=True)
+		col.operator("transform.rotate_normal", text = "Rotate Normal")
+		col.operator("mesh.point_normals")
+
+
 class VIEW3D_PT_tools_uvs(View3DPanel, Panel):
     bl_category = "Shading / UVs"
     bl_context = "mesh_edit"
@@ -2020,6 +2033,7 @@ classes = (
     VIEW3D_PT_tools_meshweight,
     VIEW3D_PT_tools_add_mesh_edit,
     VIEW3D_PT_tools_shading,
+	VIEW3D_PT_tools_normal,
     VIEW3D_PT_tools_uvs,
     VIEW3D_PT_tools_meshedit_options,
     VIEW3D_PT_tools_transform_curve,
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index dcaceef8ac9..7c0e80d860f 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -373,7 +373,8 @@ enum {
 	 * not have functions clobber them */
 	BM_ELEM_INTERNAL_TAG = (1 << 7),
 
-	/* Space invalid when set */
+	/* Space invalid when set. This is also used to mark individual clnors for editing,
+		see BM_loop_normal_indiv()		*/
 	BM_ELEM_LNORSPACE = (1 << 6)
 };
 
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index f6c5e1d7b17..47105ffb601 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -30,6 +30,7 @@
 
 #include "DNA_listBase.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BLI_linklist_stack.h"
 #include "BLI_listbase.h"
@@ -1164,6 +1165,98 @@ static void BM_lnorspace_err(BMesh *bm)
 	bm->spacearr_dirty &= ~BM_SPACEARR_DIRTY_ALL;
 
 }
+/* Marks the individual clnors to be edited, if multiple selection methods are used */
+static int BM_loop_normal_indiv(BMesh *bm)
+{
+	BMEditSelection *ese, *vert;
+	int totloopsel = 0;
+
+	if (bm->elem_index_dirty & BM_LOOP) {
+		BM_mesh_elem_index_ensure(bm, BM_LOOP);
+	}
+
+	for (ese = bm->selected.last; ese; ese = ese->prev) {		/* Goes from last selected to the first selected element */
+		if (ese->htype == BM_FACE) {
+			vert = ese;
+			while ((vert = vert->prev)) {			/* If current face is selected, then any verts to be edited must have been selected before it */
+				if (vert->htype == BM_VERT) {
+
+					BMLoop *l = BM_face_vert_share_loop((BMFace *)ese->ele, (BMVert *)vert->ele);	
+					if (l) {						/* if vert and face selected share a loop, mark it for editing */
+						BM_elem_flag_enable(l, BM_ELEM_LNORSPACE);
+						totloopsel++;
+					}
+				}
+			}
+		}
+		else if (ese->htype == BM_EDGE) {
+			vert = ese;
+			while ((vert = vert->prev)) {
+				if (vert->htype == BM_VERT) {
+
+					if (BM_vert_in_edge((BMEdge *)ese->ele, (BMVert *)vert->ele)) {
+						BMLoop *l = BM_edge_vert_share_loop(((BMEdge *)ese->ele)->l, (BMVert *)vert->ele);
+						BM_elem_flag_enable(l, BM_ELEM_LNORSPACE);
+						totloopsel++;
+					}
+				}
+			}
+		}
+	}
+
+	return totloopsel;
+}
+
+LoopNormalData *BM_loop_normal_init(BMesh *bm)
+{
+	bool verts = bm->selectmode & SCE_SELECT_VERTEX,
+		edges = bm->selectmode & SCE_SELECT_EDGE,
+		faces = bm->selectmode & SCE_SELECT_FACE;
+	int totloopsel = 0;
+
+	if (verts + edges + faces > 1) {		/* More than 1 sel mode, check if only individual normals to edit */
+		totloopsel = BM_loop_normal_indiv(bm);
+	}
+	LoopNormalData *ld = MEM_mallocN(sizeof(*ld), "__func__");
+	int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+	BMLoop *l;
+	BMVert *v;
+	BMIter liter, viter;
+
+	if (totloopsel) {
+		TransDataLoopNormal *tld = ld->normal = MEM_mallocN(sizeof(*tld) * totloopsel, "__func__");
+
+		BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+			BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+				if (BM_elem_flag_test(l, BM_ELEM_LNORSPACE)) {
+
+					InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);
+					BM_elem_flag_disable(l, BM_ELEM_LNORSPACE);
+					tld++;
+				}
+			}
+		}
+		ld->totloop = totloopsel;
+	}
+	else {					/* if multiple selection modes are inactive OR no such loop is found, fall back to editing all loops*/
+		totloopsel = BM_total_loop_select(bm);
+		TransDataLoopNormal *tld = ld->normal = MEM_mallocN(sizeof(*tld) * totloopsel, "__func__");
+
+		BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+			if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+				BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+
+					InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);
+					tld++;
+				}
+			}
+		}
+		ld->totloop = totloopsel;
+	}
+
+	ld->offset = cd_custom_normal_offset;
+	return ld;
+}
 
 int BM_total_loop_select(BMesh *bm)
 {
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 499be9c0508..6a079d91144 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -59,6 +59,7 @@ void BM_lnorspace_update(BMesh *bm);
 static void BM_lnorspace_err(BMesh *bm);
 
 /* Loop Generics */
+LoopNormalData *BM_loop_normal_init(BMesh *bm);
 int BM_total_loop_select(BMesh *bm);
 void InitTransDataNormal(BMesh *bm, TransDataLoopNormal *tld, BMVert *v, BMLoop *l, int offset);
 
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 848cd16b8f3..9f439b3f598 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -5978,6 +5978,8 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
 	RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 }
 
+#endif
+
 /* Initialize loop normal data */
 static int init_point_normals(bContext *C, wmOperator *op, const wmEvent *event)
 {
@@ -5988,52 +5990,43 @@ static int init_point_normals(bContext *C, wmOperator *op, const wmEvent *event)
 	BMIter viter, liter;
 
 	BM_lnorspace_update(bm);
-	LoopNormalData *ld = MEM_mallocN(sizeof(LoopNormalData), "__func__");
+	LoopNormalData *ld;
 	int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
-	int totloopsel = 0;
 
 	PropertyRNA *prop = RNA_struct_find_property(op->ptr, "selected");
-	int length = RNA_property_array_length(op->ptr, prop);
-
-	int *vert_sel = MEM_mallocN(sizeof(*vert_sel) * length, "__func__");
-	RNA_int_get_array(op->ptr, "selected", vert_sel);				/* Get loop indices of previous selected vertices */
+	int totloopsel = RNA_property_array_length(op->ptr, prop);
 
 	/* This if statement is required as if we RMB on mesh then prev selected loop data is lost */
 
-	if (*vert_sel != -1) {											/* Means  function is called by exec() */
-		totloopsel = RNA_int_get(op->ptr, "loop_selected");
-		TransDataLoopNormal *tld = ld->normal = MEM_mallocN(sizeof(*tld) * totloopsel, "__func__");
-		int *vert_cur = vert_sel;
+	if (totloopsel) {	
 
-		for (int i = 0; i < length; i++, vert_cur++) {
-			v = BM_vert_at_index_find_or_table(bm, *vert_cur);
+		int *loop_sel = MEM_mallocN(sizeof(*loop_sel) * totloopsel, "__func__");
+
+		RNA_int_get_array(op->ptr, "selected", loop_sel);				/* Get loop indices of previous selected vertices */
+		ld = MEM_mallocN(sizeof(LoopNormalData), "__func__");
 
-			BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
-				InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);		/* Init those loop normals used in previous call */
-				tld++;
-			}
-		}
-	}
-	else {
-		totloopsel = BM_total_loop_select(bm);		/* Invoke operation */
 		TransDataLoopNormal *tld = ld->normal = MEM_mallocN(sizeof(*tld) * totloopsel, "__func__");
-		BM_mesh_elem_index_ensure(bm, BM_LOOP);
+		int *loop_cur = loop_sel;
 
-		BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
-			if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
-				BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+		for (int i = 0; i < totloopsel; i++, loop_cur++) {
 
-					InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);
-					tld++;
+			BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+				BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+					if (*loop_cur == BM_elem_index_get(l)) {
+						InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);		/* Init those loop normals used in previous call */
+						tld++;
+					}
 				}
 			}
 		}
+		ld->totloop = totloopsel;
+		MEM_freeN(loop_sel);
+	}
+	else {
+		ld = BM_loop_normal_init(bm);
+		totloopsel = ld->totloop;
 	}
 
-	MEM_freeN(vert_sel);
-
-	ld->totloop = totloopsel;
-	ld->offset = cd_custom_normal_offset;
 	ld->funcdata = NULL;
 	op->customdata = ld;
 
@@ -6165,7 +6158,7 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
 	PropertyRNA *prop = RNA_struct_find_property(op->ptr, "target_location");
 	LoopNormalData *ld = op->customdata;
 
-	if (ld->funcdata) {				/* executes point_normals_mouse */
+	if (ld->funcdata) {				/* executes and transfers control to point_normals_mouse */
 		int(*apply)(bContext *, wmOperator *, const wmEvent *);
 		apply = ld->funcdata;
 		return apply(C, op, event);
@@ -6176,7 +6169,6 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
 		if (ele_ref == ele_new) {
 			ele_ref = NULL;
 			point_normals_free(C, op, false);
-			ED_area_headerprint(CTX_wm_area(C), NULL);
 
 			return OPERATOR_CANCELLED;
 		}
@@ -6195,22 +6187,26 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
 		if (event->type == LEFTMOUSE) {
 			ED_view3d_cursor3d_update(C, event->mval);
 			copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d));
+			sub_v3_v3(target, obedit->loc);
 			RNA_property_float_set_array(op->ptr, prop, target);
 
 			handled = true;
 		}
 		if (event->type == RIGHTMOUSE) {
 			ele_ref = BM_mesh_active_elem_get(bm);
-			int *vert_sel = MEM_mallocN(sizeof(*vert_sel) * bm->totvertsel, "__func__"), index;
+			if (!ele_ref) {
+				

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list