Sculpt+shape keys:
- Sculpting on the basis key should change original mesh - For relative keys sculpting on basis key should update others
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user