Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/key.c
| Show First 20 Lines • Show All 806 Lines • ▼ Show 20 Lines | static void key_evaluate_relative(const int start, | ||||
| elemsize = key->elemsize * step; | elemsize = key->elemsize * step; | ||||
| /* step 1 init */ | /* step 1 init */ | ||||
| cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode); | cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode); | ||||
| /* step 2: do it */ | /* step 2: do it */ | ||||
| for (kb = key->block.first, keyblock_index = 0; kb; kb = kb->next, keyblock_index++) { | for (kb = key->block.first, keyblock_index = 0; kb; kb = kb->next, keyblock_index++) { | ||||
| if (kb != key->refkey) { | bool is_edit_mesh_basis = false; | ||||
| float icuval = kb->curval; | if (kb == key->refkey) { | ||||
| /* `is_edit_mesh_basis` is a hack that makes possible to edit shape keys | |||||
| * in edit mode with shape keys blending applied. | |||||
| * Similar to the hack in `key_block_get_data`. */ | |||||
| is_edit_mesh_basis = GS(key->from->name) == ID_ME && ((Mesh *)key->from)->edit_mesh; | |||||
| if (!is_edit_mesh_basis) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| float icuval = is_edit_mesh_basis ? 1.0f : kb->curval; | |||||
| /* only with value, and no difference allowed */ | /* only with value, and no difference allowed */ | ||||
| if (!(kb->flag & KEYBLOCK_MUTE) && icuval != 0.0f && kb->totelem == tot) { | if ((kb->flag & KEYBLOCK_MUTE) || icuval == 0.0f || kb->totelem != tot) { | ||||
| KeyBlock *refb; | continue; | ||||
| float weight, | } | ||||
| *weights = per_keyblock_weights ? per_keyblock_weights[keyblock_index] : NULL; | |||||
| char *freefrom = NULL, *freereffrom = NULL; | |||||
| /* reference now can be any block */ | /* reference now can be any block */ | ||||
| refb = BLI_findlink(&key->block, kb->relative); | KeyBlock *refb = BLI_findlink(&key->block, kb->relative); | ||||
| if (refb == NULL) { | if (refb == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| float weight, *weights = per_keyblock_weights ? per_keyblock_weights[keyblock_index] : NULL; | |||||
| char *freefrom = NULL, *freereffrom = NULL; | |||||
| poin = basispoin; | poin = basispoin; | ||||
| from = key_block_get_data(key, actkb, kb, &freefrom); | from = key_block_get_data(key, actkb, kb, &freefrom); | ||||
| if (is_edit_mesh_basis) { | |||||
| reffrom = kb->data; | |||||
| } | |||||
| else { | |||||
| reffrom = key_block_get_data(key, actkb, refb, &freereffrom); | reffrom = key_block_get_data(key, actkb, refb, &freereffrom); | ||||
| } | |||||
| poin += start * poinsize; | poin += start * poinsize; | ||||
| reffrom += key->elemsize * start; // key elemsize yes! | reffrom += key->elemsize * start; // key elemsize yes! | ||||
| from += key->elemsize * start; | from += key->elemsize * start; | ||||
| for (b = start; b < end; b += step) { | for (b = start; b < end; b += step) { | ||||
| weight = weights ? (*weights * icuval) : icuval; | weight = weights ? (*weights * icuval) : icuval; | ||||
| cp = key->elemstr; | cp = key->elemstr; | ||||
| if (mode == KEY_MODE_BEZTRIPLE) { | if (mode == KEY_MODE_BEZTRIPLE) { | ||||
| cp = elemstr; | cp = elemstr; | ||||
| } | } | ||||
| ofsp = ofs; | ofsp = ofs; | ||||
| while (cp[0]) { /* (cp[0] == amount) */ | while (cp[0]) { /* (cp[0] == amount) */ | ||||
| switch (cp[1]) { | switch (cp[1]) { | ||||
| case IPO_FLOAT: | case IPO_FLOAT: | ||||
| rel_flerp(KEYELEM_FLOAT_LEN_COORD, | rel_flerp( | ||||
| (float *)poin, | KEYELEM_FLOAT_LEN_COORD, (float *)poin, (float *)reffrom, (float *)from, weight); | ||||
| (float *)reffrom, | |||||
| (float *)from, | |||||
| weight); | |||||
| break; | break; | ||||
| case IPO_BPOINT: | case IPO_BPOINT: | ||||
| rel_flerp(KEYELEM_FLOAT_LEN_BPOINT, | rel_flerp( | ||||
| (float *)poin, | KEYELEM_FLOAT_LEN_BPOINT, (float *)poin, (float *)reffrom, (float *)from, weight); | ||||
| (float *)reffrom, | |||||
| (float *)from, | |||||
| weight); | |||||
| break; | break; | ||||
| case IPO_BEZTRIPLE: | case IPO_BEZTRIPLE: | ||||
| rel_flerp(KEYELEM_FLOAT_LEN_BEZTRIPLE, | rel_flerp(KEYELEM_FLOAT_LEN_BEZTRIPLE, | ||||
| (float *)poin, | (float *)poin, | ||||
| (float *)reffrom, | (float *)reffrom, | ||||
| (float *)from, | (float *)from, | ||||
| weight); | weight); | ||||
| break; | break; | ||||
| default: | default: | ||||
| /* should never happen */ | /* should never happen */ | ||||
| if (freefrom) { | if (freefrom) { | ||||
| MEM_freeN(freefrom); | MEM_freeN(freefrom); | ||||
| } | } | ||||
| if (freereffrom) { | if (freereffrom) { | ||||
| MEM_freeN(freereffrom); | MEM_freeN(freereffrom); | ||||
| } | } | ||||
| BLI_assert(!"invalid 'cp[1]'"); | BLI_assert(!"invalid 'cp[1]'"); | ||||
| return; | return; | ||||
| } | } | ||||
| poin += *ofsp; | poin += *ofsp; | ||||
| cp += 2; | cp += 2; | ||||
| ofsp++; | ofsp++; | ||||
| } | } | ||||
| reffrom += elemsize; | reffrom += elemsize; | ||||
| from += elemsize; | from += elemsize; | ||||
| if (weights) { | if (weights) { | ||||
| weights++; | weights++; | ||||
| } | } | ||||
| } | } | ||||
| if (freefrom) { | if (freefrom) { | ||||
| MEM_freeN(freefrom); | MEM_freeN(freefrom); | ||||
| } | } | ||||
| if (freereffrom) { | if (freereffrom) { | ||||
| MEM_freeN(freereffrom); | MEM_freeN(freereffrom); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| static void do_key(const int start, | static void do_key(const int start, | ||||
| int end, | int end, | ||||
| const int tot, | const int tot, | ||||
| char *poin, | char *poin, | ||||
| Key *key, | Key *key, | ||||
| KeyBlock *actkb, | KeyBlock *actkb, | ||||
| KeyBlock **k, | KeyBlock **k, | ||||
| ▲ Show 20 Lines • Show All 1,446 Lines • Show Last 20 Lines | |||||