[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45353] trunk/blender: fix for vertex group blend - wasn' t functional since the deform verts were being tken from a NULL array,

Campbell Barton ideasman42 at gmail.com
Tue Apr 3 04:16:37 CEST 2012


Revision: 45353
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45353
Author:   campbellbarton
Date:     2012-04-03 02:16:27 +0000 (Tue, 03 Apr 2012)
Log Message:
-----------
fix for vertex group blend - wasn't functional since the deform verts were being tken from a NULL array,

also made some other improvements
- make it work in weight paint vert sel mode (some unused code for this was in the function).
- add factor slider.
- add to weight paint toolbar.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
    trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
    trunk/blender/source/blender/editors/object/object_vgroup.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2012-04-03 00:28:38 UTC (rev 45352)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2012-04-03 02:16:27 UTC (rev 45353)
@@ -1188,6 +1188,7 @@
         layout.operator("object.vertex_group_invert", text="Invert")
         layout.operator("object.vertex_group_clean", text="Clean")
         layout.operator("object.vertex_group_levels", text="Levels")
+        layout.operator("object.vertex_group_blend", text="Blend")
         layout.operator("object.vertex_group_fix", text="Fix Deforms")
 
         layout.separator()

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-04-03 00:28:38 UTC (rev 45352)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-04-03 02:16:27 UTC (rev 45353)
@@ -977,6 +977,7 @@
         col.operator("object.vertex_group_invert", text="Invert")
         col.operator("object.vertex_group_clean", text="Clean")
         col.operator("object.vertex_group_levels", text="Levels")
+        col.operator("object.vertex_group_blend", text="Blend")
         col.operator("object.vertex_group_fix", text="Fix Deforms")
 
 

Modified: trunk/blender/source/blender/editors/object/object_vgroup.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_vgroup.c	2012-04-03 00:28:38 UTC (rev 45352)
+++ trunk/blender/source/blender/editors/object/object_vgroup.c	2012-04-03 02:16:27 UTC (rev 45353)
@@ -1249,91 +1249,132 @@
 	}
 }
 
-static void vgroup_blend(Object *ob)
+static void vgroup_blend(Object *ob, const float fac)
 {
+	MDeformVert *dv;
 	MDeformWeight *dw;
-	MDeformVert *dvert_array=NULL, *dvert;
 	int i, dvert_tot=0;
-	const int def_nr= ob->actdef-1;
+	const int def_nr= ob->actdef - 1;
 
-	BMEditMesh *em;
+	BLI_assert(fac >= 0.0 && fac <= 1.0f);
 
-	if (ob->type != OB_MESH || ((em = BMEdit_FromObject(ob)) == NULL)) {
+	if (ob->type != OB_MESH) {
 		return;
 	}
 
 	if (BLI_findlink(&ob->defbase, def_nr)) {
+		const float ifac = 1.0f - fac;
+		int i1, i2;
+
+		BMEditMesh *em = BMEdit_FromObject(ob);
+		BMesh *bm = em ? em->bm : NULL;
+		Mesh  *me = em ? NULL   : ob->data;
+
+		/* bmesh only*/
 		BMEdge *eed;
 		BMVert *eve;
 		BMIter iter;
 
-		int i1, i2;
+		/* mesh only */
+		MDeformVert *dvert_array = NULL;
 
+
 		float *vg_weights;
 		float *vg_users;
 		int sel1, sel2;
 
-		BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+		if (bm) {
+			BM_mesh_elem_index_ensure(bm, BM_VERT);
+			dvert_tot = bm->totvert;
+		}
+		else {
+			dvert_tot = me->totvert;
+			dvert_array = me->dvert;
+		}
 
-		dvert_tot= em->bm->totvert;
+		vg_weights = MEM_callocN(sizeof(float) * dvert_tot, "vgroup_blend_f");
+		vg_users = MEM_callocN(sizeof(int) * dvert_tot, "vgroup_blend_i");
 
-		vg_weights= MEM_callocN(sizeof(float)*dvert_tot, "vgroup_blend_f");
-		vg_users= MEM_callocN(sizeof(int)*dvert_tot, "vgroup_blend_i");
+		if (bm) {
+			BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+				sel1 = BM_elem_flag_test(eed->v1, BM_ELEM_SELECT);
+				sel2 = BM_elem_flag_test(eed->v2, BM_ELEM_SELECT);
 
-		BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
-			sel1= BM_elem_flag_test(eed->v1, BM_ELEM_SELECT);
-			sel2= BM_elem_flag_test(eed->v2, BM_ELEM_SELECT);
+				if (sel1 != sel2) {
+					/* i1 is always the selected one */
+					if (sel1) {
+						i1= BM_elem_index_get(eed->v1);
+						i2= BM_elem_index_get(eed->v2);
+						eve= eed->v2;
+					}
+					else {
+						i2= BM_elem_index_get(eed->v1);
+						i1= BM_elem_index_get(eed->v2);
+						eve= eed->v1;
+					}
 
-			if (sel1 != sel2) {
-				/* i1 is always the selected one */
-				if (sel1==TRUE && sel2==FALSE) {
-					i1= BM_elem_index_get(eed->v1);
-					i2= BM_elem_index_get(eed->v2);
-					eve= eed->v2;
+					dv = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT);
+					dw = defvert_find_index(dv, def_nr);
+					if (dw) {
+						vg_weights[i1] += dw->weight;
+					}
+					vg_users[i1]++;
 				}
-				else {
-					i2= BM_elem_index_get(eed->v1);
-					i1= BM_elem_index_get(eed->v2);
-					eve= eed->v1;
-				}
+			}
 
-				vg_users[i1]++;
+			BM_ITER_INDEX(eve, &iter, bm, BM_VERTS_OF_MESH, NULL, i) {
+				if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && vg_users[i] > 0) {
+					dv = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT);
 
-				/* TODO, we may want object mode blending */
-#if 0
-				if (em) {
-					dvert = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+					dw = defvert_verify_index(dv, def_nr);
+					dw->weight = (fac * (vg_weights[i] / (float)vg_users[i])) + (ifac * dw->weight);
+					/* in case of division errors */
+					CLAMP(dw->weight, 0.0f, 1.0f);
 				}
-				else
-#endif
-				{
-					dvert= dvert_array+i2;
-				}
+			}
+		}
+		else {
+			MEdge *ed = me->medge;
+			MVert *mv;
 
-				dw = defvert_find_index(dvert, def_nr);
+			for (i = 0; i < me->totedge; i++, ed++) {
+				sel1 = me->mvert[ed->v1].flag & SELECT;
+				sel2 = me->mvert[ed->v2].flag & SELECT;
 
-				if (dw) {
-					vg_weights[i1] += dw->weight;
+				if (sel1 != sel2) {
+					/* i1 is always the selected one */
+					if (sel1) {
+						i1 = ed->v1;
+						i2 = ed->v2;
+					}
+					else {
+						i2 = ed->v1;
+						i1 = ed->v2;
+					}
+
+					dv = &dvert_array[i2];
+					dw = defvert_find_index(dv, def_nr);
+					if (dw) {
+						vg_weights[i1] += dw->weight;
+					}
+					vg_users[i1]++;
 				}
 			}
-		}
 
-		i= 0;
-		BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
-			if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && vg_users[i] > 0) {
-				/* TODO, we may want object mode blending */
-				if (em)  dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
-				else	dvert= dvert_array+i;
+			mv = me->mvert;
+			dv = dvert_array;
 
-				dw= defvert_verify_index(dvert, def_nr);
-				dw->weight= vg_weights[i] / (float)vg_users[i];
+			for (i = 0; i < dvert_tot; i++, mv++, dv++) {
+				if ((mv->flag & SELECT) && (vg_users[i] > 0)) {
+					dw = defvert_verify_index(dv, def_nr);
+					dw->weight = (fac * (vg_weights[i] / (float)vg_users[i])) + (ifac * dw->weight);
 
-				/* in case of division errors */
-				CLAMP(dw->weight, 0.0f, 1.0f);
+					/* in case of division errors */
+					CLAMP(dw->weight, 0.0f, 1.0f);
+				}
 			}
+		}
 
-			i++;
-		}
 		MEM_freeN(vg_weights);
 		MEM_freeN(vg_users);
 	}
@@ -2482,11 +2523,12 @@
 }
 
 
-static int vertex_group_blend_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_blend_exec(bContext *C, wmOperator *op)
 {
-	Object *ob= ED_object_context(C);
+	Object *ob = ED_object_context(C);
+	float fac = RNA_float_get(op->ptr, "factor");
 
-	vgroup_blend(ob);
+	vgroup_blend(ob, fac);
 
 	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
@@ -2495,19 +2537,53 @@
 	return OPERATOR_FINISHED;
 }
 
+/* check we have a vertex selection, either in weight paint or editmode */
+static int vertex_group_blend_poll(bContext *C)
+{
+	Object *ob = ED_object_context(C);
+	ID *data = (ob) ? ob->data: NULL;
+
+	if (!(ob && !ob->id.lib && data && !data->lib))
+		return FALSE;
+
+	if (vgroup_object_in_edit_mode(ob)) {
+		return TRUE;
+	}
+	else if ((ob->type == OB_MESH) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
+		if (ME_EDIT_PAINT_SEL_MODE(((Mesh *)data)) == SCE_SELECT_VERTEX) {
+			return TRUE;
+		}
+		else {
+			CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode");
+			return FALSE;
+		}
+
+	}
+	else {
+		return FALSE;
+	}
+}
+
 void OBJECT_OT_vertex_group_blend(wmOperatorType *ot)
 {
+	PropertyRNA *prop;
+
 	/* identifiers */
 	ot->name = "Blend Vertex Group";
 	ot->idname = "OBJECT_OT_vertex_group_blend";
-	ot->description = "";
+	ot->description = "Blend selected vertex weights with unselected for the active group";
 
 	/* api callbacks */
-	ot->poll = vertex_group_poll_edit; /* TODO - add object mode support */
+	ot->poll = vertex_group_blend_poll;
 	ot->exec = vertex_group_blend_exec;
 
 	/* flags */
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	prop = RNA_def_property(ot->srna, "factor", PROP_FLOAT, PROP_FACTOR);
+	RNA_def_property_ui_text(prop, "Factor", "");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_float_default(prop, 1.0f);
 }
 
 




More information about the Bf-blender-cvs mailing list