diff options
Diffstat (limited to 'source/blender/blenkernel/intern/key.c')
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 481 |
1 files changed, 287 insertions, 194 deletions
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 2dc615c19f9..3ba0c6e5ffa 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1086,7 +1086,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac if (cache) { if (cache->defgroup_weights == NULL) { - int num_defgroup = BLI_countlist(&ob->defbase); + int num_defgroup = BLI_listbase_count(&ob->defbase); cache->defgroup_weights = MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup, "cached defgroup weights"); @@ -1518,7 +1518,7 @@ KeyBlock *BKE_keyblock_add(Key *key, const char *name) BLI_addtail(&key->block, kb); kb->type = KEY_CARDINAL; - tot = BLI_countlist(&key->block); + tot = BLI_listbase_count(&key->block); if (name) { BLI_strncpy(kb->name, name, sizeof(kb->name)); } @@ -1669,31 +1669,43 @@ char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb) /* conversion functions */ /************************* Lattice ************************/ -void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb) +void BKE_keyblock_update_from_lattice(Lattice *lt, KeyBlock *kb) { BPoint *bp; - float *fp; + float (*fp)[3]; int a, tot; + BLI_assert(kb->totelem == lt->pntsu * lt->pntsv * lt->pntsw); + + tot = kb->totelem; + if (tot == 0) return; + + bp = lt->def; + fp = kb->data; + for (a = 0; a < kb->totelem; a++, fp++, bp++) { + copy_v3_v3(*fp, bp->vec); + } +} + +void BKE_keyblock_convert_from_lattice(Lattice *lt, KeyBlock *kb) +{ + int tot; + tot = lt->pntsu * lt->pntsv * lt->pntsw; if (tot == 0) return; - if (kb->data) MEM_freeN(kb->data); + MEM_SAFE_FREE(kb->data); - kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data"); + kb->data = MEM_mallocN(lt->key->elemsize * tot, __func__); kb->totelem = tot; - bp = lt->def; - fp = kb->data; - for (a = 0; a < kb->totelem; a++, fp += 3, bp++) { - copy_v3_v3(fp, bp->vec); - } + BKE_keyblock_update_from_lattice(lt, kb); } -void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt) +void BKE_keyblock_convert_to_lattice(KeyBlock *kb, Lattice *lt) { BPoint *bp; - const float *fp; + const float (*fp)[3]; int a, tot; bp = lt->def; @@ -1702,13 +1714,13 @@ void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt) tot = lt->pntsu * lt->pntsv * lt->pntsw; tot = min_ii(kb->totelem, tot); - for (a = 0; a < tot; a++, fp += 3, bp++) { - copy_v3_v3(bp->vec, fp); + for (a = 0; a < tot; a++, fp++, bp++) { + copy_v3_v3(bp->vec, *fp); } } /************************* Curve ************************/ -void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) +void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1717,49 +1729,52 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) int a, tot; /* count */ - tot = BKE_nurbList_verts_count(nurb); - if (tot == 0) return; - - if (kb->data) MEM_freeN(kb->data); + BLI_assert(BKE_nurbList_verts_count(nurb) == kb->totelem); - kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data"); - kb->totelem = tot; + tot = kb->totelem; + if (tot == 0) return; - nu = nurb->first; fp = kb->data; - while (nu) { - + for (nu = nurb->first; nu; nu = nu->next) { if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - copy_v3_v3(fp, bezt->vec[0]); - fp += 3; - copy_v3_v3(fp, bezt->vec[1]); - fp += 3; - copy_v3_v3(fp, bezt->vec[2]); - fp += 3; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; + + for (i = 0; i < 3; i++, fp += 3) { + copy_v3_v3(fp, bezt->vec[i]); + } fp[0] = bezt->alfa; fp += 3; /* alphas */ - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { + + ; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, fp += 4, bp++) { copy_v3_v3(fp, bp->vec); fp[3] = bp->alfa; - - fp += 4; - bp++; } } - nu = nu->next; } } -void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) +{ + int tot; + + /* count */ + tot = BKE_nurbList_verts_count(nurb); + if (tot == 0) return; + + MEM_SAFE_FREE(kb->data); + + kb->data = MEM_mallocN(cu->key->elemsize * tot, __func__); + kb->totelem = tot; + + BKE_keyblock_update_from_curve(cu, kb, nurb); +} + +void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1767,74 +1782,68 @@ void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) const float *fp; int a, tot; - nu = nurb->first; - fp = kb->data; - tot = BKE_nurbList_verts_count(nurb); - tot = min_ii(kb->totelem, tot); - while (nu && tot > 0) { - + fp = kb->data; + for (nu = nurb->first; nu && tot > 0; nu = nu->next) { if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - while (a-- && tot > 0) { - copy_v3_v3(bezt->vec[0], fp); - fp += 3; - copy_v3_v3(bezt->vec[1], fp); - fp += 3; - copy_v3_v3(bezt->vec[2], fp); - fp += 3; + for (a = nu->pntsu, bezt = nu->bezt; a && tot > 0; a--, tot -= 3, bezt++) { + int i; + + for (i = 0; i < 3; i++, fp += 3) { + copy_v3_v3(bezt->vec[i], fp); + } bezt->alfa = fp[0]; fp += 3; /* alphas */ - - tot -= 3; - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a-- && tot > 0) { + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a && tot; a--, tot--, fp += 4, bp++) { copy_v3_v3(bp->vec, fp); bp->alfa = fp[3]; - - fp += 4; - tot--; - bp++; } } - nu = nu->next; } } /************************* Mesh ************************/ -void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb) +void BKE_keyblock_update_from_mesh(Mesh *me, KeyBlock *kb) { MVert *mvert; - float *fp; - int a; - - if (me->totvert == 0) return; + float (*fp)[3]; + int a, tot; - if (kb->data) MEM_freeN(kb->data); + BLI_assert(me->totvert == kb->totelem); - kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data"); - kb->totelem = me->totvert; + tot = me->totvert; + if (tot == 0) return; mvert = me->mvert; fp = kb->data; - for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) { - copy_v3_v3(fp, mvert->co); - + for (a = 0; a < tot; a++, fp++, mvert++) { + copy_v3_v3(*fp, mvert->co); } } -void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me) +void BKE_keyblock_convert_from_mesh(Mesh *me, KeyBlock *kb) +{ + int tot = me->totvert; + + if (me->totvert == 0) return; + + MEM_SAFE_FREE(kb->data); + + kb->data = MEM_mallocN(me->key->elemsize * tot, __func__); + kb->totelem = tot; + + BKE_keyblock_update_from_mesh(me, kb); +} + +void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me) { MVert *mvert; - const float *fp; + const float (*fp)[3]; int a, tot; mvert = me->mvert; @@ -1842,94 +1851,76 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me) tot = min_ii(kb->totelem, me->totvert); - for (a = 0; a < tot; a++, fp += 3, mvert++) { - copy_v3_v3(mvert->co, fp); + for (a = 0; a < tot; a++, fp++, mvert++) { + copy_v3_v3(mvert->co, *fp); } } -/************************* vert coords ************************/ -float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3] +/************************* raw coords ************************/ +void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { - float (*vertCos)[3], *co; - const float *fp = kb->data; - int tot = 0, a; + float (*co)[3] = vertCos; + float *fp = kb->data; + int tot, 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; +#ifndef NDEBUG + if (ob->type == OB_LATTICE) { + Lattice *lt = ob->data; + BLI_assert((lt->pntsu * lt->pntsv * lt->pntsw) == kb->totelem); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - Curve *cu = (Curve *)ob->data; - tot = BKE_nurbList_verts_count(&cu->nurb); + Curve *cu = ob->data; + BLI_assert(BKE_nurbList_verts_count(&cu->nurb) == kb->totelem); } + else if (ob->type == OB_MESH) { + Mesh *me = ob->data; + BLI_assert(me->totvert == kb->totelem); + } + else { + BLI_assert(0 == kb->totelem); + } +#endif - if (tot == 0) return NULL; - - vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos"); - - /* Copy coords to array */ - co = (float *)vertCos; + tot = kb->totelem; + 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(co, fp); + for (a = 0; a < tot; a++, fp += 3, co++) { + copy_v3_v3(fp, *co); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - copy_v3_v3(co, fp); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, co++) { + copy_v3_v3(fp, *co); } - 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++; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) { + copy_v3_v3(fp, *co); } } - - nu = nu->next; } } - - return vertCos; } -void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) +void BKE_keyblock_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { - float *co = (float *)vertCos, *fp; - int tot = 0, a, elemsize; + int tot = 0, elemsize; - if (kb->data) MEM_freeN(kb->data); + MEM_SAFE_FREE(kb->data); /* Count of vertex coords in array */ if (ob->type == OB_MESH) { @@ -1948,110 +1939,212 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) tot = BKE_nurbList_verts_count(&cu->nurb); } - if (tot == 0) { - kb->data = NULL; - return; - } + if (tot == 0) return; - fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos"); + kb->data = MEM_mallocN(tot * elemsize, __func__); /* Copy coords to keyblock */ + BKE_keyblock_update_from_vertcos(ob, kb, vertCos); +} + +float (*BKE_keyblock_convert_to_vertcos(Object *ob, KeyBlock *kb))[3] +{ + float (*vertCos)[3], (*co)[3]; + const 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 = BKE_nurbList_verts_count(&cu->nurb); + } + + if (tot == 0) return NULL; + + co = vertCos = MEM_mallocN(tot * sizeof(*vertCos), __func__); + /* Copy coords to array */ if (ELEM(ob->type, OB_MESH, OB_LATTICE)) { - for (a = 0; a < tot; a++, fp += 3, co += 3) { - copy_v3_v3(fp, co); + for (a = 0; a < tot; a++, fp += 3, co++) { + copy_v3_v3(*co, fp); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - copy_v3_v3(fp, co); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, co++) { + copy_v3_v3(*co, fp); } - 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++; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) { + copy_v3_v3(*co, fp); } } - - nu = nu->next; } } + + return vertCos; } -void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3]) +/************************* raw coord offsets ************************/ +void BKE_keyblock_update_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3]) { int a; - float *co = (float *)ofs, *fp = kb->data; + float *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); + for (a = 0; a < kb->totelem; a++, fp += 3, ofs++) { + add_v3_v3(fp, *ofs); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = (Curve *)ob->data; - Nurb *nu = cu->nurb.first; + Nurb *nu; BezTriple *bezt; BPoint *bp; - while (nu) { + for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->bezt) { - int i; - bezt = nu->bezt; - a = nu->pntsu; + for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) { + int i; - while (a--) { - for (i = 0; i < 3; i++) { - add_v3_v3(fp, co); - fp += 3; co += 3; + for (i = 0; i < 3; i++, fp += 3, ofs++) { + add_v3_v3(fp, *ofs); } - fp += 3; /* skip alphas */ - - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, ofs++) { + add_v3_v3(fp, *ofs); + } + } + } + } +} - while (a--) { - add_v3_v3(fp, co); +/* ==========================================================*/ - fp += 4; - co += 3; +/** Move shape key from org_index to new_index. Safe, clamps index to valid range, updates reference keys, + * the object's active shape index, the 'frame' value in case of absolute keys, etc. + * Note indices are expected in real values (not 'fake' shapenr +1 ones). + * + * \param org_index if < 0, current object's active shape will be used as skey to move. + * \return true if something was done, else false. + */ +bool BKE_keyblock_move(Object *ob, int org_index, int new_index) +{ + Key *key = BKE_key_from_object(ob); + KeyBlock *kb; + const int act_index = ob->shapenr - 1; + const int totkey = key->totkey; + int i; + bool rev, in_range = false; - bp++; - } - } + if (org_index < 0) { + org_index = act_index; + } + + CLAMP(new_index, 0, key->totkey - 1); + CLAMP(org_index, 0, key->totkey - 1); + + if (new_index == org_index) { + return false; + } + + rev = ((new_index - org_index) < 0) ? true : false; + + /* We swap 'org' element with its previous/next neighbor (depending on direction of the move) repeatedly, + * until we reach final position. + * This allows us to only loop on the list once! */ + for (kb = (rev ? key->block.last : key->block.first), i = (rev ? totkey - 1 : 0); + kb; + kb = (rev ? kb->prev : kb->next), rev ? i-- : i++) + { + if (i == org_index) { + in_range = true; /* Start list items swapping... */ + } + else if (i == new_index) { + in_range = false; /* End list items swapping. */ + } + + if (in_range) { + KeyBlock *other_kb = rev ? kb->prev : kb->next; + + /* Swap with previous/next list item. */ + BLI_listbase_swaplinks(&key->block, kb, other_kb); + + /* Swap absolute positions. */ + SWAP(float, kb->pos, other_kb->pos); - nu = nu->next; + kb = other_kb; + } + + /* Adjust relative indices, this has to be done on the whole list! */ + if (kb->relative == org_index) { + kb->relative = new_index; + } + else if (kb->relative < org_index && kb->relative >= new_index) { + /* remove after, insert before this index */ + kb->relative++; + } + else if (kb->relative > org_index && kb->relative <= new_index) { + /* remove before, insert after this index */ + kb->relative--; + } + } + + /* Need to update active shape number if it's affected, same principle as for relative indices above. */ + if (org_index == act_index) { + ob->shapenr = new_index + 1; + } + else if (act_index < org_index && act_index >= new_index) { + ob->shapenr++; + } + else if (act_index > org_index && act_index <= new_index) { + ob->shapenr--; + } + + /* First key is always refkey, matches interface and BKE_key_sort */ + key->refkey = key->block.first; + + return true; +} + +/** + * Check if given keyblock (as index) is used as basis by others in given key. + */ +bool BKE_keyblock_is_basis(Key *key, const int index) +{ + KeyBlock *kb; + int i; + + if (key->type == KEY_RELATIVE) { + for (i = 0, kb = key->block.first; kb; i++, kb = kb->next) { + if ((i != index) && (kb->relative == index)) { + return true; + } } } + + return false; } |