[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36180] branches/bmesh/blender/source/ blender: =bmesh= modifiers can now be applied with shapekeys

Joseph Eagar joeedh at gmail.com
Fri Apr 15 07:20:19 CEST 2011


Revision: 36180
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36180
Author:   joeedh
Date:     2011-04-15 05:20:18 +0000 (Fri, 15 Apr 2011)
Log Message:
-----------
=bmesh= modifiers can now be applied with shapekeys

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/blenkernel/BKE_DerivedMesh.h
    branches/bmesh/blender/source/blender/blenkernel/intern/DerivedMesh.c
    branches/bmesh/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    branches/bmesh/blender/source/blender/blenkernel/intern/customdata.c
    branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
    branches/bmesh/blender/source/blender/blenkernel/intern/object.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c
    branches/bmesh/blender/source/blender/editors/mesh/editface.c
    branches/bmesh/blender/source/blender/editors/object/object_add.c
    branches/bmesh/blender/source/blender/editors/object/object_modifier.c
    branches/bmesh/blender/source/blender/editors/sculpt_paint/paint_image.c
    branches/bmesh/blender/source/blender/editors/sculpt_paint/paint_vertex.c
    branches/bmesh/blender/source/blender/editors/space_view3d/view3d_snap.c
    branches/bmesh/blender/source/blender/editors/transform/transform_conversions.c
    branches/bmesh/blender/source/blender/editors/util/crazyspace.c
    branches/bmesh/blender/source/blender/makesrna/intern/rna_modifier.c
    branches/bmesh/blender/source/blender/makesrna/intern/rna_object_api.c
    branches/bmesh/blender/source/blender/modifiers/intern/MOD_boolean_util.c
    branches/bmesh/blender/source/blender/modifiers/intern/MOD_mirror.c

Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-04-15 03:47:54 UTC (rev 36179)
+++ branches/bmesh/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-04-15 05:20:18 UTC (rev 36180)
@@ -446,7 +446,7 @@
 
 /* utility function to convert a DerivedMesh to a Mesh
  */
-void DM_to_mesh(DerivedMesh *dm, struct Mesh *me);
+void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob);
 
 /* utility function to convert a DerivedMesh to a shape key block 
  */
@@ -585,7 +585,8 @@
 DerivedMesh *mesh_get_derived_deform(struct Scene *scene, struct Object *ob,
 									 CustomDataMask dataMask);
 
-DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob, struct ModifierData *md);
+DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob,
+											  struct ModifierData *md, int build_shapekey_layers);
 
 DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
 										CustomDataMask dataMask);
@@ -620,7 +621,8 @@
 												 CustomDataMask dataMask);
 float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *numVerts_r))[3];
 int editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
-void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, CustomDataMask dataMask);
+void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, 
+	CustomDataMask dataMask, int build_shapekey_layers);
 
 /* returns an array of deform matrices for crazyspace correction, and the
    number of modifiers left */

Modified: branches/bmesh/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-04-15 03:47:54 UTC (rev 36179)
+++ branches/bmesh/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-04-15 05:20:18 UTC (rev 36180)
@@ -33,8 +33,8 @@
 
 
 #include <string.h>
+#include "limits.h"
 
-
 #include "MEM_guardedalloc.h"
 
 #include "DNA_cloth_types.h"
@@ -77,8 +77,11 @@
 
 #include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */
 
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
+
+		///////////////////////////////////
 ///////////////////////////////////
-///////////////////////////////////
 
 static MVert *dm_getVertArray(DerivedMesh *dm)
 {
@@ -364,13 +367,14 @@
 	target->numPolyData = source->getNumFaces(source);
 }
 
-void DM_to_mesh(DerivedMesh *dm, Mesh *me)
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
 {
 	/* dm might depend on me, so we need to do everything with a local copy */
 	Mesh tmp = *me;
 	DMFaceIter *iter;
 	int totvert, totedge, totface, totloop, totpoly;
-
+	int did_shapekeys=0;
+	
 	memset(&tmp.vdata, 0, sizeof(tmp.vdata));
 	memset(&tmp.edata, 0, sizeof(tmp.edata));
 	memset(&tmp.fdata, 0, sizeof(tmp.fdata));
@@ -396,6 +400,31 @@
 	CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
 	CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
 
+	if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
+		KeyBlock *kb;
+		int i=0;
+		
+		if (ob) {
+			for (kb=me->key->block.first; kb; kb=kb->next, i++) {
+				if (i == ob->shapenr-1) {
+					i = kb->uid;
+					break;
+				}
+			}
+			
+			if (!kb) {
+				printf("error in DM_to_mesh: could not find active shapekey! eek!!\n");
+				i = INT_MAX;
+			}
+		} else {
+			/*if no object, set to INT_MAX so we don't mess up any shapekey layers*/
+			i = INT_MAX;
+		}
+		
+		shapekey_layers_to_keyblocks(dm, me, i);
+		did_shapekeys = 1;
+	}
+	
 	/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
 	   we set them here in case they are missing */
 	if(!CustomData_has_layer(&tmp.vdata, CD_MVERT))
@@ -409,10 +438,10 @@
 
 	/* object had got displacement layer, should copy this layer to save sculpted data */
 	/* NOTE: maybe some other layers should be copied? nazgul */
-	if(CustomData_has_layer(&me->fdata, CD_MDISPS)) {
-		if (totface == me->totface) {
-			MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
-			CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface);
+	if(CustomData_has_layer(&me->ldata, CD_MDISPS)) {
+		if (totloop == me->totloop) {
+			MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+			CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
 		}
 	}
 
@@ -424,10 +453,10 @@
 	CustomData_free(&me->ldata, me->totloop);
 	CustomData_free(&me->pdata, me->totpoly);
 
-	/* BMESH_TODO/XXX: ok, this should use new CD shapekey data,
-	                   which shouuld be fed through the modifier 
-					   stack*/
-	if(tmp.totvert != me->totvert) {
+	/*  ok, this should now use new CD shapekey data,
+	    which shouuld be fed through the modifier 
+		stack*/
+	if(tmp.totvert != me->totvert && !did_shapekeys) {
 		printf("YEEK! this should be recoded! Shape key loss!!!\n");
 		if(tmp.key) tmp.key->id.us--;
 		tmp.key = NULL;
@@ -672,7 +701,8 @@
 
 /***/
 
-DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md)
+DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, 
+	ModifierData *md, int build_shapekey_layers)
 {
 	Mesh *me = ob->data;
 	ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -682,7 +712,11 @@
 	
 	if (!(md->mode&eModifierMode_Realtime)) return NULL;
 	if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
-
+	
+	if (build_shapekey_layers && me->key && ob->shapenr <= BLI_countlist(&me->key->block)) {
+		key_to_mesh(BLI_findlink(&me->key->block, ob->shapenr-1), me);
+	}
+	
 	if (mti->type==eModifierTypeType_OnlyDeform) {
 		int numVerts;
 		float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
@@ -690,9 +724,16 @@
 		mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0);
 		dm = mesh_create_derived(me, ob, deformedVerts);
 
+		if (build_shapekey_layers)
+			add_shapekey_layers(dm, me, ob);
+		
 		MEM_freeN(deformedVerts);
 	} else {
 		DerivedMesh *tdm = mesh_create_derived(me, ob, NULL);
+
+		if (build_shapekey_layers)
+			add_shapekey_layers(tdm, me, ob);
+		
 		dm = mti->applyModifier(md, ob, tdm, 0, 0);
 
 		if(tdm != dm) tdm->release(tdm);
@@ -924,6 +965,92 @@
 	dfiter->free(dfiter);
 }
 
+
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
+{
+	KeyBlock *kb;
+	int i, j, tot;
+	
+	if (!me->key)
+		return;	
+	
+	tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY);
+	for (i=0; i<tot; i++) {
+		CustomDataLayer *layer = &dm->vertData.layers[CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i)];
+		float (*cos)[3], (*kbcos)[3];
+		
+		for (kb=me->key->block.first; kb; kb=kb->next) {
+			if (kb->uid == layer->uid)
+				break;
+		}
+		
+		if (!kb) {
+			kb = add_keyblock(me->key, layer->name);
+			kb->uid = layer->uid;
+		}
+		
+		if (kb->data)
+			MEM_freeN(kb->data);
+		
+		cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
+		kb->totelem = dm->numVertData;
+
+		kb->data = kbcos = MEM_mallocN(sizeof(float)*3*kb->totelem, "kbcos DerivedMesh.c");
+		if (kb->uid == actshape_uid) {
+			MVert *mvert = dm->getVertArray(dm);
+			
+			for (j=0; j<dm->numVertData; j++, kbcos++, mvert++) {
+				copy_v3_v3(*kbcos, mvert->co);
+			}
+		} else {
+			for (j=0; j<kb->totelem; j++, cos++, kbcos++) {
+				copy_v3_v3(*kbcos, *cos);
+			}
+		}
+	}
+	
+	for (kb=me->key->block.first; kb; kb=kb->next) {
+		if (kb->totelem != dm->numVertData) {
+			if (kb->data)
+				MEM_freeN(kb->data);
+			
+			kb->totelem = dm->numVertData;
+			kb->data = MEM_callocN(sizeof(float)*3*kb->totelem, "kb->data derivedmesh.c");
+			printf("eek! lost a shapekey layer!\n");
+		}
+	}
+}
+
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob)
+{
+	KeyBlock *kb;
+	Key *key = me->key;
+	int a, b;
+	
+	if (!me->key)
+		return;
+	
+	if (dm->numVertData != me->totvert) {
+		printf("error in add_shapekey_layers: dm isn't the same size as me\n");
+		return;
+	}
+		
+	for (a=0, kb=key->block.first; kb; kb=kb->next, a++) {
+		float (*cos)[3] = CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_CALLOC, NULL, dm->numVertData, kb->name);
+		int ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, a);
+		
+		dm->vertData.layers[ci].uid = kb->uid;
+		if (kb->totelem != dm->numVertData) {
+			printf("error in add_shapekey_layers: totelem and totvert don't match");
+			continue;
+		}
+		
+		for (b=0; b<kb->totelem; b++, cos++) {
+			copy_v3_v3(cos, ((float*)kb->data)+b*3);
+		}
+	}
+}
+
 /* new value for useDeform -1  (hack for the gameengine):
  * - apply only the modifier stack of the object, skipping the virtual modifiers,
  * - don't apply the key
@@ -932,7 +1059,8 @@
 static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
 								DerivedMesh **deform_r, DerivedMesh **final_r,
 								int useRenderParams, int useDeform,
-								int needMapping, CustomDataMask dataMask, int index, int useCache)
+								int needMapping, CustomDataMask dataMask, 
+								int index, int useCache, int build_shapekey_layers)
 {
 	Mesh *me = ob->data;
 	ModifierData *firstmd, *md;
@@ -1007,7 +1135,10 @@
 		 */
 		if (deform_r) {
 			*deform_r = CDDM_from_mesh(me, ob);
-
+			
+			if (build_shapekey_layers)
+				add_shapekey_layers(dm, me, ob);
+			
 			if(deformedVerts) {
 				CDDM_apply_vert_coords(*deform_r, deformedVerts);
 				CDDM_calc_normals(*deform_r);
@@ -1081,7 +1212,7 @@
 
 			/* if this is not the last modifier in the stack then recalculate the normals
 			 * to avoid giving bogus normals to the next modifier see: [#23673] */
-			if(isPrevDeform &&  mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+			if(dm && isPrevDeform &&  mti->dependsOnNormals && mti->dependsOnNormals(md)) {
 				/* XXX, this covers bug #23673, but we may need normal calc for other types */
 				if(dm->type == DM_TYPE_CDDM) {
 					CDDM_apply_vert_coords(dm, deformedVerts);
@@ -1112,6 +1243,9 @@
 			} else {
 				dm = CDDM_from_mesh(me, ob);
 
+				if (build_shapekey_layers)
+					add_shapekey_layers(dm, me, ob);
+
 				if(deformedVerts) {
 					CDDM_apply_vert_coords(dm, deformedVerts);
 					CDDM_calc_normals(dm);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list