[Bf-blender-cvs] [ab32900] master: Refactor 'apply' part of Editmode View3d Transform panel code.

Bastien Montagne noreply at git.blender.org
Wed Oct 15 08:59:27 CEST 2014


Commit: ab3290048c85e6dda28bd048d6815e2e9b52f6a2
Author: Bastien Montagne
Date:   Tue Oct 14 23:35:28 2014 +0200
Branches: master
https://developer.blender.org/rBab3290048c85e6dda28bd048d6815e2e9b52f6a2

Refactor 'apply' part of Editmode View3d Transform panel code.

This was way too verbose, heavily factorized the code.

Also made sure only changed data are applied (was not always the case,
especially for curves and lattices), and that we always use raw value
when only one element is affected (was only that way for coordinates).

Note I checked performances, they seem to be roughly the same as previously.

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

M	source/blender/editors/space_view3d/view3d_buttons.c

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

diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 91b60a0..6a43357 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -124,6 +124,50 @@ static float compute_scale_factor(const float ve_median, const float median)
 	}
 }
 
+/* Apply helpers.
+ * Note: In case we only have one element, copy directly the value instead of applying the diff or scale factor.
+ *       Avoids some glitches when going e.g. from 3 to 0.0001 (see T37327).
+ */
+static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median)
+{
+	*val = (tot == 1) ? ve_median : (*val + median);
+}
+
+static void apply_raw_diff_v3(float val[3], const int tot, const float ve_median[3], const float median[3])
+{
+	if (tot == 1) {
+		copy_v3_v3(val, ve_median);
+	}
+	else {
+		add_v3_v3(val, median);
+	}
+}
+
+static void apply_scale_factor(float *val, const int tot, const float ve_median, const float median, const float sca)
+{
+	if (tot == 1 || ve_median == median) {
+		*val = ve_median;
+	}
+	else {
+		*val *= sca;
+	}
+}
+
+static void apply_scale_factor_clamp(float *val, const int tot, const float ve_median, const float sca)
+{
+	if (tot == 1) {
+		*val = ve_median;
+		CLAMP(*val, 0.0f, 1.0f);
+	}
+	else if (ELEM(sca, 0.0f, 1.0f)) {
+		*val = sca;
+	}
+	else {
+		*val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca));
+		CLAMP(*val, 0.0f, 1.0f);
+	}
+}
+
 /* is used for both read and write... */
 static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
 {
@@ -473,6 +517,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 	}
 	else { /* apply */
 		int i;
+		bool apply_vcos;
 
 		memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
 
@@ -485,191 +530,130 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 		while (i--)
 			median[i] = ve_median[i] - median[i];
 
-		if (ob->type == OB_MESH) {
+		/* Note with a single element selected, we always do. */
+		apply_vcos = (tot == 1) || (len_squared_v3(&median[LOC_X]) != 0.0f);
+
+		if ((ob->type == OB_MESH) &&
+		    (apply_vcos || median[M_BV_WEIGHT] || median[M_SKIN_X] || median[M_SKIN_Y] ||
+		     median[M_BE_WEIGHT] || median[M_CREASE]))
+		{
 			Mesh *me = ob->data;
 			BMEditMesh *em = me->edit_btmesh;
 			BMesh *bm = em->bm;
 			BMIter iter;
+			BMVert *eve;
+			BMEdge *eed;
 
-			if (tot == 1 || len_v3(&median[LOC_X]) != 0.0f) {
-				BMVert *eve;
+			int cd_vert_bweight_offset = -1;
+			int cd_vert_skin_offset = -1;
+			int cd_edge_bweight_offset = -1;
+			int cd_edge_crease_offset = -1;
 
-				BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-					if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-						if (tot == 1) {
-							/* In case we only have one element selected, copy directly the value instead of applying
-							 * the diff. Avoids some glitches when going e.g. from 3 to 0.0001 (see [#37327]).
-							 */
-							copy_v3_v3(eve->co, &ve_median[LOC_X]);
-						}
-						else {
-							add_v3_v3(eve->co, &median[LOC_X]);
-						}
-					}
-				}
+			float scale_bv_weight = 1.0f;
+			float scale_skin_x = 1.0f;
+			float scale_skin_y = 1.0f;
+			float scale_be_weight = 1.0f;
+			float scale_crease = 1.0f;
 
-				EDBM_mesh_normals_update(em);
-			}
+			/* Vertices */
 
-			if (median[M_BV_WEIGHT] != 0.0f) {
-				const int cd_vert_bweight_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT),
-				                                    CustomData_get_offset(&bm->vdata, CD_BWEIGHT));
-				const float sca = compute_scale_factor(ve_median[M_BV_WEIGHT], median[M_BV_WEIGHT]);
-				BMVert *eve;
+			if (apply_vcos || median[M_BV_WEIGHT] || median[M_SKIN_X] || median[M_SKIN_Y]) {
+				if (median[M_BV_WEIGHT]) {
+					BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
+					cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+					BLI_assert(cd_vert_bweight_offset != -1);
 
-				BLI_assert(cd_vert_bweight_offset != -1);
+					scale_bv_weight = compute_scale_factor(ve_median[M_BV_WEIGHT], median[M_BV_WEIGHT]);
+				}
 
-				if (ELEM(sca, 0.0f, 1.0f)) {
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
-							*bweight = sca;
-						}
+				if (median[M_SKIN_X]) {
+					cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+					BLI_assert(cd_vert_skin_offset != -1);
+
+					if (ve_median[M_SKIN_X] != median[M_SKIN_X]) {
+						scale_skin_x = ve_median[M_SKIN_X] / (ve_median[M_SKIN_X] - median[M_SKIN_X]);
 					}
 				}
-				else if (sca > 0.0f) {
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
-							*bweight *= sca;
-							CLAMP(*bweight, 0.0f, 1.0f);
-						}
+				if (median[M_SKIN_Y]) {
+					if (cd_vert_skin_offset == -1) {
+						cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+						BLI_assert(cd_vert_skin_offset != -1);
 					}
-				}
-				else {
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
-							*bweight = 1.0f + ((1.0f - *bweight) * sca);
-							CLAMP(*bweight, 0.0f, 1.0f);
-						}
+
+					if (ve_median[M_SKIN_Y] != median[M_SKIN_Y]) {
+						scale_skin_y = ve_median[M_SKIN_Y] / (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
 					}
 				}
-			}
-
-			if (median[M_SKIN_X] != 0.0f) {
-				const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
-				/* That one is not clamped to [0.0, 1.0]. */
-				float sca = ve_median[M_SKIN_X];
-				BMVert *eve;
 
-				BLI_assert(cd_vert_skin_offset != -1);
+				BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+					if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+						if (apply_vcos) {
+							apply_raw_diff_v3(eve->co, tot, &ve_median[LOC_X], &median[LOC_X]);
+						}
 
-				if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) {
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
-							vs->radius[0] = sca;
+						if (cd_vert_bweight_offset != -1) {
+							float *bweight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
+							apply_scale_factor_clamp(bweight, tot, ve_median[M_BV_WEIGHT], scale_bv_weight);
 						}
-					}
-				}
-				else {
-					sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]);
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+
+						if (cd_vert_skin_offset != -1) {
 							MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
-							vs->radius[0] *= sca;
+
+							/* That one is not clamped to [0.0, 1.0]. */
+							if (median[M_SKIN_X] != 0.0f) {
+								apply_scale_factor(&vs->radius[0], tot, ve_median[M_SKIN_X], median[M_SKIN_X],
+								                   scale_skin_x);
+							}
+							if (median[M_SKIN_Y] != 0.0f) {
+								apply_scale_factor(&vs->radius[1], tot, ve_median[M_SKIN_Y], median[M_SKIN_Y],
+								                   scale_skin_y);
+							}
 						}
 					}
 				}
 			}
-			if (median[M_SKIN_Y] != 0.0f) {
-				const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
-				/* That one is not clamped to [0.0, 1.0]. */
-				float sca = ve_median[M_SKIN_Y];
-				BMVert *eve;
-
-				BLI_assert(cd_vert_skin_offset != -1);
 
-				if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) {
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
-							vs->radius[1] = sca;
-						}
-					}
-				}
-				else {
-					sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
-					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
-							MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
-							vs->radius[1] *= sca;
-						}
-					}
-				}
+			if (apply_vcos) {
+				EDBM_mesh_normals_update(em);
 			}
 
-			if (median[M_BE_WEIGHT] != 0.0f) {
-				const int cd_edge_bweight_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT),
-				                                    CustomData_get_offset(&bm->edata, CD_BWEIGHT));
-				const float sca = compute_scale_factor(ve_median[M_BE_WEIGHT], median[M_BE_WEIGHT]);
-				BMEdge *eed;
+			/* Edges */
 
-				BLI_assert(cd_edge_bweight_offset != -1);
+			if (median[M_BE_WEIGHT] || median[M_CREASE]) {
+				if (median[M_BE_WEIGHT]) {
+					BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
+					cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+					BLI_assert(cd_edge_bweight_offset != -1);
 
-				if (ELEM(sca, 0.0f, 1.0f)) {
-					BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
-						if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
-							*bweight = sca;
-						}
-					}
-				}
-				else if (sca > 0.0f) {
-					BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
-						if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
-							*bweight *= sca;
-							CLAMP(*bweight, 0.0f, 1.0f);
-						}
-					}
-				}
-				else {
-					BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
-						if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
-							float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
-							*bweight = 1.0f + ((1.0f - *bweight) * sca);
-							CLAMP(*bweight, 0.0f, 1.0f);
-						}
-					}
+					scale_be_weight = compute_scale_factor(ve_median[M_BE_WEIGHT], median[M_BE_WEIGHT]);
 				}
-			}
 
-			if (median[M_CREASE] != 0.0f) {
-				const int cd_edge_crease_offset  = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE),
-				       

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list