diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_key.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_key.c | 297 |
1 files changed, 238 insertions, 59 deletions
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index 6170c884b51..5181912f4eb 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -35,6 +35,7 @@ #include "BLI_string_utils.h" #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BLT_translation.h" @@ -42,6 +43,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "MEM_guardedalloc.h" + #include "rna_internal.h" #ifdef RNA_RUNTIME @@ -51,10 +54,11 @@ #include "DNA_object_types.h" #include "BKE_animsys.h" -#include "BKE_depsgraph.h" #include "BKE_key.h" #include "BKE_main.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -335,6 +339,19 @@ static void rna_ShapeKeyCurvePoint_tilt_set(PointerRNA *ptr, float value) vec[3] = value; } +static float rna_ShapeKeyCurvePoint_radius_get(PointerRNA *ptr) +{ + float *vec = (float *)ptr->data; + return vec[4]; +} + +static void rna_ShapeKeyCurvePoint_radius_set(PointerRNA *ptr, float value) +{ + float *vec = (float *)ptr->data; + CLAMP_MIN(value, 0.0f); + vec[4] = value; +} + static void rna_ShapeKeyBezierPoint_co_get(PointerRNA *ptr, float *values) { float *vec = (float *)ptr->data; @@ -389,35 +406,166 @@ static void rna_ShapeKeyBezierPoint_handle_2_co_set(PointerRNA *ptr, const float vec[6 + 2] = values[2]; } -#if 0 static float rna_ShapeKeyBezierPoint_tilt_get(PointerRNA *ptr) { float *vec = (float *)ptr->data; - return vec[10]; + return vec[9]; } static void rna_ShapeKeyBezierPoint_tilt_set(PointerRNA *ptr, float value) { float *vec = (float *)ptr->data; + vec[9] = value; +} + +static float rna_ShapeKeyBezierPoint_radius_get(PointerRNA *ptr) +{ + float *vec = (float *)ptr->data; + return vec[10]; +} + +static void rna_ShapeKeyBezierPoint_radius_set(PointerRNA *ptr, float value) +{ + float *vec = (float *)ptr->data; + CLAMP_MIN(value, 0.0f); vec[10] = value; } -#endif + +/* Indexing and iteration of Curve points through sub-curves. */ +typedef struct NurbInfo { + Nurb *nu; + int nurb_size, nurb_elem_step; + + /* Current index in the Nurb */ + int nurb_index; + + /* Total index as item and element. */ + int item_index, elem_index; +} NurbInfo; + +StructRNA *rna_ShapeKey_curve_point_type(Nurb *nu) +{ + if (nu->bezt) { + return &RNA_ShapeKeyBezierPoint; + } + else { + return &RNA_ShapeKeyCurvePoint; + } +} + +static void rna_ShapeKey_NurbInfo_init(NurbInfo *r_info, Nurb *nu) +{ + r_info->nu = nu; + + if (nu->bezt) { + r_info->nurb_size = nu->pntsu; + r_info->nurb_elem_step = KEYELEM_ELEM_LEN_BEZTRIPLE; + } + else { + r_info->nurb_size = nu->pntsu * nu->pntsv; + r_info->nurb_elem_step = KEYELEM_ELEM_LEN_BPOINT; + } +} + +static void rna_ShapeKey_NurbInfo_step(NurbInfo *r_info, Nurb *nu, int *p_raw_index, bool input_elem) +{ + rna_ShapeKey_NurbInfo_init(r_info, nu); + + if (input_elem) { + r_info->nurb_index = MIN2(r_info->nurb_size, *p_raw_index / r_info->nurb_elem_step); + *p_raw_index -= r_info->nurb_size * r_info->nurb_elem_step; + } + else { + r_info->nurb_index = MIN2(r_info->nurb_size, *p_raw_index); + *p_raw_index -= r_info->nurb_size; + } + + r_info->item_index += r_info->nurb_index; + r_info->elem_index += r_info->nurb_index * r_info->nurb_elem_step; +} + +static void rna_ShapeKey_NurbInfo_find_index(Key *key, int raw_index, bool input_elem, NurbInfo *r_info) +{ + Curve *cu = (Curve *)key->from; + + memset(r_info, 0, sizeof(*r_info)); + + for (Nurb *nu = cu->nurb.first; nu && raw_index >= 0; nu = nu->next) { + rna_ShapeKey_NurbInfo_step(r_info, nu, &raw_index, input_elem); + } +} + +static int rna_ShapeKey_curve_find_index(Key *key, int elem_index) +{ + NurbInfo info; + rna_ShapeKey_NurbInfo_find_index(key, elem_index, true, &info); + return info.item_index; +} + +typedef struct ShapeKeyCurvePoint { + StructRNA *type; + void *data; +} ShapeKeyCurvePoint; + +/* Build a mapping array for Curve objects with mixed sub-curve types. */ +static void rna_ShapeKey_data_begin_mixed(CollectionPropertyIterator *iter, Key *key, KeyBlock *kb, Curve *cu) +{ + int point_count = rna_ShapeKey_curve_find_index(key, kb->totelem); + + ShapeKeyCurvePoint *points = MEM_malloc_arrayN(sizeof(ShapeKeyCurvePoint), point_count, __func__); + + char *databuf = kb->data; + int items_left = point_count; + NurbInfo info = { NULL }; + + for (Nurb *nu = cu->nurb.first; nu && items_left > 0; nu = nu->next) { + ShapeKeyCurvePoint *nurb_points = points + info.item_index; + char *nurb_data = databuf + info.elem_index * key->elemsize; + + rna_ShapeKey_NurbInfo_step(&info, nu, &items_left, false); + + StructRNA *type = rna_ShapeKey_curve_point_type(nu); + + for (int i = 0; i < info.nurb_index; i++) { + nurb_points[i].type = type; + nurb_points[i].data = nurb_data + i * info.nurb_elem_step * key->elemsize; + } + } + + rna_iterator_array_begin(iter, points, sizeof(*points), point_count, true, NULL); +} static void rna_ShapeKey_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Key *key = rna_ShapeKey_find_key(ptr->id.data); KeyBlock *kb = (KeyBlock *)ptr->data; - Curve *cu; - Nurb *nu; int tot = kb->totelem, size = key->elemsize; - if (GS(key->from->name) == ID_CU) { - cu = (Curve *)key->from; - nu = cu->nurb.first; + if (GS(key->from->name) == ID_CU && tot > 0) { + Curve *cu = (Curve *)key->from; + StructRNA *type = NULL; + NurbInfo info = { 0 }; - if (nu->bezt) { - tot /= 3; - size *= 3; + /* Check if all sub-curves have the same type. */ + for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + if (type == NULL) { + type = rna_ShapeKey_curve_point_type(nu); + rna_ShapeKey_NurbInfo_init(&info, nu); + } + else if (type != rna_ShapeKey_curve_point_type(nu)) { + type = NULL; + break; + } + } + + /* If types are mixed, build a mapping array. */ + if (type == NULL) { + rna_ShapeKey_data_begin_mixed(iter, key, kb, cu); + return; + } + else { + tot /= info.nurb_elem_step; + size *= info.nurb_elem_step; } } @@ -428,16 +576,10 @@ static int rna_ShapeKey_data_length(PointerRNA *ptr) { Key *key = rna_ShapeKey_find_key(ptr->id.data); KeyBlock *kb = (KeyBlock *)ptr->data; - Curve *cu; - Nurb *nu; int tot = kb->totelem; if (GS(key->from->name) == ID_CU) { - cu = (Curve *)key->from; - nu = cu->nurb.first; - - if (nu->bezt) - tot /= 3; + tot = rna_ShapeKey_curve_find_index(key, tot); } return tot; @@ -446,23 +588,57 @@ static int rna_ShapeKey_data_length(PointerRNA *ptr) static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter) { Key *key = rna_ShapeKey_find_key(iter->parent.id.data); - StructRNA *type; - Curve *cu; - Nurb *nu; + void *ptr = rna_iterator_array_get(iter); + StructRNA *type = &RNA_ShapeKeyPoint; + + /* If data_begin allocated a mapping array, access it. */ + if (iter->internal.array.free_ptr) { + ShapeKeyCurvePoint *point = ptr; + + return rna_pointer_inherit_refine(&iter->parent, point->type, point->data); + } if (GS(key->from->name) == ID_CU) { - cu = (Curve *)key->from; - nu = cu->nurb.first; + Curve *cu = (Curve *)key->from; - if (nu->bezt) - type = &RNA_ShapeKeyBezierPoint; - else - type = &RNA_ShapeKeyCurvePoint; + type = rna_ShapeKey_curve_point_type(cu->nurb.first); } - else - type = &RNA_ShapeKeyPoint; - return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter)); + return rna_pointer_inherit_refine(&iter->parent, type, ptr); +} + +int rna_ShapeKey_data_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Key *key = rna_ShapeKey_find_key(ptr->id.data); + KeyBlock *kb = (KeyBlock *)ptr->data; + int elemsize = key->elemsize; + char *databuf = kb->data; + + memset(r_ptr, 0, sizeof(*r_ptr)); + + if (index < 0) { + return false; + } + + if (GS(key->from->name) == ID_CU) { + NurbInfo info; + rna_ShapeKey_NurbInfo_find_index(key, index, false, &info); + + if (info.nu && info.nurb_index < info.nurb_size) { + StructRNA *type = rna_ShapeKey_curve_point_type(info.nu); + + *r_ptr = rna_pointer_inherit_refine(ptr, type, databuf + elemsize * info.elem_index); + return true; + } + } + else { + if (index < kb->totelem) { + *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ShapeKeyPoint, databuf + elemsize * index); + return true; + } + } + + return false; } static char *rna_ShapeKey_path(PointerRNA *ptr) @@ -486,7 +662,7 @@ static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *p for (ob = bmain->object.first; ob; ob = ob->id.next) { if (BKE_key_from_object(ob) == key) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob); } } @@ -546,19 +722,6 @@ static int rna_ShapeKeyPoint_get_index(Key *key, KeyBlock *kb, float *point) return (int)(pt - start) / key->elemsize; } -static int rna_ShapeKeyBezierPoint_get_index(KeyBlock *kb, float *point) -{ - float *start = (float *)kb->data; - - /* Unlike with rna_ShapeKeyPoint_get_index(), we cannot use key->elemsize here - * since the default value for curves (16) is actually designed for BPoints - * (i.e. NURBS Surfaces). The magic number "12" here was found by empirical - * testing on a 64-bit system, and is similar to what's used for meshes and - * lattices. For more details, see T38013 - */ - return (int)(point - start) / 12; -} - static char *rna_ShapeKeyPoint_path(PointerRNA *ptr) { ID *id = (ID *)ptr->id.data; @@ -573,10 +736,11 @@ static char *rna_ShapeKeyPoint_path(PointerRNA *ptr) char name_esc_kb[sizeof(kb->name) * 2]; int index; - if (ptr->type == &RNA_ShapeKeyBezierPoint) - index = rna_ShapeKeyBezierPoint_get_index(kb, point); - else - index = rna_ShapeKeyPoint_get_index(key, kb, point); + index = rna_ShapeKeyPoint_get_index(key, kb, point); + + if (ELEM(ptr->type, &RNA_ShapeKeyBezierPoint, &RNA_ShapeKeyCurvePoint)) { + index = rna_ShapeKey_curve_find_index(key, index); + } BLI_strescape(name_esc_kb, kb->name, sizeof(name_esc_kb)); @@ -599,6 +763,8 @@ const EnumPropertyItem rna_enum_keyblock_type_items[] = { {0, NULL, 0, NULL, NULL} }; +static const float tilt_limit = DEG2RADF(21600.0f); + static void rna_def_keydata(BlenderRNA *brna) { StructRNA *srna; @@ -625,9 +791,17 @@ static void rna_def_keydata(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Location", ""); RNA_def_property_update(prop, 0, "rna_Key_update_data"); - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_funcs(prop, "rna_ShapeKeyCurvePoint_tilt_get", "rna_ShapeKeyCurvePoint_tilt_set", NULL); - RNA_def_property_ui_text(prop, "Tilt", ""); + RNA_def_property_range(prop, -tilt_limit, tilt_limit); + RNA_def_property_ui_range(prop, -tilt_limit, tilt_limit, 10, 3); + RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); + RNA_def_property_update(prop, 0, "rna_Key_update_data"); + + prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_funcs(prop, "rna_ShapeKeyCurvePoint_radius_get", "rna_ShapeKeyCurvePoint_radius_set", NULL); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Radius", "Radius for beveling"); RNA_def_property_update(prop, 0, "rna_Key_update_data"); srna = RNA_def_struct(brna, "ShapeKeyBezierPoint", NULL); @@ -655,13 +829,18 @@ static void rna_def_keydata(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Handle 2 Location", ""); RNA_def_property_update(prop, 0, "rna_Key_update_data"); - /* appears to be unused currently */ -#if 0 - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_tilt_get", "rna_ShapeKeyBezierPoint_tilt_set", NULL); - RNA_def_property_ui_text(prop, "Tilt", ""); + RNA_def_property_range(prop, -tilt_limit, tilt_limit); + RNA_def_property_ui_range(prop, -tilt_limit, tilt_limit, 10, 3); + RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); + RNA_def_property_update(prop, 0, "rna_Key_update_data"); + + prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_radius_get", "rna_ShapeKeyBezierPoint_radius_set", NULL); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Radius", "Radius for beveling"); RNA_def_property_update(prop, 0, "rna_Key_update_data"); -#endif } static void rna_def_keyblock(BlenderRNA *brna) @@ -712,7 +891,7 @@ static void rna_def_keyblock(BlenderRNA *brna) prop = RNA_def_property(srna, "relative_key", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ShapeKey"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL | PROP_PTR_NO_OWNERSHIP); RNA_def_property_pointer_funcs(prop, "rna_ShapeKey_relative_key_get", "rna_ShapeKey_relative_key_set", NULL, NULL); RNA_def_property_ui_text(prop, "Relative Key", "Shape used as a relative key"); @@ -721,7 +900,7 @@ static void rna_def_keyblock(BlenderRNA *brna) prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYBLOCK_MUTE); RNA_def_property_ui_text(prop, "Mute", "Mute this shape key"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); + RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1); RNA_def_property_update(prop, 0, "rna_Key_update_data"); prop = RNA_def_property(srna, "slider_min", PROP_FLOAT, PROP_NONE); @@ -742,7 +921,7 @@ static void rna_def_keyblock(BlenderRNA *brna) RNA_def_property_struct_type(prop, "UnknownType"); RNA_def_property_ui_text(prop, "Data", ""); RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", NULL, NULL, "rna_ShapeKey_data_get", - "rna_ShapeKey_data_length", NULL, NULL, NULL); + "rna_ShapeKey_data_length", "rna_ShapeKey_data_lookup_int", NULL, NULL); /* XXX multi-dim dynamic arrays are very badly supported by (py)rna currently, those are defined for the day * it works better, for now user will get a 1D tuple... |