[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12610] trunk/blender/source/blender: Long outstanding feature request: "Multi Modifier"

Ton Roosendaal ton at blender.org
Fri Nov 16 16:47:00 CET 2007


Revision: 12610
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12610
Author:   ton
Date:     2007-11-16 16:46:59 +0100 (Fri, 16 Nov 2007)

Log Message:
-----------
Long outstanding feature request: "Multi Modifier"

This allows to mix between the result of 2 modifiers, with both
using the same input state. This is useful for having a mesh deform
and armature deform working together.

However! This functionality could have been presented better...
this is actually Node editor stuff!

Now it works by adding a "MM" button, next to the "overall vgroup"
option. If MM is pressed, the input of this modifier is the same as
the input of the previous modifier.
Only the armature modifier has this option now...

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_lattice.h
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/makesdna/DNA_modifier_types.h
    trunk/blender/source/blender/src/buttons_editing.c

Modified: trunk/blender/source/blender/blenkernel/BKE_lattice.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_lattice.h	2007-11-16 14:47:31 UTC (rev 12609)
+++ trunk/blender/source/blender/blenkernel/BKE_lattice.h	2007-11-16 15:46:59 UTC (rev 12610)
@@ -64,8 +64,8 @@
                           int numVerts, char *vgroup);
 void armature_deform_verts(struct Object *armOb, struct Object *target,
                            struct DerivedMesh *dm, float (*vertexCos)[3],
-                           float (*defMats)[3][3], int numVerts,
-                           int deformflag, const char *defgrp_name);
+                           float (*defMats)[3][3], int numVerts, int deformflag, 
+						   float (*prevCos)[3], const char *defgrp_name);
 float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3];
 void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]);
 void lattice_calc_modifiers(struct Object *ob);

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-16 14:47:31 UTC (rev 12609)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-16 15:46:59 UTC (rev 12610)
@@ -790,7 +790,8 @@
 
 void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
                            float (*vertexCos)[3], float (*defMats)[3][3],
-						   int numVerts, int deformflag, const char *defgrp_name)
+						   int numVerts, int deformflag, 
+						   float (*prevCos)[3], const char *defgrp_name)
 {
 	bPoseChannel *pchan, **defnrToPC = NULL;
 	MDeformVert *dverts = NULL;
@@ -881,11 +882,12 @@
 	for(i = 0; i < numVerts; i++) {
 		MDeformVert *dvert;
 		DualQuat sumdq, *dq = NULL;
-		float *co = vertexCos[i], dco[3];
+		float *co, dco[3];
 		float sumvec[3], summat[3][3];
 		float *vec = NULL, (*smat)[3] = NULL;
 		float contrib = 0.0f;
-		float armature_weight = 1.0f; /* default to 1 if no overall def group */
+		float armature_weight = 1.0f;	/* default to 1 if no overall def group */
+		float prevco_weight = 1.0f;		/* weight for optional cached vertexcos */
 		int	  j;
 
 		if(use_quaternion) {
@@ -917,11 +919,19 @@
 					break;
 				}
 			}
+			/* hackish: the blending factor can be used for blending with prevCos too */
+			if(prevCos) {
+				prevco_weight= armature_weight;
+				armature_weight= 1.0f;
+			}
 		}
 
 		/* check if there's any  point in calculating for this vert */
 		if(armature_weight == 0.0f) continue;
 		
+		/* get the coord we work on */
+		co= prevCos?prevCos[i]:vertexCos[i];
+		
 		/* Apply the object's matrix */
 		Mat4MulVecfl(premat, co);
 		
@@ -1005,6 +1015,15 @@
 		
 		/* always, check above code */
 		Mat4MulVecfl(postmat, co);
+		
+		
+		/* interpolate with previous modifier position using weight group */
+		if(prevCos && prevco_weight!=1.0f) {
+			float mw= 1.0f - prevco_weight;
+			vertexCos[i][0]= mw*vertexCos[i][0] + prevco_weight*co[0];
+			vertexCos[i][1]= mw*vertexCos[i][1] + prevco_weight*co[1];
+			vertexCos[i][2]= mw*vertexCos[i][2] + prevco_weight*co[2];
+		}
 	}
 
 	if(dualquats) MEM_freeN(dualquats);

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-16 14:47:31 UTC (rev 12609)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-16 15:46:59 UTC (rev 12610)
@@ -238,12 +238,29 @@
 	}
 }
 
+static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
+{
+	md= md->next;
+	if(md) {
+		if(md->type==eModifierType_Armature) {
+			ArmatureModifierData *amd = (ArmatureModifierData*) md;
+			if(amd->multi)
+				amd->prevCos= MEM_dupallocN(vertexCos);
+		}
+		/* lattice/mesh modifier too */
+	}
+}
+
+
 static void latticeModifier_deformVerts(
                 ModifierData *md, Object *ob, DerivedMesh *derivedData,
                 float (*vertexCos)[3], int numVerts)
 {
 	LatticeModifierData *lmd = (LatticeModifierData*) md;
 
+
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+	
 	lattice_deform_verts(lmd->object, ob, derivedData,
 	                     vertexCos, numVerts, lmd->name);
 }
@@ -4664,8 +4681,16 @@
 {
 	ArmatureModifierData *amd = (ArmatureModifierData*) md;
 
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+	
 	armature_deform_verts(amd->object, ob, derivedData, vertexCos, NULL,
-	                      numVerts, amd->deformflag, amd->defgrp_name);
+	                      numVerts, amd->deformflag, 
+						  amd->prevCos, amd->defgrp_name);
+	/* free cache */
+	if(amd->prevCos) {
+		MEM_freeN(amd->prevCos);
+		amd->prevCos= NULL;
+	}
 }
 
 static void armatureModifier_deformVertsEM(
@@ -4678,7 +4703,7 @@
 	if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 
 	armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts,
-	                      amd->deformflag, amd->defgrp_name);
+	                      amd->deformflag, NULL, amd->defgrp_name);
 
 	if(!derivedData) dm->release(dm);
 }
@@ -4694,7 +4719,7 @@
 	if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 
 	armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
-	                      amd->deformflag, amd->defgrp_name);
+	                      amd->deformflag, NULL, amd->defgrp_name);
 
 	if(!derivedData) dm->release(dm);
 }
@@ -5241,6 +5266,8 @@
 	else
 		dm= derivedData;
 
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+	
 	meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
 
 	if(dm != derivedData)

Modified: trunk/blender/source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-16 14:47:31 UTC (rev 12609)
+++ trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-16 15:46:59 UTC (rev 12610)
@@ -313,9 +313,10 @@
 typedef struct ArmatureModifierData {
 	ModifierData modifier;
 
-	short deformflag, pad1;		/* deformflag replaces armature->deformflag */
+	short deformflag, multi;		/* deformflag replaces armature->deformflag */
 	int pad2;
 	struct Object *object;
+	float *prevCos;		/* stored input of previous modifier, for vertexgroup blending */
 	char defgrp_name[32];
 } ArmatureModifierData;
 

Modified: trunk/blender/source/blender/src/buttons_editing.c
===================================================================
--- trunk/blender/source/blender/src/buttons_editing.c	2007-11-16 14:47:31 UTC (rev 12609)
+++ trunk/blender/source/blender/src/buttons_editing.c	2007-11-16 15:46:59 UTC (rev 12610)
@@ -1957,8 +1957,10 @@
 			ArmatureModifierData *amd = (ArmatureModifierData*) md;
 			uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
 			
-			but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",				  lx, (cy-=19), buttonWidth,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence");
+			but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",				  lx, (cy-=19), buttonWidth-40,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence");
 			uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+			uiDefButS(block, TOG, B_ARM_RECALCDATA, "MM",	lx+buttonWidth-40,cy, 40, 20, &amd->multi, 0, 0, 0, 0, "MultiModifier: This modifier uses same input as previous modifier, and mixes using this vgroup");
+			
 			uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vert.Groups",	lx,cy-=19,buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform");
 			uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes",	lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform");
 			uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion",	lx,(cy-=19),buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions");





More information about the Bf-blender-cvs mailing list