249d132068c9cac849acd90452d151899983326f
[blender-staging.git] / source / blender / makesrna / intern / rna_key.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Foundation (2008).
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_key.c
24  *  \ingroup RNA
25  */
26
27 #include <stdlib.h>
28
29 #include "DNA_ID.h"
30 #include "DNA_scene_types.h"
31 #include "DNA_curve_types.h"
32 #include "DNA_key_types.h"
33 #include "DNA_lattice_types.h"
34 #include "DNA_mesh_types.h"
35
36 #include "BLI_utildefines.h"
37
38 #include "BLF_translation.h"
39
40 #include "RNA_access.h"
41 #include "RNA_define.h"
42 #include "RNA_enum_types.h"
43
44 #include "rna_internal.h"
45
46 #ifdef RNA_RUNTIME
47
48 #include <stddef.h>
49
50 #include "DNA_object_types.h"
51 #include "DNA_scene_types.h"
52
53 #include "BKE_animsys.h"
54 #include "BKE_depsgraph.h"
55 #include "BKE_key.h"
56 #include "BKE_main.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 static Key *rna_ShapeKey_find_key(ID *id)
62 {
63         switch (GS(id->name)) {
64                 case ID_CU: return ((Curve *)id)->key;
65                 case ID_KE: return (Key *)id;
66                 case ID_LT: return ((Lattice *)id)->key;
67                 case ID_ME: return ((Mesh *)id)->key;
68                 case ID_OB: return BKE_key_from_object((Object *)id);
69                 default: return NULL;
70         }
71 }
72
73 static void rna_ShapeKey_name_set(PointerRNA *ptr, const char *value)
74 {
75         KeyBlock *kb = ptr->data;
76         char oldname[sizeof(kb->name)];
77         
78         /* make a copy of the old name first */
79         BLI_strncpy(oldname, kb->name, sizeof(kb->name));
80         
81         /* copy the new name into the name slot */
82         BLI_strncpy_utf8(kb->name, value, sizeof(kb->name));
83         
84         /* make sure the name is truly unique */
85         if (ptr->id.data) {
86                 Key *key = rna_ShapeKey_find_key(ptr->id.data);
87                 BLI_uniquename(&key->block, kb, CTX_DATA_(BLF_I18NCONTEXT_ID_SHAPEKEY, "Key"), '.',
88                                offsetof(KeyBlock, name), sizeof(kb->name));
89         }
90         
91         /* fix all the animation data which may link to this */
92         BKE_animdata_fix_paths_rename_all(NULL, "key_blocks", oldname, kb->name);
93 }
94
95 static float rna_ShapeKey_frame_get(PointerRNA *ptr)
96 {
97         KeyBlock *kb = (KeyBlock *)ptr->data;
98         return kb->pos * 100.0f;  /* Because pos is ctime/100... */
99 }
100
101 static void rna_ShapeKey_value_set(PointerRNA *ptr, float value)
102 {
103         KeyBlock *data = (KeyBlock *)ptr->data;
104         CLAMP(value, data->slidermin, data->slidermax);
105         data->curval = value;
106 }
107
108 static void rna_ShapeKey_value_range(PointerRNA *ptr, float *min, float *max,
109                                      float *UNUSED(softmin), float *UNUSED(softmax))
110 {
111         KeyBlock *data = (KeyBlock *)ptr->data;
112
113         *min = data->slidermin;
114         *max = data->slidermax;
115 }
116
117 /* epsilon for how close one end of shapekey range can get to the other */
118 #define SHAPEKEY_SLIDER_TOL 0.001f
119
120 static void rna_ShapeKey_slider_min_range(PointerRNA *ptr, float *min, float *max,
121                                           float *UNUSED(softmin), float *UNUSED(softmax))
122 {
123         KeyBlock *data = (KeyBlock *)ptr->data;
124
125         *min = -10.0f;
126         *max = data->slidermax - SHAPEKEY_SLIDER_TOL;
127 }
128
129 static void rna_ShapeKey_slider_min_set(PointerRNA *ptr, float value)
130 {
131         KeyBlock *data = (KeyBlock *)ptr->data;
132         float min, max, softmin, softmax;
133         
134         rna_ShapeKey_slider_min_range(ptr, &min, &max, &softmin, &softmax);
135         CLAMP(value, min, max);
136         data->slidermin = value;
137 }
138
139 static void rna_ShapeKey_slider_max_range(PointerRNA *ptr, float *min, float *max,
140                                           float *UNUSED(softmin), float *UNUSED(softmax))
141 {
142         KeyBlock *data = (KeyBlock *)ptr->data;
143
144         *min = data->slidermin + SHAPEKEY_SLIDER_TOL;
145         *max = 10.0f;
146 }
147
148 static void rna_ShapeKey_slider_max_set(PointerRNA *ptr, float value)
149 {
150         KeyBlock *data = (KeyBlock *)ptr->data;
151         float min, max, softmin, softmax;
152         
153         rna_ShapeKey_slider_max_range(ptr, &min, &max, &softmin, &softmax);
154         CLAMP(value, min, max);
155         data->slidermax = value;
156 }
157
158 #undef SHAPEKEY_SLIDER_TOL
159
160 PointerRNA rna_object_shapekey_index_get(ID *id, int value)
161 {
162         Key *key = rna_ShapeKey_find_key(id);
163         KeyBlock *kb = NULL;
164         PointerRNA ptr;
165
166         if (key && value < key->totkey)
167                 kb = BLI_findlink(&key->block, value);
168         
169         RNA_pointer_create(id, &RNA_ShapeKey, kb, &ptr);
170
171         return ptr;
172 }
173
174 int rna_object_shapekey_index_set(ID *id, PointerRNA value, int current)
175 {
176         Key *key = rna_ShapeKey_find_key(id);
177
178         if (key) {
179                 int a = BLI_findindex(&key->block, value.data);
180                 if (a != -1) return a;
181         }
182         
183         return current;
184 }
185
186 static PointerRNA rna_ShapeKey_relative_key_get(PointerRNA *ptr)
187 {
188         KeyBlock *kb = (KeyBlock *)ptr->data;
189
190         return rna_object_shapekey_index_get(ptr->id.data, kb->relative);
191 }
192
193 static void rna_ShapeKey_relative_key_set(PointerRNA *ptr, PointerRNA value)
194 {
195         KeyBlock *kb = (KeyBlock *)ptr->data;
196
197         kb->relative = rna_object_shapekey_index_set(ptr->id.data, value, kb->relative);
198 }
199
200 static void rna_ShapeKeyPoint_co_get(PointerRNA *ptr, float *values)
201 {
202         float *vec = (float *)ptr->data;
203
204         values[0] = vec[0];
205         values[1] = vec[1];
206         values[2] = vec[2];
207 }
208
209 static void rna_ShapeKeyPoint_co_set(PointerRNA *ptr, const float *values)
210 {
211         float *vec = (float *)ptr->data;
212
213         vec[0] = values[0];
214         vec[1] = values[1];
215         vec[2] = values[2];
216 }
217
218 static float rna_ShapeKeyCurvePoint_tilt_get(PointerRNA *ptr)
219 {
220         float *vec = (float *)ptr->data;
221         return vec[3];
222 }
223
224 static void rna_ShapeKeyCurvePoint_tilt_set(PointerRNA *ptr, float value)
225 {
226         float *vec = (float *)ptr->data;
227         vec[3] = value;
228 }
229
230 static void rna_ShapeKeyBezierPoint_co_get(PointerRNA *ptr, float *values)
231 {
232         float *vec = (float *)ptr->data;
233
234         values[0] = vec[0 + 3];
235         values[1] = vec[1 + 3];
236         values[2] = vec[2 + 3];
237 }
238
239 static void rna_ShapeKeyBezierPoint_co_set(PointerRNA *ptr, const float *values)
240 {
241         float *vec = (float *)ptr->data;
242
243         vec[0 + 3] = values[0];
244         vec[1 + 3] = values[1];
245         vec[2 + 3] = values[2];
246 }
247
248 static void rna_ShapeKeyBezierPoint_handle_1_co_get(PointerRNA *ptr, float *values)
249 {
250         float *vec = (float *)ptr->data;
251
252         values[0] = vec[0];
253         values[1] = vec[1];
254         values[2] = vec[2];
255 }
256
257 static void rna_ShapeKeyBezierPoint_handle_1_co_set(PointerRNA *ptr, const float *values)
258 {
259         float *vec = (float *)ptr->data;
260
261         vec[0] = values[0];
262         vec[1] = values[1];
263         vec[2] = values[2];
264 }
265
266 static void rna_ShapeKeyBezierPoint_handle_2_co_get(PointerRNA *ptr, float *values)
267 {
268         float *vec = (float *)ptr->data;
269
270         values[0] = vec[6 + 0];
271         values[1] = vec[6 + 1];
272         values[2] = vec[6 + 2];
273 }
274
275 static void rna_ShapeKeyBezierPoint_handle_2_co_set(PointerRNA *ptr, const float *values)
276 {
277         float *vec = (float *)ptr->data;
278
279         vec[6 + 0] = values[0];
280         vec[6 + 1] = values[1];
281         vec[6 + 2] = values[2];
282 }
283
284 #if 0
285 static float rna_ShapeKeyBezierPoint_tilt_get(PointerRNA *ptr)
286 {
287         float *vec = (float *)ptr->data;
288         return vec[10];
289 }
290
291 static void rna_ShapeKeyBezierPoint_tilt_set(PointerRNA *ptr, float value)
292 {
293         float *vec = (float *)ptr->data;
294         vec[10] = value;
295 }
296 #endif
297
298 static void rna_ShapeKey_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
299 {
300         Key *key = rna_ShapeKey_find_key(ptr->id.data);
301         KeyBlock *kb = (KeyBlock *)ptr->data;
302         Curve *cu;
303         Nurb *nu;
304         int tot = kb->totelem, size = key->elemsize;
305         
306         if (GS(key->from->name) == ID_CU) {
307                 cu = (Curve *)key->from;
308                 nu = cu->nurb.first;
309                 
310                 if (nu->bezt) {
311                         tot /= 3;
312                         size *= 3;
313                 }
314         }
315         
316         rna_iterator_array_begin(iter, (void *)kb->data, size, tot, 0, NULL);
317 }
318
319 static int rna_ShapeKey_data_length(PointerRNA *ptr)
320 {
321         Key *key = rna_ShapeKey_find_key(ptr->id.data);
322         KeyBlock *kb = (KeyBlock *)ptr->data;
323         Curve *cu;
324         Nurb *nu;
325         int tot = kb->totelem;
326         
327         if (GS(key->from->name) == ID_CU) {
328                 cu = (Curve *)key->from;
329                 nu = cu->nurb.first;
330                 
331                 if (nu->bezt)
332                         tot /= 3;
333         }
334         
335         return tot;
336 }
337
338 static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter)
339 {
340         Key *key = rna_ShapeKey_find_key(iter->parent.id.data);
341         StructRNA *type;
342         Curve *cu;
343         Nurb *nu;
344         
345         if (GS(key->from->name) == ID_CU) {
346                 cu = (Curve *)key->from;
347                 nu = cu->nurb.first;
348                 
349                 if (nu->bezt)
350                         type = &RNA_ShapeKeyBezierPoint;
351                 else
352                         type = &RNA_ShapeKeyCurvePoint;
353         }
354         else
355                 type = &RNA_ShapeKeyPoint;
356         
357         return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter));
358 }
359
360 static char *rna_ShapeKey_path(PointerRNA *ptr)
361 {
362         KeyBlock *kb = (KeyBlock *)ptr->data;
363         ID *id = ptr->id.data;
364         char name_esc[sizeof(kb->name) * 2];
365
366         BLI_strescape(name_esc, kb->name, sizeof(name_esc));
367
368         if ((id) && (GS(id->name) != ID_KE))
369                 return BLI_sprintfN("shape_keys.key_blocks[\"%s\"]", name_esc);
370         else
371                 return BLI_sprintfN("key_blocks[\"%s\"]", name_esc);
372 }
373
374 static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
375 {
376         Key *key = ptr->id.data;
377         Object *ob;
378
379         for (ob = bmain->object.first; ob; ob = ob->id.next) {
380                 if (BKE_key_from_object(ob) == key) {
381                         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
382                         WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
383                 }
384         }
385 }
386
387 static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point)
388 {
389         KeyBlock *kb;
390         
391         /* sanity checks */
392         if (ELEM(NULL, key, point))
393                 return NULL;
394         
395         /* we'll need to manually search through the keyblocks and check
396          * if the point is somewhere in the middle of each block's data
397          */
398         for (kb = key->block.first; kb; kb = kb->next) {
399                 if (kb->data) {
400                         float *start = (float *)kb->data;
401                         float *end;
402                         
403                         /* easy cases first */
404                         if ((start == NULL) || (start > point)) {
405                                 /* there's no chance point is in array */
406                                 continue;
407                         }
408                         else if (start == point) {
409                                 /* exact match - point is first in array */
410                                 return kb;
411                         }
412                         
413                         /* determine where end of array is
414                          *      - elemsize is in bytes, so use (char *) cast to get array in terms of bytes
415                          */
416                         end = (float *)((char *)start + (key->elemsize * kb->totelem));
417                         
418                         /* if point's address is less than the end, then it is somewhere between start and end, so in array */
419                         if (end > point) {
420                                 /* we've found the owner of the point data */
421                                 return kb;
422                         }
423                 }
424         }
425         
426         return NULL;
427 }
428
429 static int rna_ShapeKeyPoint_get_index(Key *key, KeyBlock *kb, float *point)
430 {
431         /* if we frame the data array and point pointers as (char *), then the difference between
432          * them will be in bytes. Thus, dividing through by key->elemsize (number of bytes per point)
433          * gives us the offset of point from start of array.
434          */
435         char *start = (char *)kb->data;
436         char *pt = (char *)point;
437         
438         return (int)(pt - start) / key->elemsize;
439 }
440
441 static int rna_ShapeKeyBezierPoint_get_index(KeyBlock *kb, float *point)
442 {
443         float *start = (float *)kb->data;
444         
445         /* Unlike with rna_ShapeKeyPoint_get_index(), we cannot use key->elemsize here
446          * since the default value for curves (16) is actually designed for BPoints
447          * (i.e. NURBS Surfaces). The magic number "12" here was found by empirical
448          * testing on a 64-bit system, and is similar to what's used for meshes and 
449          * lattices. For more details, see T38013
450          */
451         return (int)(point - start) / 12;
452 }
453
454 static char *rna_ShapeKeyPoint_path(PointerRNA *ptr)
455 {
456         ID *id = (ID *)ptr->id.data;
457         Key *key = rna_ShapeKey_find_key(ptr->id.data);
458         KeyBlock *kb;
459         float *point = (float *)ptr->data;
460         
461         /* if we can get a key block, we can construct a path */
462         kb = rna_ShapeKeyData_find_keyblock(key, point);
463         
464         if (kb) {
465                 char name_esc_kb[sizeof(kb->name) * 2];
466                 int index;
467                 
468                 if (ptr->type == &RNA_ShapeKeyBezierPoint)
469                         index = rna_ShapeKeyBezierPoint_get_index(kb, point);
470                 else
471                         index = rna_ShapeKeyPoint_get_index(key, kb, point);
472
473                 BLI_strescape(name_esc_kb, kb->name, sizeof(name_esc_kb));
474                 
475                 if (GS(id->name) == ID_KE)
476                         return BLI_sprintfN("key_blocks[\"%s\"].data[%d]", name_esc_kb, index);
477                 else
478                         return BLI_sprintfN("shape_keys.key_blocks[\"%s\"].data[%d]", name_esc_kb, index);
479         }
480         else
481                 return NULL;  /* XXX: there's really no way to resolve this... */
482 }
483
484 #else
485
486 EnumPropertyItem keyblock_type_items[] = {
487         {KEY_LINEAR, "KEY_LINEAR", 0, "Linear", ""},
488         {KEY_CARDINAL, "KEY_CARDINAL", 0, "Cardinal", ""},
489         {KEY_CATMULL_ROM, "KEY_CATMULL_ROM", 0, "Catmull-Rom", ""},
490         {KEY_BSPLINE, "KEY_BSPLINE", 0, "BSpline", ""},
491         {0, NULL, 0, NULL, NULL}
492 };
493
494 static void rna_def_keydata(BlenderRNA *brna)
495 {
496         StructRNA *srna;
497         PropertyRNA *prop;
498
499         srna = RNA_def_struct(brna, "ShapeKeyPoint", NULL);
500         RNA_def_struct_ui_text(srna, "Shape Key Point", "Point in a shape key");
501         RNA_def_struct_path_func(srna, "rna_ShapeKeyPoint_path");
502
503         prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
504         RNA_def_property_array(prop, 3);
505         RNA_def_property_float_funcs(prop, "rna_ShapeKeyPoint_co_get", "rna_ShapeKeyPoint_co_set", NULL);
506         RNA_def_property_ui_text(prop, "Location", "");
507         RNA_def_property_update(prop, 0, "rna_Key_update_data");
508
509         srna = RNA_def_struct(brna, "ShapeKeyCurvePoint", NULL);
510         RNA_def_struct_ui_text(srna, "Shape Key Curve Point", "Point in a shape key for curves");
511         /* there's nothing type specific here, so this is fine for now */
512         RNA_def_struct_path_func(srna, "rna_ShapeKeyPoint_path");
513
514         prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
515         RNA_def_property_array(prop, 3);
516         RNA_def_property_float_funcs(prop, "rna_ShapeKeyPoint_co_get", "rna_ShapeKeyPoint_co_set", NULL);
517         RNA_def_property_ui_text(prop, "Location", "");
518         RNA_def_property_update(prop, 0, "rna_Key_update_data");
519
520         prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE);
521         RNA_def_property_float_funcs(prop, "rna_ShapeKeyCurvePoint_tilt_get", "rna_ShapeKeyCurvePoint_tilt_set", NULL);
522         RNA_def_property_ui_text(prop, "Tilt", "");
523         RNA_def_property_update(prop, 0, "rna_Key_update_data");
524
525         srna = RNA_def_struct(brna, "ShapeKeyBezierPoint", NULL);
526         RNA_def_struct_ui_text(srna, "Shape Key Bezier Point", "Point in a shape key for Bezier curves");
527         /* there's nothing type specific here, so this is fine for now */
528         RNA_def_struct_path_func(srna, "rna_ShapeKeyPoint_path");
529
530         prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
531         RNA_def_property_array(prop, 3);
532         RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_co_get", "rna_ShapeKeyBezierPoint_co_set", NULL);
533         RNA_def_property_ui_text(prop, "Location", "");
534         RNA_def_property_update(prop, 0, "rna_Key_update_data");
535
536         prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION);
537         RNA_def_property_array(prop, 3);
538         RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_handle_1_co_get",
539                                      "rna_ShapeKeyBezierPoint_handle_1_co_set", NULL);
540         RNA_def_property_ui_text(prop, "Handle 1 Location", "");
541         RNA_def_property_update(prop, 0, "rna_Key_update_data");
542
543         prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION);
544         RNA_def_property_array(prop, 3);
545         RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_handle_2_co_get",
546                                      "rna_ShapeKeyBezierPoint_handle_2_co_set", NULL);
547         RNA_def_property_ui_text(prop, "Handle 2 Location", "");
548         RNA_def_property_update(prop, 0, "rna_Key_update_data");
549
550         /* appears to be unused currently */
551 #if 0
552         prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE);
553         RNA_def_property_float_funcs(prop, "rna_ShapeKeyBezierPoint_tilt_get", "rna_ShapeKeyBezierPoint_tilt_set", NULL);
554         RNA_def_property_ui_text(prop, "Tilt", "");
555         RNA_def_property_update(prop, 0, "rna_Key_update_data");
556 #endif
557 }
558
559 static void rna_def_keyblock(BlenderRNA *brna)
560 {
561         StructRNA *srna;
562         PropertyRNA *prop;
563
564         srna = RNA_def_struct(brna, "ShapeKey", NULL);
565         RNA_def_struct_ui_text(srna, "Shape Key", "Shape key in a shape keys datablock");
566         RNA_def_struct_sdna(srna, "KeyBlock");
567         RNA_def_struct_path_func(srna, "rna_ShapeKey_path");
568         RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA);
569
570         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
571         RNA_def_property_ui_text(prop, "Name", "Name of Shape Key");
572         RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShapeKey_name_set");
573         RNA_def_property_update(prop, 0, "rna_Key_update_data");
574         RNA_def_struct_name_property(srna, prop);
575
576         /* keys need to be sorted to edit this */
577         prop = RNA_def_property(srna, "frame", PROP_FLOAT, PROP_TIME);
578         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
579         RNA_def_property_float_sdna(prop, NULL, "pos");
580         RNA_def_property_float_funcs(prop, "rna_ShapeKey_frame_get", NULL, NULL);
581         RNA_def_property_ui_text(prop, "Frame", "Frame for absolute keys");
582         RNA_def_property_update(prop, 0, "rna_Key_update_data");
583         
584         /* for now, this is editable directly, as users can set this even if they're not animating them
585          * (to test results) */
586         prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_FACTOR);
587         RNA_def_property_float_sdna(prop, NULL, "curval");
588         RNA_def_property_float_funcs(prop, NULL, "rna_ShapeKey_value_set", "rna_ShapeKey_value_range");
589         RNA_def_property_ui_range(prop, -10.0f, 10.0f, 10, 3);
590         RNA_def_property_ui_text(prop, "Value", "Value of shape key at the current frame");
591         RNA_def_property_update(prop, 0, "rna_Key_update_data");
592
593         prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
594         RNA_def_property_enum_sdna(prop, NULL, "type");
595         RNA_def_property_enum_items(prop, keyblock_type_items);
596         RNA_def_property_ui_text(prop, "Interpolation", "Interpolation type for absolute shape keys");
597         RNA_def_property_update(prop, 0, "rna_Key_update_data");
598
599         prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
600         RNA_def_property_string_sdna(prop, NULL, "vgroup");
601         RNA_def_property_ui_text(prop, "Vertex Group", "Vertex weight group, to blend with basis shape");
602         RNA_def_property_update(prop, 0, "rna_Key_update_data");
603
604         prop = RNA_def_property(srna, "relative_key", PROP_POINTER, PROP_NONE);
605         RNA_def_property_struct_type(prop, "ShapeKey");
606         RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
607         RNA_def_property_pointer_funcs(prop, "rna_ShapeKey_relative_key_get",
608                                        "rna_ShapeKey_relative_key_set", NULL, NULL);
609         RNA_def_property_ui_text(prop, "Relative Key", "Shape used as a relative key");
610         RNA_def_property_update(prop, 0, "rna_Key_update_data");
611
612         prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
613         RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYBLOCK_MUTE);
614         RNA_def_property_ui_text(prop, "Mute", "Mute this shape key");
615         RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
616         RNA_def_property_update(prop, 0, "rna_Key_update_data");
617
618         prop = RNA_def_property(srna, "slider_min", PROP_FLOAT, PROP_NONE);
619         RNA_def_property_float_sdna(prop, NULL, "slidermin");
620         RNA_def_property_range(prop, -10.0f, 10.0f);
621         RNA_def_property_float_funcs(prop, NULL, "rna_ShapeKey_slider_min_set", "rna_ShapeKey_slider_min_range");
622         RNA_def_property_ui_text(prop, "Slider Min", "Minimum for slider");
623
624         prop = RNA_def_property(srna, "slider_max", PROP_FLOAT, PROP_NONE);
625         RNA_def_property_float_sdna(prop, NULL, "slidermax");
626         RNA_def_property_range(prop, -10.0f, 10.0f);
627         RNA_def_property_float_default(prop, 1.0f);
628         RNA_def_property_float_funcs(prop, NULL, "rna_ShapeKey_slider_max_set", "rna_ShapeKey_slider_max_range");
629         RNA_def_property_ui_text(prop, "Slider Max", "Maximum for slider");
630
631         prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
632         RNA_def_property_collection_sdna(prop, NULL, "data", "totelem");
633         RNA_def_property_struct_type(prop, "UnknownType");
634         RNA_def_property_ui_text(prop, "Data", "");
635         RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", NULL, NULL, "rna_ShapeKey_data_get",
636                                           "rna_ShapeKey_data_length", NULL, NULL, NULL);
637 }
638
639 static void rna_def_key(BlenderRNA *brna)
640 {
641         StructRNA *srna;
642         PropertyRNA *prop;
643
644         srna = RNA_def_struct(brna, "Key", "ID");
645         RNA_def_struct_ui_text(srna, "Key", "Shape keys datablock containing different shapes of geometric datablocks");
646         RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA);
647
648         prop = RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NONE);
649         RNA_def_property_flag(prop, PROP_NEVER_NULL);
650         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
651         RNA_def_property_pointer_sdna(prop, NULL, "refkey");
652         RNA_def_property_ui_text(prop, "Reference Key", "");
653
654         prop = RNA_def_property(srna, "key_blocks", PROP_COLLECTION, PROP_NONE);
655         RNA_def_property_collection_sdna(prop, NULL, "block", NULL);
656         RNA_def_property_struct_type(prop, "ShapeKey");
657         RNA_def_property_ui_text(prop, "Key Blocks", "Shape keys");
658
659         rna_def_animdata_common(srna);
660
661         prop = RNA_def_property(srna, "user", PROP_POINTER, PROP_NONE);
662         RNA_def_property_flag(prop, PROP_NEVER_NULL);
663         RNA_def_property_pointer_sdna(prop, NULL, "from");
664         RNA_def_property_ui_text(prop, "User", "Datablock using these shape keys");
665
666         prop = RNA_def_property(srna, "use_relative", PROP_BOOLEAN, PROP_NONE);
667         RNA_def_property_boolean_sdna(prop, NULL, "type", KEY_RELATIVE);
668         RNA_def_property_ui_text(prop, "Relative",
669                                  "Make shape keys relative, "
670                                  "otherwise play through shapes as a sequence using the evaluation time");
671         RNA_def_property_update(prop, 0, "rna_Key_update_data");
672
673         prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_NONE);
674         RNA_def_property_float_sdna(prop, NULL, "ctime");
675         RNA_def_property_range(prop, MINFRAME, MAXFRAME);
676         RNA_def_property_ui_text(prop, "Evaluation Time", "Evaluation time for absolute shape keys");
677         RNA_def_property_update(prop, 0, "rna_Key_update_data");
678 }
679
680 void RNA_def_key(BlenderRNA *brna)
681 {
682         rna_def_key(brna);
683         rna_def_keyblock(brna);
684         rna_def_keydata(brna);
685 }
686
687 #endif