[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29597] trunk/blender/source/blender: [ #22262] Sculpting shape keys using the Smooth brush switches the shape to the Basis

Sergey Sharybin g.ulairi at gmail.com
Mon Jun 21 22:11:00 CEST 2010


Revision: 29597
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29597
Author:   nazgul
Date:     2010-06-21 22:10:59 +0200 (Mon, 21 Jun 2010)

Log Message:
-----------
[#22262] Sculpting shape keys using the Smooth brush switches the shape to the Basis

PBVH used the same verts array as mesh data and shape key/reference key coords
were applying on the mesh data, so on some refreshing undeformed mesh was
displayed.
Added utility functions to get vert coords from key block, apply new vert coords
on keyblock and function to apply coords on bpvh, so now pbvh uses it's ovn
vertex array and no changes are making to the mesh data.

Additional change:
Store key block name in SculptUndoNode, so now shape wouldn't be copied to
wrong keyblock on undo

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_key.h
    trunk/blender/source/blender/blenkernel/BKE_paint.h
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenkernel/intern/depsgraph.c
    trunk/blender/source/blender/blenkernel/intern/key.c
    trunk/blender/source/blender/blenlib/BLI_pbvh.h
    trunk/blender/source/blender/blenlib/intern/pbvh.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt_intern.h

Modified: trunk/blender/source/blender/blenkernel/BKE_key.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_key.h	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenkernel/BKE_key.h	2010-06-21 20:10:59 UTC (rev 29597)
@@ -75,6 +75,8 @@
 void latt_to_key(struct Lattice *lt, struct KeyBlock *kb);
 void key_to_curve(struct KeyBlock *kb, struct Curve  *cu, struct ListBase *nurb);
 void curve_to_key(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
+float (*key_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3];
+void vertcos_to_key(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
 
 #ifdef __cplusplus
 };

Modified: trunk/blender/source/blender/blenkernel/BKE_paint.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_paint.h	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenkernel/BKE_paint.h	2010-06-21 20:10:59 UTC (rev 29597)
@@ -70,7 +70,7 @@
 	int totvert, totface;
 	float *face_normals;
 	struct Object *ob;
-	struct KeyBlock *kb, *refkb;
+	struct KeyBlock *kb;
 	
 	/* Mesh connectivity */
 	struct ListBase *fmap;
@@ -94,6 +94,8 @@
 	struct StrokeCache *cache;
 
 	struct GPUDrawObject *drawobject;
+
+	int modifiers_active;
 } SculptSession;
 
 void free_sculptsession(struct Object *ob);

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2010-06-21 20:10:59 UTC (rev 29597)
@@ -186,6 +186,16 @@
 	return cddm->fmap;
 }
 
+static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
+{
+	CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+	Mesh *me= (ob)? ob->data: NULL;
+
+	if(ob->sculpt->modifiers_active) return 0;
+
+	return (cddm->mvert == me->mvert) || ob->sculpt->kb;
+}
+
 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
 {
 	CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
@@ -200,7 +210,7 @@
 		return NULL;
 	if(ob->sculpt->pbvh) {
 		cddm->pbvh= ob->sculpt->pbvh;
-		cddm->pbvh_draw = (cddm->mvert == me->mvert) || ob->sculpt->kb;
+		cddm->pbvh_draw = can_pbvh_draw(ob, dm);
 	}
 
 	/* always build pbvh from original mesh, and only use it for drawing if
@@ -208,7 +218,7 @@
 	   that this is actually for, to support a pbvh on a modified mesh */
 	if(!cddm->pbvh && ob->type == OB_MESH) {
 		cddm->pbvh = BLI_pbvh_new();
-		cddm->pbvh_draw = (cddm->mvert == me->mvert) || ob->sculpt->kb;
+		cddm->pbvh_draw = can_pbvh_draw(ob, dm);
 		BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
 				   me->totface, me->totvert);
 	}

Modified: trunk/blender/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2010-06-21 20:10:59 UTC (rev 29597)
@@ -2286,9 +2286,6 @@
 			/* no point in trying in this cases */
 			if(!id || id->us <= 1)
 				id= NULL;
-			/* for locked shape keys we make an exception */
-			else if(ob_get_key(ob) && (ob->shapeflag & OB_SHAPE_LOCK))
-				id= NULL;
 		}
 	}
 

Modified: trunk/blender/source/blender/blenkernel/intern/key.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/key.c	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenkernel/intern/key.c	2010-06-21 20:10:59 UTC (rev 29597)
@@ -38,6 +38,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
+#include "BLI_math_vector.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_key_types.h"
@@ -1719,3 +1720,151 @@
 		VECCOPY(mvert->co, fp);
 	}
 }
+
+/************************* vert coords ************************/
+float (*key_to_vertcos(Object *ob, KeyBlock *kb))[3]
+{
+	float (*vertCos)[3], *co;
+	float *fp= kb->data;
+	int tot= 0, a;
+
+	/* Count of vertex coords in array */
+	if(ob->type == OB_MESH) {
+		Mesh *me= (Mesh*)ob->data;
+		tot= me->totvert;
+	} else if(ob->type == OB_LATTICE) {
+		Lattice *lt= (Lattice*)ob->data;
+		tot= lt->pntsu*lt->pntsv*lt->pntsw;
+	} else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+		Curve *cu= (Curve*)ob->data;
+		tot= count_curveverts(&cu->nurb);
+	}
+
+	if (tot == 0) return NULL;
+
+	vertCos= MEM_callocN(tot*sizeof(*vertCos), "key_to_vertcos vertCos");
+
+	/* Copy coords to array */
+	co= (float*)vertCos;
+
+	if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
+		for (a= 0; a<tot; a++, fp+=3, co+=3) {
+			copy_v3_v3(co, fp);
+		}
+	} else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+		Curve *cu= (Curve*)ob->data;
+		Nurb *nu= cu->nurb.first;
+		BezTriple *bezt;
+		BPoint *bp;
+
+		while (nu) {
+			if(nu->bezt) {
+				int i;
+				bezt= nu->bezt;
+				a= nu->pntsu;
+
+				while (a--) {
+					for (i= 0; i<3; i++) {
+						copy_v3_v3(co, fp);
+						fp+= 3; co+= 3;
+					}
+
+					fp+= 3; /* skip alphas */
+
+					bezt++;
+				}
+			}
+			else {
+				bp= nu->bp;
+				a= nu->pntsu*nu->pntsv;
+
+				while (a--) {
+					copy_v3_v3(co, fp);
+
+					fp+= 4;
+					co+= 3;
+
+					bp++;
+				}
+			}
+
+			nu= nu->next;
+		}
+	}
+
+	return vertCos;
+}
+
+void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
+{
+	float *co= (float*)vertCos, *fp;
+	int tot= 0, a, elemsize;
+
+	if (kb->data) MEM_freeN(kb->data);
+
+	/* Count of vertex coords in array */
+	if(ob->type == OB_MESH) {
+		Mesh *me= (Mesh*)ob->data;
+		tot= me->totvert;
+		elemsize= me->key->elemsize;
+	} else if(ob->type == OB_LATTICE) {
+		Lattice *lt= (Lattice*)ob->data;
+		tot= lt->pntsu*lt->pntsv*lt->pntsw;
+		elemsize= lt->key->elemsize;
+	} else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+		Curve *cu= (Curve*)ob->data;
+		elemsize= cu->key->elemsize;
+		tot= count_curveverts(&cu->nurb);
+	}
+
+	fp= kb->data= MEM_callocN(tot*elemsize, "key_to_vertcos vertCos");
+
+	if (tot == 0) return;
+
+	/* Copy coords to keyblock */
+
+	if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
+		for (a= 0; a<tot; a++, fp+=3, co+=3) {
+			copy_v3_v3(fp, co);
+		}
+	} else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+		Curve *cu= (Curve*)ob->data;
+		Nurb *nu= cu->nurb.first;
+		BezTriple *bezt;
+		BPoint *bp;
+
+		while (nu) {
+			if(nu->bezt) {
+				int i;
+				bezt= nu->bezt;
+				a= nu->pntsu;
+
+				while (a--) {
+					for (i= 0; i<3; i++) {
+						copy_v3_v3(fp, co);
+						fp+= 3; co+= 3;
+					}
+
+					fp+= 3; /* skip alphas */
+
+					bezt++;
+				}
+			}
+			else {
+				bp= nu->bp;
+				a= nu->pntsu*nu->pntsv;
+
+				while (a--) {
+					copy_v3_v3(fp, co);
+
+					fp+= 4;
+					co+= 3;
+
+					bp++;
+				}
+			}
+
+			nu= nu->next;
+		}
+	}
+}

Modified: trunk/blender/source/blender/blenlib/BLI_pbvh.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_pbvh.h	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenlib/BLI_pbvh.h	2010-06-21 20:10:59 UTC (rev 29597)
@@ -114,6 +114,12 @@
 void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids,
 	struct DMGridAdjacency *gridadj, void **gridfaces);
 
+/* vertex deformer */
+float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
+void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
+int BLI_pbvh_isDeformed(struct PBVH *pbvh);
+
+
 /* Vertex Iterator */
 
 /* this iterator has quite a lot of code, but it's designed to:

Modified: trunk/blender/source/blender/blenlib/intern/pbvh.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/pbvh.c	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/blenlib/intern/pbvh.c	2010-06-21 20:10:59 UTC (rev 29597)
@@ -29,6 +29,7 @@
 #include "BLI_pbvh.h"
 
 #include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h" /* for mesh_calc_normals */
 
 #include "gpu_buffers.h"
 
@@ -120,6 +121,9 @@
 #ifdef PERFCNTRS
 	int perf_modified;
 #endif
+
+	/* flag are verts/faces deformed */
+	int deformed;
 };
 
 #define STACK_FIXED_DEPTH	100
@@ -576,6 +580,15 @@
 		}
 	}
 
+	if (bvh->deformed) {
+		if (bvh->verts) {
+			/* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
+
+			MEM_freeN(bvh->verts);
+			MEM_freeN(bvh->faces);
+		}
+	}
+
 	MEM_freeN(bvh->nodes);
 	MEM_freeN(bvh->prim_indices);
 	MEM_freeN(bvh);
@@ -1330,3 +1343,55 @@
 	bvh->gridfaces= gridfaces;
 }
 
+float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
+{
+	int a;
+	float (*vertCos)[3]= NULL;
+
+	if (pbvh->verts) {
+		float *co;
+		MVert *mvert= pbvh->verts;
+
+		vertCos= MEM_callocN(3*pbvh->totvert*sizeof(float), "BLI_pbvh_get_vertCoords");
+		co= (float*)vertCos;
+
+		for (a= 0; a<pbvh->totvert; a++, mvert++, co+= 3) {
+			copy_v3_v3(co, mvert->co);
+		}
+	}
+
+	return vertCos;
+}
+
+void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+{
+	int a;
+
+	if (!pbvh->deformed) {
+		if (pbvh->verts) {
+			/* if pbvh is not already deformed, verts/faces points to the */
+			/* original data and applying new coords to this arrays would lead to */
+			/* unneeded deformation -- duplicate verts/faces to avoid this */
+
+			pbvh->verts= MEM_dupallocN(pbvh->verts);
+			pbvh->faces= MEM_dupallocN(pbvh->faces);
+
+			pbvh->deformed= 1;
+		}
+	}
+
+	if (pbvh->verts) {
+		/* copy new verts coords */
+		for (a= 0; a < pbvh->totvert; ++a) {
+			copy_v3_v3(pbvh->verts[a].co, vertCos[a]);
+		}
+
+		/* coordinates are new -- normals should also be updated */
+		mesh_calc_normals(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
+	}
+}
+
+int BLI_pbvh_isDeformed(PBVH *pbvh)
+{
+	return pbvh->deformed;
+}

Modified: trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2010-06-21 19:46:23 UTC (rev 29596)
+++ trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2010-06-21 20:10:59 UTC (rev 29597)
@@ -275,6 +275,9 @@
 
 	/* layer brush */
 	float *layer_disp;
+
+	/* shape keys */
+	char *shapeName[32]; /* keep size in sync with keyblock dna */
 } SculptUndoNode;
 
 static void update_cb(PBVHNode *node, void *data)
@@ -326,16 +329,53 @@
 			continue;
 
 		if(unode->maxvert) {
+			char *shapeName= (char*)unode->shapeName;
+
 			/* regular mesh restore */
 			if(ss->totvert != unode->maxvert)
 				continue;
 
+			if (ss->kb && strcmp(ss->kb->name, shapeName)) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list