diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_mesh.py | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 121 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 43 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_shapekey.c | 2 |
5 files changed, 129 insertions, 49 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 2fc949f4aae..80b9b773d9b 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -58,7 +58,12 @@ class MESH_MT_shape_key_context_menu(Menu): layout.operator("object.join_shapes") layout.operator("object.shape_key_transfer") layout.separator() - layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys").all = True + op = layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys") + op.all = True + op.apply_mix = False + op = layout.operator("object.shape_key_remove", text="Apply All Shape Keys") + op.all = True + op.apply_mix = True layout.separator() layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP' layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM' diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 676ac6fe37b..37b30d63722 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -46,8 +46,11 @@ void key_curve_normal_weights(float t, float data[4], int type); /** * Returns key coordinates (+ tilt) when key applied, NULL otherwise. + * + * \param obdata if given, also update that geometry with the result of the shape keys evaluation. */ -float *BKE_key_evaluate_object_ex(struct Object *ob, int *r_totelem, float *arr, size_t arr_size); +float *BKE_key_evaluate_object_ex( + struct Object *ob, int *r_totelem, float *arr, size_t arr_size, struct ID *obdata); float *BKE_key_evaluate_object(struct Object *ob, int *r_totelem); /** diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 97eac0b9f91..7ef15912567 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1501,7 +1501,14 @@ static void do_latt_key(Object *ob, Key *key, char *out, const int tot) } } -float *BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t arr_size) +static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert); +static void keyblock_data_convert_to_lattice(const float (*fp)[3], + BPoint *bpoint, + const int totpoint); +static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, const int totpoint); + +float *BKE_key_evaluate_object_ex( + Object *ob, int *r_totelem, float *arr, size_t arr_size, ID *obdata) { Key *key = BKE_key_from_object(ob); KeyBlock *actkb = BKE_keyblock_from_object(ob); @@ -1576,7 +1583,6 @@ float *BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t } } else { - if (ob->type == OB_MESH) { do_mesh_key(ob, key, out, tot); } @@ -1591,6 +1597,31 @@ float *BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t } } + if (obdata != NULL) { + switch (GS(obdata->name)) { + case ID_ME: { + Mesh *mesh = (Mesh *)obdata; + const int totvert = min_ii(tot, mesh->totvert); + keyblock_data_convert_to_mesh((const float(*)[3])out, mesh->mvert, totvert); + break; + } + case ID_LT: { + Lattice *lattice = (Lattice *)obdata; + const int totpoint = min_ii(tot, lattice->pntsu * lattice->pntsv * lattice->pntsw); + keyblock_data_convert_to_lattice((const float(*)[3])out, lattice->def, totpoint); + break; + } + case ID_CU_LEGACY: { + Curve *curve = (Curve *)obdata; + const int totpoint = min_ii(tot, BKE_keyblock_curve_element_count(&curve->nurb)); + keyblock_data_convert_to_curve((const float *)out, &curve->nurb, totpoint); + break; + } + default: + BLI_assert_unreachable(); + } + } + if (r_totelem) { *r_totelem = tot; } @@ -1599,7 +1630,7 @@ float *BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t float *BKE_key_evaluate_object(Object *ob, int *r_totelem) { - return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0); + return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0, NULL); } int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index) @@ -1971,21 +2002,22 @@ void BKE_keyblock_convert_from_lattice(const Lattice *lt, KeyBlock *kb) BKE_keyblock_update_from_lattice(lt, kb); } -void BKE_keyblock_convert_to_lattice(const KeyBlock *kb, Lattice *lt) +static void keyblock_data_convert_to_lattice(const float (*fp)[3], + BPoint *bpoint, + const int totpoint) { - BPoint *bp; - const float(*fp)[3]; - int a, tot; - - bp = lt->def; - fp = kb->data; + for (int i = 0; i < totpoint; i++, fp++, bpoint++) { + copy_v3_v3(bpoint->vec, *fp); + } +} - tot = lt->pntsu * lt->pntsv * lt->pntsw; - tot = min_ii(kb->totelem, tot); +void BKE_keyblock_convert_to_lattice(const KeyBlock *kb, Lattice *lt) +{ + BPoint *bp = lt->def; + const float(*fp)[3] = kb->data; + const int tot = min_ii(kb->totelem, lt->pntsu * lt->pntsv * lt->pntsw); - for (a = 0; a < tot; a++, fp++, bp++) { - copy_v3_v3(bp->vec, *fp); - } + keyblock_data_convert_to_lattice(fp, bp, tot); } /************************* Curve ************************/ @@ -2097,42 +2129,40 @@ void BKE_keyblock_convert_from_curve(const Curve *cu, KeyBlock *kb, const ListBa BKE_keyblock_update_from_curve(cu, kb, nurb); } -void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, int totpoint) { - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - const float *fp; - int a, tot; - - tot = BKE_keyblock_curve_element_count(nurb); - tot = min_ii(kb->totelem, tot); - - fp = kb->data; - for (nu = nurb->first; nu && tot > 0; nu = nu->next) { - if (nu->bezt) { - for (a = nu->pntsu, bezt = nu->bezt; a && (tot -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0; - a--, bezt++) { - for (int i = 0; i < 3; i++) { - copy_v3_v3(bezt->vec[i], &fp[i * 3]); + for (Nurb *nu = nurb->first; nu && totpoint > 0; nu = nu->next) { + if (nu->bezt != NULL) { + BezTriple *bezt = nu->bezt; + for (int i = nu->pntsu; i && (totpoint -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0; + i--, bezt++, fp += KEYELEM_FLOAT_LEN_BEZTRIPLE) { + for (int j = 0; j < 3; j++) { + copy_v3_v3(bezt->vec[j], &fp[j * 3]); } bezt->tilt = fp[9]; bezt->radius = fp[10]; - fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; } } else { - for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a && (tot -= KEYELEM_ELEM_LEN_BPOINT) >= 0; - a--, bp++) { + BPoint *bp = nu->bp; + for (int i = nu->pntsu * nu->pntsv; i && (totpoint -= KEYELEM_ELEM_LEN_BPOINT) >= 0; + i--, bp++, fp += KEYELEM_FLOAT_LEN_BPOINT) { copy_v3_v3(bp->vec, fp); bp->tilt = fp[3]; bp->radius = fp[4]; - fp += KEYELEM_FLOAT_LEN_BPOINT; } } } } +void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +{ + const float *fp = kb->data; + const int tot = min_ii(kb->totelem, BKE_keyblock_curve_element_count(nurb)); + + keyblock_data_convert_to_curve(fp, nurb, tot); +} + /************************* Mesh ************************/ void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb) @@ -2171,20 +2201,21 @@ void BKE_keyblock_convert_from_mesh(const Mesh *me, const Key *key, KeyBlock *kb BKE_keyblock_update_from_mesh(me, kb); } -void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, MVert *mvert, const int totvert) +static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert) { - const float(*fp)[3]; - int a, tot; - - fp = kb->data; - - tot = min_ii(kb->totelem, totvert); - - for (a = 0; a < tot; a++, fp++, mvert++) { + for (int i = 0; i < totvert; i++, fp++, mvert++) { copy_v3_v3(mvert->co, *fp); } } +void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, MVert *mvert, const int totvert) +{ + const float(*fp)[3] = kb->data; + const int tot = min_ii(kb->totelem, totvert); + + keyblock_data_convert_to_mesh(fp, mvert, tot); +} + void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, const Mesh *mesh, float (*r_vertnors)[3], diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index ebcf8573ccd..7d8c04d4d18 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -20,6 +20,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + #include "DNA_key_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -299,6 +301,10 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op) bool changed = false; if (RNA_boolean_get(op->ptr, "all")) { + if (RNA_boolean_get(op->ptr, "apply_mix")) { + float *arr = BKE_key_evaluate_object_ex(ob, NULL, NULL, 0, ob->data); + MEM_freeN(arr); + } changed = BKE_object_shapekey_free(bmain, ob); } else { @@ -315,6 +321,34 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } +static bool shape_key_remove_poll_property(const bContext *C, + wmOperator *op, + const PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + const bool do_all = RNA_enum_get(op->ptr, "all"); + + /* Only show seed for randomize action! */ + if (STREQ(prop_id, "apply_mix") && !do_all) { + return false; + } + return true; +} + +static char *shape_key_remove_get_description(bContext *UNUSED(C), + wmOperatorType *UNUSED(ot), + PointerRNA *ptr) +{ + const bool do_apply_mix = RNA_boolean_get(ptr, "apply_mix"); + + if (do_apply_mix) { + return BLI_strdup( + TIP_("Apply current visible shape to the object data, and delete all shape keys")); + } + + return NULL; +} + void OBJECT_OT_shape_key_remove(wmOperatorType *ot) { /* identifiers */ @@ -325,12 +359,19 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot) /* api callbacks */ ot->poll = shape_key_mode_exists_poll; ot->exec = shape_key_remove_exec; + ot->poll_property = shape_key_remove_poll_property; + ot->get_description = shape_key_remove_get_description; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "all", 0, "All", "Remove all shape keys"); + RNA_def_boolean(ot->srna, "all", false, "All", "Remove all shape keys"); + RNA_def_boolean(ot->srna, + "apply_mix", + false, + "Apply Mix", + "Apply current mix of shape keys to the geometry before removing them"); } /** \} */ diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index cc214c1147a..56dd1fc50f8 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -36,7 +36,7 @@ static void deformVerts(ModifierData *UNUSED(md), if (key && key->block.first) { int deformedVerts_tot; BKE_key_evaluate_object_ex( - ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * verts_num); + ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * verts_num, NULL); } } |