RNA: Object.shape_key_remove method
Python had no ability to remove shape keys Original D1169 from @lichtwerk, with edits
This commit is contained in:
parent
546a0e2d96
commit
87629b2a74
|
@ -65,6 +65,7 @@ float *BKE_key_evaluate_object_ex(
|
|||
float *BKE_key_evaluate_object(
|
||||
struct Object *ob, int *r_totelem);
|
||||
|
||||
struct Key **BKE_key_from_object_p(struct Object *ob);
|
||||
struct Key *BKE_key_from_object(struct Object *ob);
|
||||
struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
|
||||
struct KeyBlock *BKE_keyblock_from_object_reference(struct Object *ob);
|
||||
|
|
|
@ -217,7 +217,9 @@ int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float *
|
|||
|
||||
int BKE_object_insert_ptcache(struct Object *ob);
|
||||
void BKE_object_delete_ptcache(struct Object *ob, int index);
|
||||
struct KeyBlock *BKE_object_insert_shape_key(struct Object *ob, const char *name, const bool from_mix);
|
||||
struct KeyBlock *BKE_object_shapekey_insert(struct Object *ob, const char *name, const bool from_mix);
|
||||
bool BKE_object_shapekey_remove(struct Main *bmain, struct Object *ob, struct KeyBlock *kb);
|
||||
bool BKE_object_shapekey_free(struct Main *bmain, struct Object *ob);
|
||||
|
||||
bool BKE_object_flag_test_recursive(const struct Object *ob, short flag);
|
||||
|
||||
|
|
|
@ -1392,25 +1392,37 @@ float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
|
|||
return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0);
|
||||
}
|
||||
|
||||
Key *BKE_key_from_object(Object *ob)
|
||||
Key **BKE_key_from_object_p(Object *ob)
|
||||
{
|
||||
if (ob == NULL) return NULL;
|
||||
|
||||
if (ob == NULL)
|
||||
return NULL;
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = ob->data;
|
||||
return me->key;
|
||||
return &me->key;
|
||||
}
|
||||
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
|
||||
Curve *cu = ob->data;
|
||||
return cu->key;
|
||||
return &cu->key;
|
||||
}
|
||||
else if (ob->type == OB_LATTICE) {
|
||||
Lattice *lt = ob->data;
|
||||
return lt->key;
|
||||
return <->key;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *BKE_key_from_object(Object *ob)
|
||||
{
|
||||
Key **key_p;
|
||||
key_p = BKE_key_from_object_p(ob);
|
||||
if (key_p) {
|
||||
return *key_p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeyBlock *BKE_keyblock_add(Key *key, const char *name)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
|
|
|
@ -3358,7 +3358,7 @@ static KeyBlock *insert_curvekey(Object *ob, const char *name, const bool from_m
|
|||
return kb;
|
||||
}
|
||||
|
||||
KeyBlock *BKE_object_insert_shape_key(Object *ob, const char *name, const bool from_mix)
|
||||
KeyBlock *BKE_object_shapekey_insert(Object *ob, const char *name, const bool from_mix)
|
||||
{
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
|
@ -3374,6 +3374,85 @@ KeyBlock *BKE_object_insert_shape_key(Object *ob, const char *name, const bool f
|
|||
|
||||
}
|
||||
|
||||
bool BKE_object_shapekey_free(Main *bmain, Object *ob)
|
||||
{
|
||||
Key **key_p, *key;
|
||||
|
||||
key_p = BKE_key_from_object_p(ob);
|
||||
if (ELEM(NULL, key_p, *key_p)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
key = *key_p;
|
||||
*key_p = NULL;
|
||||
|
||||
BKE_libblock_free_us(bmain, key);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
|
||||
{
|
||||
KeyBlock *rkb;
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
short kb_index;
|
||||
|
||||
if (key == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
kb_index = BLI_findindex(&key->block, kb);
|
||||
BLI_assert(kb_index != -1);
|
||||
|
||||
for (rkb = key->block.first; rkb; rkb = rkb->next) {
|
||||
if (rkb->relative == kb_index) {
|
||||
/* remap to the 'Basis' */
|
||||
rkb->relative = 0;
|
||||
}
|
||||
else if (rkb->relative >= kb_index) {
|
||||
/* Fix positional shift of the keys when kb is deleted from the list */
|
||||
rkb->relative -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_remlink(&key->block, kb);
|
||||
key->totkey--;
|
||||
if (key->refkey == kb) {
|
||||
key->refkey = key->block.first;
|
||||
|
||||
if (key->refkey) {
|
||||
/* apply new basis key on original data */
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
BKE_keyblock_convert_to_mesh(key->refkey, ob->data);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
BKE_keyblock_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data));
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
BKE_keyblock_convert_to_lattice(key->refkey, ob->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kb->data) {
|
||||
MEM_freeN(kb->data);
|
||||
}
|
||||
MEM_freeN(kb);
|
||||
|
||||
if (ob->shapenr > 1) {
|
||||
ob->shapenr--;
|
||||
}
|
||||
|
||||
if (key->totkey == 0) {
|
||||
BKE_object_shapekey_free(bmain, ob);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BKE_object_flag_test_recursive(const Object *ob, short flag)
|
||||
{
|
||||
if (ob->flag & flag) {
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
if ((kb = BKE_object_insert_shape_key(ob, NULL, from_mix))) {
|
||||
if ((kb = BKE_object_shapekey_insert(ob, NULL, from_mix))) {
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
/* for absolute shape keys, new keys may not be added last */
|
||||
ob->shapenr = BLI_findindex(&key->block, kb) + 1;
|
||||
|
@ -88,89 +88,21 @@ static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix
|
|||
|
||||
/*********************** remove shape key ***********************/
|
||||
|
||||
static bool ED_object_shape_key_remove_all(Main *bmain, Object *ob)
|
||||
static bool object_shapekey_remove(Main *bmain, Object *ob)
|
||||
{
|
||||
Key *key;
|
||||
KeyBlock *kb;
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
|
||||
key = BKE_key_from_object(ob);
|
||||
if (key == NULL)
|
||||
if (key == NULL) {
|
||||
return false;
|
||||
|
||||
switch (GS(key->from->name)) {
|
||||
case ID_ME: ((Mesh *)key->from)->key = NULL; break;
|
||||
case ID_CU: ((Curve *)key->from)->key = NULL; break;
|
||||
case ID_LT: ((Lattice *)key->from)->key = NULL; break;
|
||||
}
|
||||
|
||||
BKE_libblock_free_us(bmain, key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ED_object_shape_key_remove(Main *bmain, Object *ob)
|
||||
{
|
||||
KeyBlock *kb, *rkb;
|
||||
Key *key;
|
||||
|
||||
key = BKE_key_from_object(ob);
|
||||
if (key == NULL)
|
||||
return false;
|
||||
|
||||
kb = BLI_findlink(&key->block, ob->shapenr - 1);
|
||||
|
||||
if (kb) {
|
||||
for (rkb = key->block.first; rkb; rkb = rkb->next) {
|
||||
if (rkb->relative == ob->shapenr - 1) {
|
||||
/* remap to the 'Basis' */
|
||||
rkb->relative = 0;
|
||||
}
|
||||
else if (rkb->relative >= ob->shapenr) {
|
||||
/* Fix positional shift of the keys when kb is deleted from the list */
|
||||
rkb->relative -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_remlink(&key->block, kb);
|
||||
key->totkey--;
|
||||
if (key->refkey == kb) {
|
||||
key->refkey = key->block.first;
|
||||
|
||||
if (key->refkey) {
|
||||
/* apply new basis key on original data */
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
BKE_keyblock_convert_to_mesh(key->refkey, ob->data);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
BKE_keyblock_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data));
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
BKE_keyblock_convert_to_lattice(key->refkey, ob->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kb->data) MEM_freeN(kb->data);
|
||||
MEM_freeN(kb);
|
||||
|
||||
if (ob->shapenr > 1) {
|
||||
ob->shapenr--;
|
||||
}
|
||||
}
|
||||
|
||||
if (key->totkey == 0) {
|
||||
switch (GS(key->from->name)) {
|
||||
case ID_ME: ((Mesh *)key->from)->key = NULL; break;
|
||||
case ID_CU: ((Curve *)key->from)->key = NULL; break;
|
||||
case ID_LT: ((Lattice *)key->from)->key = NULL; break;
|
||||
}
|
||||
|
||||
BKE_libblock_free_us(bmain, key);
|
||||
return BKE_object_shapekey_remove(bmain, ob, kb);
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool object_shape_key_mirror(bContext *C, Object *ob,
|
||||
|
@ -361,10 +293,10 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op)
|
|||
bool changed = false;
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "all")) {
|
||||
changed = ED_object_shape_key_remove_all(bmain, ob);
|
||||
changed = BKE_object_shapekey_free(bmain, ob);
|
||||
}
|
||||
else {
|
||||
changed = ED_object_shape_key_remove(bmain, ob);
|
||||
changed = object_shapekey_remove(bmain, ob);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
|
|
|
@ -229,7 +229,7 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *
|
|||
{
|
||||
KeyBlock *kb = NULL;
|
||||
|
||||
if ((kb = BKE_object_insert_shape_key(ob, name, from_mix))) {
|
||||
if ((kb = BKE_object_shapekey_insert(ob, name, from_mix))) {
|
||||
PointerRNA keyptr;
|
||||
|
||||
RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
|
||||
|
@ -243,6 +243,29 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_Object_shape_key_remove(
|
||||
Object *ob, Main *bmain, ReportList *reports,
|
||||
PointerRNA *kb_ptr)
|
||||
{
|
||||
KeyBlock *kb = kb_ptr->data;
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
|
||||
if ((key == NULL) || BLI_findindex(&key->block, kb) == -1) {
|
||||
BKE_reportf(reports, RPT_ERROR, "ShapeKey not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BKE_object_shapekey_remove(bmain, ob, kb)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Could not remove ShapeKey");
|
||||
return;
|
||||
}
|
||||
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
|
||||
RNA_POINTER_INVALIDATE(kb_ptr);
|
||||
}
|
||||
|
||||
static int rna_Object_is_visible(Object *ob, Scene *sce)
|
||||
{
|
||||
return !(ob->restrictflag & OB_RESTRICT_VIEW) && (ob->lay & sce->lay);
|
||||
|
@ -557,7 +580,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
|
||||
/* Shape key */
|
||||
func = RNA_def_function(srna, "shape_key_add", "rna_Object_shape_key_add");
|
||||
RNA_def_function_ui_description(func, "Add shape key to an object");
|
||||
RNA_def_function_ui_description(func, "Add shape key to this object");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_string(func, "name", "Key", 0, "", "Unique name for the new keyblock"); /* optional */
|
||||
RNA_def_boolean(func, "from_mix", 1, "", "Create new shape from existing mix of shapes");
|
||||
|
@ -565,6 +588,13 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "shape_key_remove", "rna_Object_shape_key_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a Shape Key from this object");
|
||||
RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "key", "ShapeKey", "", "Keyblock to be removed");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
/* Ray Cast */
|
||||
func = RNA_def_function(srna, "ray_cast", "rna_Object_ray_cast");
|
||||
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
|
||||
|
|
Loading…
Reference in New Issue