Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/makesrna/intern/rna_key.c288
1 files changed, 233 insertions, 55 deletions
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index ed1e0d2690e..684756c0b12 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
@@ -336,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;
@@ -390,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 };
+
+ /* 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 (nu->bezt) {
- tot /= 3;
- size *= 3;
+ /* 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;
}
}
@@ -429,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;
@@ -447,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);
+ }
+
+ 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;
+ }
}
- else
- type = &RNA_ShapeKeyPoint;
- return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter));
+ return false;
}
static char *rna_ShapeKey_path(PointerRNA *ptr)
@@ -547,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;
@@ -574,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));
@@ -600,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;
@@ -626,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);
@@ -656,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)
@@ -743,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...