[Bf-blender-cvs] [f0e23f93219] soc-2017-normal-tools: More rampaging cleanup & refactor in new clnor editmesh/transform code.

Bastien Montagne noreply at git.blender.org
Thu Nov 9 23:13:30 CET 2017


Commit: f0e23f9321904095654edd507393a6ac1fc20c6a
Author: Bastien Montagne
Date:   Thu Nov 9 22:34:51 2017 +0100
Branches: soc-2017-normal-tools
https://developer.blender.org/rBf0e23f9321904095654edd507393a6ac1fc20c6a

More rampaging cleanup & refactor in new clnor editmesh/transform code.

Also added loop_index to TransDataLoopNormal mapping, which allows us to
avoid another nasty loop-in-loop case.

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

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/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 59b00f6c4ea..47265e4d65f 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -281,6 +281,8 @@ typedef struct TransDataLoopNormal {
 
 typedef struct LoopNormalData {
 	TransDataLoopNormal *normal;
+	/* This one has full amount of loops, used to map loop index to actual TransDataLoopNormal struct. */
+	TransDataLoopNormal **loop_idx_to_transdata_lnors;
 
 	int offset;
 	int totloop;
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index ec817383cfe..7c178e4c7e5 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1087,9 +1087,7 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
 
 	int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
 
-	if (bm->elem_index_dirty & BM_LOOP) {
-		BM_mesh_elem_index_ensure(bm, BM_LOOP);
-	}
+	BM_mesh_elem_index_ensure(bm, BM_LOOP);
 
 	if (preserve_clnor) {
 		BLI_assert(bm->lnor_spacearr->lspacearr != NULL);
@@ -1199,14 +1197,15 @@ void BM_lnorspace_err(BMesh *bm)
 }
 
 /* Mark the individual clnors to be edited, if multiple selection methods are used. */
-static int BM_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
+static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
 {
 	BMEditSelection *ese, *vert;
 	int totloopsel = 0;
 
-	if (bm->elem_index_dirty & BM_LOOP) {
-		BM_mesh_elem_index_ensure(bm, BM_LOOP);
-	}
+	BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+	BLI_assert(bm->lnor_spacearr != NULL);
+	BLI_assert(bm->lnor_spacearr->flags & MLNOR_SPACEARR_BMLOOP_PTR);
 
 	/* Goes from last selected to the first selected element. */
 	for (ese = bm->selected.last; ese; ese = ese->prev) {
@@ -1240,14 +1239,15 @@ static int BM_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
 
 	for (int i = 0; i < bm->totloop; i++) {  /* Mark all loops in a loop normal space. */
 		if (BLI_BITMAP_TEST(loops, i)) {
-			LinkNode *node = bm->lnor_spacearr->lspacearr[i]->loops;
-			while (node) {
-				const int l_index = GET_INT_FROM_POINTER(node->link);
-				if (!BLI_BITMAP_TEST(loops, l_index)) {
-					BLI_BITMAP_ENABLE(loops, l_index);
-					totloopsel++;
+			if ((bm->lnor_spacearr->lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
+				LinkNode *node = bm->lnor_spacearr->lspacearr[i]->loops;
+				for (; node; node = node->next) {
+					const int l_index = BM_elem_index_get((BMLoop *)node->link);
+					if (!BLI_BITMAP_TEST(loops, l_index)) {
+						BLI_BITMAP_ENABLE(loops, l_index);
+						totloopsel++;
+					}
 				}
-				node = node->next;
 			}
 		}
 	}
@@ -1257,6 +1257,10 @@ static int BM_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
 
 LoopNormalData *BM_loop_normal_init(BMesh *bm)
 {
+	BMLoop *l;
+	BMVert *v;
+	BMIter liter, viter;
+
 	bool verts = (bm->selectmode & SCE_SELECT_VERTEX) != 0;
 	bool edges = (bm->selectmode & SCE_SELECT_EDGE) != 0;
 	bool faces = (bm->selectmode & SCE_SELECT_FACE) != 0;
@@ -1264,19 +1268,22 @@ LoopNormalData *BM_loop_normal_init(BMesh *bm)
 
 	BLI_assert(bm->spacearr_dirty == 0);
 
-	BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__);
-	if (verts + edges + faces > 1) {
-		/* More than one selection mode, check if only individual normals to edit. */
-		totloopsel = BM_loop_normal_mark_indiv(bm, loops);
-	}
 	LoopNormalData *ld = MEM_mallocN(sizeof(*ld), __func__);
+	ld->loop_idx_to_transdata_lnors = MEM_callocN(sizeof(*ld->loop_idx_to_transdata_lnors) * bm->totloop, __func__);
+
+	if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+		BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
+	}
 	int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
-	BMLoop *l;
-	BMVert *v;
-	BMIter liter, viter;
 
 	BM_mesh_elem_index_ensure(bm, BM_LOOP);
 
+	BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__);
+	if (verts + edges + faces > 1) {
+		/* More than one selection mode, check if only individual normals to edit. */
+		totloopsel = bm_loop_normal_mark_indiv(bm, loops);
+	}
+
 	if (totloopsel) {
 		TransDataLoopNormal *tld = ld->normal = MEM_mallocN(sizeof(*tld) * totloopsel, __func__);
 
@@ -1284,6 +1291,7 @@ LoopNormalData *BM_loop_normal_init(BMesh *bm)
 			BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
 				if (BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
 					InitTransDataNormal(bm, tld, v, l, cd_custom_normal_offset);
+					ld->loop_idx_to_transdata_lnors[BM_elem_index_get(l)] = tld;
 					tld++;
 				}
 			}
@@ -1298,6 +1306,7 @@ LoopNormalData *BM_loop_normal_init(BMesh *bm)
 			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);
+					ld->loop_idx_to_transdata_lnors[BM_elem_index_get(l)] = tld;
 					tld++;
 				}
 			}
@@ -1310,6 +1319,13 @@ LoopNormalData *BM_loop_normal_init(BMesh *bm)
 	return ld;
 }
 
+void BM_loop_normal_free(LoopNormalData *ld)
+{
+	MEM_SAFE_FREE(ld->normal);
+	MEM_SAFE_FREE(ld->loop_idx_to_transdata_lnors);
+	MEM_freeN(ld);
+}
+
 int BM_total_loop_select(BMesh *bm)
 {
 	int r_sel = 0;
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 5559669e4d2..722bf46bbfd 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -62,6 +62,7 @@ void BM_lnorspace_err(BMesh *bm);
 
 /* Loop Generics */
 LoopNormalData *BM_loop_normal_init(BMesh *bm);
+void BM_loop_normal_free(LoopNormalData *ld);
 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 5558f6dbc3a..ab79803a3bc 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -6040,11 +6040,12 @@ static void apply_point_normals(bContext *C, wmOperator *op, const wmEvent *UNUS
 static void point_normals_free(bContext *C, wmOperator *op, const bool align)
 {
 	LoopNormalData *ld = op->customdata;
+
 	if (align) {
+		/* FIXME WHAAAAAAAATTTTTTTT? When do you ever allocate that? --mont29 */
 		MEM_freeN(ld->normal->loc);
 	}
-	MEM_freeN(ld->normal);
-	MEM_freeN(ld);
+	BM_loop_normal_free(ld);
 	op->customdata = NULL;
 
 	ED_area_headerprint(CTX_wm_area(C), NULL);
@@ -6362,8 +6363,6 @@ static void edbm_point_normals_ui(bContext *C, wmOperator *op)
 
 void MESH_OT_point_normals(struct wmOperatorType *ot)
 {
-	PropertyRNA *prop;
-
 	/* identifiers */
 	ot->name = "Point normals to Target";
 	ot->description = "Point selected normals to specified Target";
@@ -6380,50 +6379,57 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
 	ot->flag = OPTYPE_BLOCKING | OPTYPE_REGISTER | OPTYPE_UNDO;
 
 	RNA_def_boolean(ot->srna, "point_away", false, "Point Away", "Point Away from target");
-	
+
 	RNA_def_boolean(ot->srna, "align", false, "Align", "Align normal with mouse location");
 
-	prop = RNA_def_property(ot->srna, "target_location", PROP_FLOAT, PROP_XYZ);
-	RNA_def_property_array(prop, 3);
-	RNA_def_property_ui_text(prop, "Target", "Target location where normals will point");
+	RNA_def_float_vector(ot->srna, "target_location", 3, (float[3]){0.0f, 0.0f, 0.0f}, -FLT_MAX, FLT_MAX,
+	                     "Target", "Target location to which normals will point", -1000.0f, 1000.0f);
 
-	RNA_def_boolean(ot->srna, "spherize", false, "Spherize Normal", "Add normal vector of target to custom normal with given proportion");
+	RNA_def_boolean(ot->srna, "spherize", false,
+	                "Spherize Normal", "Add normal vector of target to custom normal with given proportion");
 
-	RNA_def_float(ot->srna, "strength", 0.1, 0.0f, 1.0f, "Strength", "Ratio of spherized normal to original normal", 0.0f, 1.0f);
+	RNA_def_float(ot->srna, "strength", 0.1, 0.0f, 1.0f,
+	              "Strength", "Ratio of spherized normal to original normal", 0.0f, 1.0f);
 }
 
 /********************** Split/Merge Loop Normals **********************/
 
-static void custom_loops_tag(BMesh *bm)
+static void custom_loops_tag(BMesh *bm, const bool do_edges)
 {
 	BMFace *f;
 	BMEdge *e;
 	BMIter fiter, eiter;
 	BMLoop *l_curr, *l_first;
 
-	BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
-		BMLoop *l_a, *l_b;
+	if (do_edges) {
+		int index_edge;
+		BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) {
+			BMLoop *l_a, *l_b;
 
-		BM_elem_flag_disable(e, BM_ELEM_TAG);
-		if (BM_edge_loop_pair(e, &l_a, &l_b)) {
-			if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
-				BM_elem_flag_enable(e, BM_ELEM_TAG);
+			BM_elem_index_set(e, index_edge);  /* set_inline */
+			BM_elem_flag_disable(e, BM_ELEM_TAG);
+			if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+				if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
+					BM_elem_flag_enable(e, BM_ELEM_TAG);
+				}
 			}
 		}
+		bm->elem_index_dirty &= ~BM_EDGE;
 	}
 
 	int index_face, index_loop = 0;
 	BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) {
-		BM_elem_index_set(f, index_face);
+		BM_elem_index_set(f, index_face);  /* set_inline */
 		l_curr = l_first = BM_FACE_FIRST_LOOP(f);
 		do {
-			BM_elem_index_set(l_curr, index_loop++);
+			BM_elem_index_set(l_curr, index_loop++);  /* set_inline */
 			BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
 		} while ((l_curr = l_curr->next) != l_first);
 	}
+	bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
 }
 
-static bool merge_loop(bContext *C, wmOperator *UNUSED(op), LoopNormalData *ld)
+static void merge_loop(bContext *C, LoopNormalData *ld)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -6435,9 +6441,12 @@ static bool merge_loop(bContext *C, wmOperator *UNUSED(op), LoopNormalData *ld)
 
 	BLI_assert(bm->lnor_spacearr->flags & MLNOR_SPACEARR_BMLOOP_PTR);
 
+	custom_loops_tag(bm, false);
+
 	for (int i = 0; i < ld->totloop; i++, tld++) {
-		if (tld->loop_index == -1)
+		if (BM_elem_flag_test(tld->loop, BM_ELEM_TAG)) {
 			continue;
+		}
 
 		MLoopNorSpace *lnor_space = bm->lnor_spacearr->lspacearr[tld->loo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list