diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-06-23 16:27:13 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-06-23 16:27:13 +0400 |
commit | 46d28a5e8dee014fe3aadce6c137eb5d67b9e4ac (patch) | |
tree | 0c175c802b429887d264d4510f5e1422f500b3da /source | |
parent | 08b5e5a492d5ac4097d814debb3c4520cb18e33d (diff) |
Sculpt+shape keys:
- Sculpting on the basis key should change original mesh
- For relative keys sculpting on basis key should update others
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 51 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 60 |
3 files changed, 110 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index c94955e611e..31e920406c0 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -77,6 +77,7 @@ 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]); +void offset_to_key(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]); #ifdef __cplusplus }; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 84484417f42..b8219c4aa35 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1868,3 +1868,54 @@ void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) } } } + +void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3]) +{ + int a; + float *co= (float*)ofs, *fp= kb->data; + + if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { + for (a= 0; a<kb->totelem; a++, fp+=3, co+=3) { + add_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++) { + add_v3_v3(fp, co); + fp+= 3; co+= 3; + } + + fp+= 3; /* skip alphas */ + + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + + while (a--) { + add_v3_v3(fp, co); + + fp+= 4; + co+= 3; + + bp++; + } + } + + nu= nu->next; + } + } +} diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 91769c92efe..53e07a50020 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -91,6 +91,11 @@ /* Number of vertices to average in order to determine the flatten distance */ #define FLATTEN_SAMPLE_SIZE 10 +/* ==== FORWARD DEFINITIONS ===== + * + */ +static void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]); + /* ===== STRUCTS ===== * */ @@ -364,7 +369,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) swap_v3_v3(vertCos[index[i]], unode->co[i]); /* propagate new coords to keyblock */ - vertcos_to_key(ob, ss->kb, vertCos); + sculpt_vertcos_to_key(ob, ss->kb, vertCos); /* pbvh uses it's own mvert array, so coords should be */ /* propagated to pbvh here */ @@ -1408,13 +1413,64 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, PBVHNode **node } } +static void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) +{ + Mesh *me= (Mesh*)ob->data; + float (*ofs)[3]= NULL; + int a, is_basis= 0; + KeyBlock *currkey; + + /* for relative keys editing of base should update other keys */ + if (me->key->type == KEY_RELATIVE) + for (currkey = me->key->block.first; currkey; currkey= currkey->next) + if(ob->shapenr-1 == currkey->relative) { + is_basis= 1; + break; + } + + if (is_basis) { + ofs= key_to_vertcos(ob, kb); + + /* calculate key coord offsets (from previous location) */ + for (a= 0; a < me->totvert; a++) { + VECSUB(ofs[a], vertCos[a], ofs[a]); + } + + /* apply offsets on other keys */ + currkey = me->key->block.first; + while (currkey) { + int apply_offset = ((currkey != kb) && (ob->shapenr-1 == currkey->relative)); + + if (apply_offset) + offset_to_key(ob, currkey, ofs); + + currkey= currkey->next; + } + + MEM_freeN(ofs); + } + + /* modifying of basis key should update mesh */ + if (kb == me->key->refkey) { + MVert *mvert= me->mvert; + + for (a= 0; a < me->totvert; a++, mvert++) + VECCOPY(mvert->co, vertCos[a]); + + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + } + + /* apply new coords on active key block */ + vertcos_to_key(ob, kb, vertCos); +} + /* copy the modified vertices from bvh to the active key */ static void sculpt_update_keyblock(SculptSession *ss) { float (*vertCos)[3]= BLI_pbvh_get_vertCos(ss->pbvh); if (vertCos) { - vertcos_to_key(ss->ob, ss->kb, vertCos); + sculpt_vertcos_to_key(ss->ob, ss->kb, vertCos); MEM_freeN(vertCos); } } |