Fix T59713: Armature layer dots not updated on changes
[blender.git] / source / blender / makesrna / intern / rna_armature.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup RNA
19  */
20
21 #include <stdlib.h>
22
23 #include "BLI_math.h"
24
25 #include "RNA_access.h"
26 #include "RNA_define.h"
27
28 #include "rna_internal.h"
29
30 #include "DNA_armature_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_scene_types.h"
33
34 #include "WM_api.h"
35 #include "WM_types.h"
36
37 #ifdef RNA_RUNTIME
38
39 #  include "BKE_action.h"
40 #  include "BKE_context.h"
41 #  include "BKE_global.h"
42 #  include "BKE_idprop.h"
43 #  include "BKE_main.h"
44
45 #  include "ED_armature.h"
46 #  include "BKE_armature.h"
47
48 #  include "DEG_depsgraph.h"
49 #  include "DEG_depsgraph_build.h"
50
51 static void rna_Armature_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
52 {
53   ID *id = ptr->id.data;
54
55   DEG_id_tag_update(id, 0);
56   WM_main_add_notifier(NC_GEOM | ND_DATA, id);
57   /*WM_main_add_notifier(NC_OBJECT|ND_POSE, NULL); */
58 }
59
60 static void rna_Armature_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
61 {
62   ID *id = ptr->id.data;
63
64   DEG_relations_tag_update(bmain);
65
66   DEG_id_tag_update(id, 0);
67   WM_main_add_notifier(NC_GEOM | ND_DATA, id);
68 }
69
70 static void rna_Armature_act_bone_set(PointerRNA *ptr,
71                                       PointerRNA value,
72                                       struct ReportList *UNUSED(reports))
73 {
74   bArmature *arm = (bArmature *)ptr->data;
75
76   if (value.id.data == NULL && value.data == NULL) {
77     arm->act_bone = NULL;
78   }
79   else {
80     if (value.id.data != arm) {
81       Object *ob = (Object *)value.id.data;
82
83       if (GS(ob->id.name) != ID_OB || (ob->data != arm)) {
84         printf("ERROR: armature set active bone - new active doesn't come from this armature\n");
85         return;
86       }
87     }
88
89     arm->act_bone = value.data;
90     arm->act_bone->flag |= BONE_SELECTED;
91   }
92 }
93
94 static void rna_Armature_act_edit_bone_set(PointerRNA *ptr,
95                                            PointerRNA value,
96                                            struct ReportList *UNUSED(reports))
97 {
98   bArmature *arm = (bArmature *)ptr->data;
99
100   if (value.id.data == NULL && value.data == NULL) {
101     arm->act_edbone = NULL;
102   }
103   else {
104     if (value.id.data != arm) {
105       /* raise an error! */
106     }
107     else {
108       arm->act_edbone = value.data;
109       ((EditBone *)arm->act_edbone)->flag |= BONE_SELECTED;
110     }
111   }
112 }
113
114 static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, const char *name)
115 {
116   if (arm->edbo == NULL) {
117     BKE_reportf(reports,
118                 RPT_ERROR,
119                 "Armature '%s' not in edit mode, cannot add an editbone",
120                 arm->id.name + 2);
121     return NULL;
122   }
123   return ED_armature_ebone_add(arm, name);
124 }
125
126 static void rna_Armature_edit_bone_remove(bArmature *arm,
127                                           ReportList *reports,
128                                           PointerRNA *ebone_ptr)
129 {
130   EditBone *ebone = ebone_ptr->data;
131   if (arm->edbo == NULL) {
132     BKE_reportf(reports,
133                 RPT_ERROR,
134                 "Armature '%s' not in edit mode, cannot remove an editbone",
135                 arm->id.name + 2);
136     return;
137   }
138
139   if (BLI_findindex(arm->edbo, ebone) == -1) {
140     BKE_reportf(reports,
141                 RPT_ERROR,
142                 "Armature '%s' does not contain bone '%s'",
143                 arm->id.name + 2,
144                 ebone->name);
145     return;
146   }
147
148   ED_armature_ebone_remove(arm, ebone);
149   RNA_POINTER_INVALIDATE(ebone_ptr);
150 }
151
152 static void rna_Armature_update_layers(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
153 {
154   bArmature *arm = ptr->id.data;
155   Object *ob;
156
157   /* proxy lib exception, store it here so we can restore layers on file
158    * load, since it would otherwise get lost due to being linked data */
159   for (ob = bmain->objects.first; ob; ob = ob->id.next) {
160     if (ob->data == arm && ob->pose) {
161       ob->pose->proxy_layer = arm->layer;
162     }
163   }
164
165   DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
166   WM_main_add_notifier(NC_GEOM | ND_DATA, arm);
167 }
168
169 static void rna_Armature_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
170 {
171   ID *id = ptr->id.data;
172
173   DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
174   WM_main_add_notifier(NC_GEOM | ND_DATA, id);
175 }
176
177 /* called whenever a bone is renamed */
178 static void rna_Bone_update_renamed(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
179 {
180   ID *id = ptr->id.data;
181
182   /* redraw view */
183   WM_main_add_notifier(NC_GEOM | ND_DATA, id);
184
185   /* update animation channels */
186   WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN, id);
187 }
188
189 static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
190 {
191   ID *id = ptr->id.data;
192
193   /* 1) special updates for cases where rigs try to hook into armature drawing stuff
194    *    e.g. Mask Modifier - 'Armature' option
195    * 2) tag armature for copy-on-write, so that selection status (set by addons)
196    *    will update properly, like standard tools do already
197    */
198   if (id) {
199     if (GS(id->name) == ID_AR) {
200       bArmature *arm = (bArmature *)id;
201
202       if (arm->flag & ARM_HAS_VIZ_DEPS) {
203         DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
204       }
205
206       DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
207     }
208     else if (GS(id->name) == ID_OB) {
209       Object *ob = (Object *)id;
210       bArmature *arm = (bArmature *)ob->data;
211
212       if (arm->flag & ARM_HAS_VIZ_DEPS) {
213         DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
214       }
215
216       DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
217     }
218   }
219
220   WM_main_add_notifier(NC_GEOM | ND_DATA, id);
221
222   /* spaces that show animation data of the selected bone need updating */
223   WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN, id);
224 }
225
226 static char *rna_Bone_path(PointerRNA *ptr)
227 {
228   ID *id = ptr->id.data;
229   Bone *bone = (Bone *)ptr->data;
230   char name_esc[sizeof(bone->name) * 2];
231
232   BLI_strescape(name_esc, bone->name, sizeof(name_esc));
233
234   /* special exception for trying to get the path where ID-block is Object
235    * - this will be assumed to be from a Pose Bone...
236    */
237   if (id) {
238     if (GS(id->name) == ID_OB) {
239       return BLI_sprintfN("pose.bones[\"%s\"].bone", name_esc);
240     }
241   }
242
243   /* from armature... */
244   return BLI_sprintfN("bones[\"%s\"]", name_esc);
245 }
246
247 static IDProperty *rna_Bone_idprops(PointerRNA *ptr, bool create)
248 {
249   Bone *bone = ptr->data;
250
251   if (create && !bone->prop) {
252     IDPropertyTemplate val = {0};
253     bone->prop = IDP_New(IDP_GROUP, &val, "RNA_Bone ID properties");
254   }
255
256   return bone->prop;
257 }
258
259 static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, bool create)
260 {
261   EditBone *ebone = ptr->data;
262
263   if (create && !ebone->prop) {
264     IDPropertyTemplate val = {0};
265     ebone->prop = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties");
266   }
267
268   return ebone->prop;
269 }
270
271 static void rna_bone_layer_set(int *layer, const bool *values)
272 {
273   int i, tot = 0;
274
275   /* ensure we always have some layer selected */
276   for (i = 0; i < 32; i++) {
277     if (values[i]) {
278       tot++;
279     }
280   }
281
282   if (tot == 0) {
283     return;
284   }
285
286   for (i = 0; i < 32; i++) {
287     if (values[i]) {
288       *layer |= (1u << i);
289     }
290     else {
291       *layer &= ~(1u << i);
292     }
293   }
294 }
295
296 static void rna_Bone_layer_set(PointerRNA *ptr, const bool *values)
297 {
298   bArmature *arm = (bArmature *)ptr->id.data;
299   Bone *bone = (Bone *)ptr->data;
300
301   rna_bone_layer_set(&bone->layer, values);
302
303   BKE_armature_refresh_layer_used(arm);
304 }
305
306 static void rna_Armature_layer_set(PointerRNA *ptr, const bool *values)
307 {
308   bArmature *arm = (bArmature *)ptr->data;
309   int i, tot = 0;
310
311   /* ensure we always have some layer selected */
312   for (i = 0; i < 32; i++) {
313     if (values[i]) {
314       tot++;
315     }
316   }
317
318   if (tot == 0) {
319     return;
320   }
321
322   for (i = 0; i < 32; i++) {
323     if (values[i]) {
324       arm->layer |= (1u << i);
325     }
326     else {
327       arm->layer &= ~(1u << i);
328     }
329   }
330 }
331
332 static void rna_EditBone_name_set(PointerRNA *ptr, const char *value)
333 {
334   bArmature *arm = (bArmature *)ptr->id.data;
335   EditBone *ebone = (EditBone *)ptr->data;
336   char oldname[sizeof(ebone->name)], newname[sizeof(ebone->name)];
337
338   /* need to be on the stack */
339   BLI_strncpy_utf8(newname, value, sizeof(ebone->name));
340   BLI_strncpy(oldname, ebone->name, sizeof(ebone->name));
341
342   BLI_assert(BKE_id_is_in_global_main(&arm->id));
343   ED_armature_bone_rename(G_MAIN, arm, oldname, newname);
344 }
345
346 static void rna_Bone_name_set(PointerRNA *ptr, const char *value)
347 {
348   bArmature *arm = (bArmature *)ptr->id.data;
349   Bone *bone = (Bone *)ptr->data;
350   char oldname[sizeof(bone->name)], newname[sizeof(bone->name)];
351
352   /* need to be on the stack */
353   BLI_strncpy_utf8(newname, value, sizeof(bone->name));
354   BLI_strncpy(oldname, bone->name, sizeof(bone->name));
355
356   BLI_assert(BKE_id_is_in_global_main(&arm->id));
357   ED_armature_bone_rename(G_MAIN, arm, oldname, newname);
358 }
359
360 static void rna_EditBone_layer_set(PointerRNA *ptr, const bool values[])
361 {
362   EditBone *data = (EditBone *)(ptr->data);
363   rna_bone_layer_set(&data->layer, values);
364 }
365
366 static void rna_EditBone_connected_check(EditBone *ebone)
367 {
368   if (ebone->parent) {
369     if (ebone->flag & BONE_CONNECTED) {
370       /* Attach this bone to its parent */
371       copy_v3_v3(ebone->head, ebone->parent->tail);
372
373       if (ebone->flag & BONE_ROOTSEL) {
374         ebone->parent->flag |= BONE_TIPSEL;
375       }
376     }
377     else if (!(ebone->parent->flag & BONE_ROOTSEL)) {
378       ebone->parent->flag &= ~BONE_TIPSEL;
379     }
380   }
381 }
382
383 static void rna_EditBone_connected_set(PointerRNA *ptr, bool value)
384 {
385   EditBone *ebone = (EditBone *)(ptr->data);
386
387   if (value) {
388     ebone->flag |= BONE_CONNECTED;
389   }
390   else {
391     ebone->flag &= ~BONE_CONNECTED;
392   }
393
394   rna_EditBone_connected_check(ebone);
395 }
396
397 static PointerRNA rna_EditBone_parent_get(PointerRNA *ptr)
398 {
399   EditBone *data = (EditBone *)(ptr->data);
400   return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->parent);
401 }
402
403 static void rna_EditBone_parent_set(PointerRNA *ptr,
404                                     PointerRNA value,
405                                     struct ReportList *UNUSED(reports))
406 {
407   EditBone *ebone = (EditBone *)(ptr->data);
408   EditBone *pbone, *parbone = (EditBone *)value.data;
409
410   if (parbone == NULL) {
411     if (ebone->parent && !(ebone->parent->flag & BONE_ROOTSEL)) {
412       ebone->parent->flag &= ~BONE_TIPSEL;
413     }
414
415     ebone->parent = NULL;
416     ebone->flag &= ~BONE_CONNECTED;
417   }
418   else {
419     /* within same armature */
420     if (value.id.data != ptr->id.data) {
421       return;
422     }
423
424     /* make sure this is a valid child */
425     if (parbone == ebone) {
426       return;
427     }
428
429     for (pbone = parbone->parent; pbone; pbone = pbone->parent) {
430       if (pbone == ebone) {
431         return;
432       }
433     }
434
435     ebone->parent = parbone;
436     rna_EditBone_connected_check(ebone);
437   }
438 }
439
440 static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values)
441 {
442   EditBone *ebone = (EditBone *)(ptr->data);
443   ED_armature_ebone_to_mat4(ebone, (float(*)[4])values);
444 }
445
446 static void rna_EditBone_matrix_set(PointerRNA *ptr, const float *values)
447 {
448   EditBone *ebone = (EditBone *)(ptr->data);
449   ED_armature_ebone_from_mat4(ebone, (float(*)[4])values);
450 }
451
452 static void rna_Bone_bbone_handle_update(Main *bmain, Scene *scene, PointerRNA *ptr)
453 {
454   bArmature *arm = (bArmature *)ptr->id.data;
455   Bone *bone = (Bone *)ptr->data;
456
457   /* Update all users of this armature after changing B-Bone handles. */
458   for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
459     if (obt->data == arm && obt->pose) {
460       bPoseChannel *pchan = BKE_pose_channel_find_name(obt->pose, bone->name);
461
462       if (pchan && pchan->bone == bone) {
463         BKE_pchan_rebuild_bbone_handles(obt->pose, pchan);
464         DEG_id_tag_update(&obt->id, ID_RECALC_COPY_ON_WRITE);
465       }
466     }
467   }
468
469   rna_Armature_dependency_update(bmain, scene, ptr);
470 }
471
472 static PointerRNA rna_EditBone_bbone_prev_get(PointerRNA *ptr)
473 {
474   EditBone *data = (EditBone *)(ptr->data);
475   return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_prev);
476 }
477
478 static void rna_EditBone_bbone_prev_set(PointerRNA *ptr,
479                                         PointerRNA value,
480                                         struct ReportList *UNUSED(reports))
481 {
482   EditBone *ebone = (EditBone *)(ptr->data);
483   EditBone *hbone = (EditBone *)value.data;
484
485   /* Within the same armature? */
486   if (hbone == NULL || value.id.data == ptr->id.data) {
487     ebone->bbone_prev = hbone;
488   }
489 }
490
491 static void rna_Bone_bbone_prev_set(PointerRNA *ptr,
492                                     PointerRNA value,
493                                     struct ReportList *UNUSED(reports))
494 {
495   Bone *bone = (Bone *)ptr->data;
496   Bone *hbone = (Bone *)value.data;
497
498   /* Within the same armature? */
499   if (hbone == NULL || value.id.data == ptr->id.data) {
500     bone->bbone_prev = hbone;
501   }
502 }
503
504 static PointerRNA rna_EditBone_bbone_next_get(PointerRNA *ptr)
505 {
506   EditBone *data = (EditBone *)(ptr->data);
507   return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_next);
508 }
509
510 static void rna_EditBone_bbone_next_set(PointerRNA *ptr,
511                                         PointerRNA value,
512                                         struct ReportList *UNUSED(reports))
513 {
514   EditBone *ebone = (EditBone *)(ptr->data);
515   EditBone *hbone = (EditBone *)value.data;
516
517   /* Within the same armature? */
518   if (hbone == NULL || value.id.data == ptr->id.data) {
519     ebone->bbone_next = hbone;
520   }
521 }
522
523 static void rna_Bone_bbone_next_set(PointerRNA *ptr,
524                                     PointerRNA value,
525                                     struct ReportList *UNUSED(reports))
526 {
527   Bone *bone = (Bone *)ptr->data;
528   Bone *hbone = (Bone *)value.data;
529
530   /* Within the same armature? */
531   if (hbone == NULL || value.id.data == ptr->id.data) {
532     bone->bbone_next = hbone;
533   }
534 }
535
536 static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr)
537 {
538   bArmature *arm = (bArmature *)ptr->id.data;
539   EditBone *ebone = (EditBone *)ptr->data;
540   EditBone *child;
541
542   /* update our parent */
543   if (ebone->parent && ebone->flag & BONE_CONNECTED) {
544     copy_v3_v3(ebone->parent->tail, ebone->head);
545   }
546
547   /* update our children if necessary */
548   for (child = arm->edbo->first; child; child = child->next) {
549     if (child->parent == ebone && (child->flag & BONE_CONNECTED)) {
550       copy_v3_v3(child->head, ebone->tail);
551     }
552   }
553
554   if (arm->flag & ARM_MIRROR_EDIT) {
555     ED_armature_ebone_transform_mirror_update(arm, ebone, false);
556   }
557
558   rna_Armature_update_data(bmain, scene, ptr);
559 }
560
561 static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
562 {
563   ListBaseIterator *internal = &iter->internal.listbase;
564   Bone *bone = (Bone *)internal->link;
565
566   if (bone->childbase.first) {
567     internal->link = (Link *)bone->childbase.first;
568   }
569   else if (bone->next) {
570     internal->link = (Link *)bone->next;
571   }
572   else {
573     internal->link = NULL;
574
575     do {
576       bone = bone->parent;
577       if (bone && bone->next) {
578         internal->link = (Link *)bone->next;
579         break;
580       }
581     } while (bone);
582   }
583
584   iter->valid = (internal->link != NULL);
585 }
586
587 /* not essential, but much faster then the default lookup function */
588 static int rna_Armature_bones_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
589 {
590   bArmature *arm = (bArmature *)ptr->data;
591   Bone *bone = BKE_armature_find_bone_name(arm, key);
592   if (bone) {
593     RNA_pointer_create(ptr->id.data, &RNA_Bone, bone, r_ptr);
594     return true;
595   }
596   else {
597     return false;
598   }
599 }
600
601 static bool rna_Armature_is_editmode_get(PointerRNA *ptr)
602 {
603   bArmature *arm = (bArmature *)ptr->id.data;
604   return (arm->edbo != NULL);
605 }
606
607 static void rna_Armature_transform(struct bArmature *arm, Main *bmain, float *mat)
608 {
609   ED_armature_transform(bmain, arm, (float(*)[4])mat, true);
610 }
611
612 #else
613
614 /* Settings for curved bbone settings -
615  * The posemode values get applied over the top of the editmode ones. */
616 void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone)
617 {
618 #  define RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone) \
619     { \
620       if (is_posebone) { \
621         RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); \
622       } \
623       else { \
624         RNA_def_property_update(prop, 0, "rna_Armature_update_data"); \
625       } \
626     } \
627     ((void)0)
628
629   PropertyRNA *prop;
630
631   /* Roll In/Out */
632   prop = RNA_def_property(srna, "bbone_rollin", PROP_FLOAT, PROP_ANGLE);
633   RNA_def_property_float_sdna(prop, NULL, "roll1");
634   RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
635   RNA_def_property_ui_text(
636       prop, "Roll In", "Roll offset for the start of the B-Bone, adjusts twist");
637   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
638
639   prop = RNA_def_property(srna, "bbone_rollout", PROP_FLOAT, PROP_ANGLE);
640   RNA_def_property_float_sdna(prop, NULL, "roll2");
641   RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
642   RNA_def_property_ui_text(
643       prop, "Roll Out", "Roll offset for the end of the B-Bone, adjusts twist");
644   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
645
646   if (is_posebone == false) {
647     prop = RNA_def_property(srna, "use_endroll_as_inroll", PROP_BOOLEAN, PROP_NONE);
648     RNA_def_property_ui_text(
649         prop, "Inherit End Roll", "Add Roll Out of the Start Handle bone to the Roll In value");
650     RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ADD_PARENT_END_ROLL);
651     RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
652     RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
653   }
654
655   /* Curve X/Y Offsets */
656   prop = RNA_def_property(srna, "bbone_curveinx", PROP_FLOAT, PROP_NONE);
657   RNA_def_property_float_sdna(prop, NULL, "curve_in_x");
658   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
659   RNA_def_property_ui_text(
660       prop, "In X", "X-axis handle offset for start of the B-Bone's curve, adjusts curvature");
661   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
662
663   prop = RNA_def_property(srna, "bbone_curveiny", PROP_FLOAT, PROP_NONE);
664   RNA_def_property_float_sdna(prop, NULL, "curve_in_y");
665   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
666   RNA_def_property_ui_text(
667       prop, "In Y", "Y-axis handle offset for start of the B-Bone's curve, adjusts curvature");
668   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
669
670   prop = RNA_def_property(srna, "bbone_curveoutx", PROP_FLOAT, PROP_NONE);
671   RNA_def_property_float_sdna(prop, NULL, "curve_out_x");
672   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
673   RNA_def_property_ui_text(
674       prop, "Out X", "X-axis handle offset for end of the B-Bone's curve, adjusts curvature");
675   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
676
677   prop = RNA_def_property(srna, "bbone_curveouty", PROP_FLOAT, PROP_NONE);
678   RNA_def_property_float_sdna(prop, NULL, "curve_out_y");
679   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
680   RNA_def_property_ui_text(
681       prop, "Out Y", "Y-axis handle offset for end of the B-Bone's curve, adjusts curvature");
682   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
683
684   /* Ease In/Out */
685   prop = RNA_def_property(srna, "bbone_easein", PROP_FLOAT, PROP_NONE);
686   RNA_def_property_float_sdna(prop, NULL, "ease1");
687   RNA_def_property_ui_range(prop, -5.0f, 5.0f, 1, 3);
688   RNA_def_property_float_default(prop, 1.0f);
689   RNA_def_property_ui_text(prop, "Ease In", "Length of first Bezier Handle (for B-Bones only)");
690   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
691
692   prop = RNA_def_property(srna, "bbone_easeout", PROP_FLOAT, PROP_NONE);
693   RNA_def_property_float_sdna(prop, NULL, "ease2");
694   RNA_def_property_ui_range(prop, -5.0f, 5.0f, 1, 3);
695   RNA_def_property_float_default(prop, 1.0f);
696   RNA_def_property_ui_text(prop, "Ease Out", "Length of second Bezier Handle (for B-Bones only)");
697   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
698
699   /* Scale In/Out */
700   prop = RNA_def_property(srna, "bbone_scaleinx", PROP_FLOAT, PROP_NONE);
701   RNA_def_property_float_sdna(prop, NULL, "scale_in_x");
702   RNA_def_property_flag(prop, PROP_PROPORTIONAL);
703   RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
704   RNA_def_property_float_default(prop, 1.0f);
705   RNA_def_property_ui_text(prop,
706                            "Scale In X",
707                            "X-axis scale factor for start of the B-Bone, "
708                            "adjusts thickness (for tapering effects)");
709   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
710
711   prop = RNA_def_property(srna, "bbone_scaleiny", PROP_FLOAT, PROP_NONE);
712   RNA_def_property_float_sdna(prop, NULL, "scale_in_y");
713   RNA_def_property_flag(prop, PROP_PROPORTIONAL);
714   RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
715   RNA_def_property_float_default(prop, 1.0f);
716   RNA_def_property_ui_text(prop,
717                            "Scale In Y",
718                            "Y-axis scale factor for start of the B-Bone, "
719                            "adjusts thickness (for tapering effects)");
720   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
721
722   prop = RNA_def_property(srna, "bbone_scaleoutx", PROP_FLOAT, PROP_NONE);
723   RNA_def_property_float_sdna(prop, NULL, "scale_out_x");
724   RNA_def_property_flag(prop, PROP_PROPORTIONAL);
725   RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
726   RNA_def_property_float_default(prop, 1.0f);
727   RNA_def_property_ui_text(prop,
728                            "Scale Out X",
729                            "X-axis scale factor for end of the B-Bone, "
730                            "adjusts thickness (for tapering effects)");
731   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
732
733   prop = RNA_def_property(srna, "bbone_scaleouty", PROP_FLOAT, PROP_NONE);
734   RNA_def_property_float_sdna(prop, NULL, "scale_out_y");
735   RNA_def_property_flag(prop, PROP_PROPORTIONAL);
736   RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
737   RNA_def_property_float_default(prop, 1.0f);
738   RNA_def_property_ui_text(prop,
739                            "Scale Out Y",
740                            "Y-axis scale factor for end of the B-Bone, "
741                            "adjusts thickness (for tapering effects)");
742   RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
743
744 #  undef RNA_DEF_CURVEBONE_UPDATE
745 }
746
747 static void rna_def_bone_common(StructRNA *srna, int editbone)
748 {
749   static const EnumPropertyItem prop_bbone_handle_type[] = {
750       {BBONE_HANDLE_AUTO,
751        "AUTO",
752        0,
753        "Automatic",
754        "Use connected parent and children to compute the handle"},
755       {BBONE_HANDLE_ABSOLUTE,
756        "ABSOLUTE",
757        0,
758        "Absolute",
759        "Use the position of the specified bone to compute the handle"},
760       {BBONE_HANDLE_RELATIVE,
761        "RELATIVE",
762        0,
763        "Relative",
764        "Use the offset of the specified bone from rest pose to compute the handle"},
765       {BBONE_HANDLE_TANGENT,
766        "TANGENT",
767        0,
768        "Tangent",
769        "Use the orientation of the specified bone to compute the handle, ignoring the location"},
770       {0, NULL, 0, NULL, NULL},
771   };
772
773   PropertyRNA *prop;
774
775   /* strings */
776   prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
777   RNA_def_property_string_sdna(prop, NULL, "name");
778   RNA_def_property_ui_text(prop, "Name", "");
779   RNA_def_struct_name_property(srna, prop);
780   if (editbone) {
781     RNA_def_property_string_funcs(prop, NULL, NULL, "rna_EditBone_name_set");
782   }
783   else {
784     RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Bone_name_set");
785   }
786   RNA_def_property_update(prop, 0, "rna_Bone_update_renamed");
787
788   /* flags */
789   prop = RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_LAYER_MEMBER);
790   RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
791   RNA_def_property_array(prop, 32);
792   if (editbone) {
793     RNA_def_property_boolean_funcs(prop, NULL, "rna_EditBone_layer_set");
794   }
795   else {
796     RNA_def_property_boolean_funcs(prop, NULL, "rna_Bone_layer_set");
797   }
798   RNA_def_property_ui_text(prop, "Layers", "Layers bone exists in");
799   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
800
801   prop = RNA_def_property(srna, "use_connect", PROP_BOOLEAN, PROP_NONE);
802   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_CONNECTED);
803   if (editbone) {
804     RNA_def_property_boolean_funcs(prop, NULL, "rna_EditBone_connected_set");
805   }
806   else {
807     RNA_def_property_clear_flag(prop, PROP_EDITABLE);
808   }
809   RNA_def_property_ui_text(
810       prop, "Connected", "When bone has a parent, bone's head is stuck to the parent's tail");
811   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
812
813   prop = RNA_def_property(srna, "use_inherit_rotation", PROP_BOOLEAN, PROP_NONE);
814   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
815   RNA_def_property_ui_text(
816       prop, "Inherit Rotation", "Bone inherits rotation or scale from parent bone");
817   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
818
819   prop = RNA_def_property(srna, "use_envelope_multiply", PROP_BOOLEAN, PROP_NONE);
820   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_MULT_VG_ENV);
821   RNA_def_property_ui_text(
822       prop,
823       "Multiply Vertex Group with Envelope",
824       "When deforming bone, multiply effects of Vertex Group weights with Envelope influence");
825   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
826
827   prop = RNA_def_property(srna, "use_deform", PROP_BOOLEAN, PROP_NONE);
828   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_DEFORM);
829   RNA_def_property_ui_text(prop, "Deform", "Enable Bone to deform geometry");
830   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
831
832   prop = RNA_def_property(srna, "use_inherit_scale", PROP_BOOLEAN, PROP_NONE);
833   RNA_def_property_ui_text(prop, "Inherit Scale", "Bone inherits scaling from parent bone");
834   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_SCALE);
835   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
836
837   prop = RNA_def_property(srna, "use_local_location", PROP_BOOLEAN, PROP_NONE);
838   RNA_def_property_ui_text(prop, "Local Location", "Bone location is set in local space");
839   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION);
840   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
841
842   prop = RNA_def_property(srna, "use_relative_parent", PROP_BOOLEAN, PROP_NONE);
843   RNA_def_property_ui_text(
844       prop, "Relative Parenting", "Object children will use relative transform, like deform");
845   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_RELATIVE_PARENTING);
846   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
847
848   prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
849   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
850   RNA_def_property_ui_text(prop,
851                            "Display Wire",
852                            "Bone is always drawn as Wireframe regardless of viewport draw mode "
853                            "(useful for non-obstructive custom bone shapes)");
854   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
855
856   /* XXX: use_cyclic_offset is deprecated in 2.5. May/may not return */
857   prop = RNA_def_property(srna, "use_cyclic_offset", PROP_BOOLEAN, PROP_NONE);
858   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
859   RNA_def_property_ui_text(
860       prop,
861       "Cyclic Offset",
862       "When bone doesn't have a parent, it receives cyclic offset effects (Deprecated)");
863   //                         "When bone doesn't have a parent, it receives cyclic offset effects");
864   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
865
866   prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
867   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_UNSELECTABLE);
868   RNA_def_property_ui_text(prop, "Selectable", "Bone is able to be selected");
869   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
870
871   /* Number values */
872   /* envelope deform settings */
873   prop = RNA_def_property(srna, "envelope_distance", PROP_FLOAT, PROP_DISTANCE);
874   RNA_def_property_float_sdna(prop, NULL, "dist");
875   RNA_def_property_range(prop, 0.0f, 1000.0f);
876   RNA_def_property_ui_text(
877       prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only)");
878   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
879
880   prop = RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE);
881   RNA_def_property_float_sdna(prop, NULL, "weight");
882   RNA_def_property_range(prop, 0.0f, 1000.0f);
883   RNA_def_property_ui_text(
884       prop, "Envelope Deform Weight", "Bone deformation weight (for Envelope deform only)");
885   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
886
887   prop = RNA_def_property(srna, "head_radius", PROP_FLOAT, PROP_DISTANCE);
888   if (editbone) {
889     RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
890   }
891   else {
892     RNA_def_property_update(prop, 0, "rna_Armature_update_data");
893   }
894   RNA_def_property_float_sdna(prop, NULL, "rad_head");
895   /* XXX range is 0 to lim, where lim = 10000.0f * MAX2(1.0, view3d->grid); */
896   /*RNA_def_property_range(prop, 0, 1000); */
897   RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
898   RNA_def_property_ui_text(
899       prop, "Envelope Head Radius", "Radius of head of bone (for Envelope deform only)");
900
901   prop = RNA_def_property(srna, "tail_radius", PROP_FLOAT, PROP_DISTANCE);
902   if (editbone) {
903     RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
904   }
905   else {
906     RNA_def_property_update(prop, 0, "rna_Armature_update_data");
907   }
908   RNA_def_property_float_sdna(prop, NULL, "rad_tail");
909   /* XXX range is 0 to lim, where lim = 10000.0f * MAX2(1.0, view3d->grid); */
910   /*RNA_def_property_range(prop, 0, 1000); */
911   RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
912   RNA_def_property_ui_text(
913       prop, "Envelope Tail Radius", "Radius of tail of bone (for Envelope deform only)");
914
915   /* b-bones deform settings */
916   prop = RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE);
917   RNA_def_property_int_sdna(prop, NULL, "segments");
918   RNA_def_property_range(prop, 1, 32);
919   RNA_def_property_ui_text(
920       prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only)");
921   RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
922
923   prop = RNA_def_property(srna, "bbone_x", PROP_FLOAT, PROP_NONE);
924   RNA_def_property_float_sdna(prop, NULL, "xwidth");
925   RNA_def_property_range(prop, 0.0f, 1000.0f);
926   RNA_def_property_ui_text(prop, "B-Bone Display X Width", "B-Bone X size");
927   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
928
929   prop = RNA_def_property(srna, "bbone_z", PROP_FLOAT, PROP_NONE);
930   RNA_def_property_float_sdna(prop, NULL, "zwidth");
931   RNA_def_property_range(prop, 0.0f, 1000.0f);
932   RNA_def_property_ui_text(prop, "B-Bone Display Z Width", "B-Bone Z size");
933   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
934
935   prop = RNA_def_property(srna, "bbone_handle_type_start", PROP_ENUM, PROP_NONE);
936   RNA_def_property_enum_sdna(prop, NULL, "bbone_prev_type");
937   RNA_def_property_enum_items(prop, prop_bbone_handle_type);
938   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
939   RNA_def_property_ui_text(
940       prop, "B-Bone Start Handle Type", "Selects how the start handle of the B-Bone is computed");
941   RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
942
943   prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE);
944   RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev");
945   RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
946   if (editbone) {
947     RNA_def_property_pointer_funcs(
948         prop, "rna_EditBone_bbone_prev_get", "rna_EditBone_bbone_prev_set", NULL, NULL);
949     RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
950   }
951   else {
952     RNA_def_property_pointer_funcs(prop, NULL, "rna_Bone_bbone_prev_set", NULL, NULL);
953     RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
954   }
955   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP);
956   RNA_def_property_ui_text(
957       prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve");
958
959   prop = RNA_def_property(srna, "bbone_handle_type_end", PROP_ENUM, PROP_NONE);
960   RNA_def_property_enum_sdna(prop, NULL, "bbone_next_type");
961   RNA_def_property_enum_items(prop, prop_bbone_handle_type);
962   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
963   RNA_def_property_ui_text(
964       prop, "B-Bone End Handle Type", "Selects how the end handle of the B-Bone is computed");
965   RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
966
967   prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE);
968   RNA_def_property_pointer_sdna(prop, NULL, "bbone_next");
969   RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
970   if (editbone) {
971     RNA_def_property_pointer_funcs(
972         prop, "rna_EditBone_bbone_next_get", "rna_EditBone_bbone_next_set", NULL, NULL);
973     RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
974   }
975   else {
976     RNA_def_property_pointer_funcs(prop, NULL, "rna_Bone_bbone_next_set", NULL, NULL);
977     RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
978   }
979   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP);
980   RNA_def_property_ui_text(
981       prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve");
982 }
983
984 /* err... bones should not be directly edited (only editbones should be...) */
985 static void rna_def_bone(BlenderRNA *brna)
986 {
987   StructRNA *srna;
988   PropertyRNA *prop;
989
990   srna = RNA_def_struct(brna, "Bone", NULL);
991   RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature data-block");
992   RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
993   RNA_def_struct_path_func(srna, "rna_Bone_path");
994   RNA_def_struct_idprops_func(srna, "rna_Bone_idprops");
995
996   /* pointers/collections */
997   /* parent (pointer) */
998   prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
999   RNA_def_property_struct_type(prop, "Bone");
1000   RNA_def_property_pointer_sdna(prop, NULL, "parent");
1001   RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
1002   RNA_def_property_ui_text(prop, "Parent", "Parent bone (in same Armature)");
1003   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1004
1005   /* children (collection) */
1006   prop = RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
1007   RNA_def_property_collection_sdna(prop, NULL, "childbase", NULL);
1008   RNA_def_property_struct_type(prop, "Bone");
1009   RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
1010   RNA_def_property_ui_text(prop, "Children", "Bones which are children of this bone");
1011
1012   rna_def_bone_common(srna, 0);
1013   rna_def_bone_curved_common(srna, 0);
1014
1015   /* XXX should we define this in PoseChannel wrapping code instead?
1016    *     But PoseChannels directly get some of their flags from here... */
1017   prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1018   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_HIDDEN_P);
1019   RNA_def_property_ui_text(
1020       prop,
1021       "Hide",
1022       "Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes)");
1023   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1024
1025   prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1026   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED);
1027   RNA_def_property_ui_text(prop, "Select", "");
1028   RNA_def_property_clear_flag(
1029       prop,
1030       PROP_ANIMATABLE); /* XXX: review whether this could be used for interesting effects... */
1031   RNA_def_property_update(prop, 0, "rna_Bone_select_update");
1032
1033   prop = RNA_def_property(srna, "select_head", PROP_BOOLEAN, PROP_NONE);
1034   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ROOTSEL);
1035   RNA_def_property_ui_text(prop, "Select Head", "");
1036   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1037   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1038
1039   prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
1040   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_TIPSEL);
1041   RNA_def_property_ui_text(prop, "Select Tail", "");
1042   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1043   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1044
1045   /* XXX better matrix descriptions possible (Arystan) */
1046   prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
1047   RNA_def_property_float_sdna(prop, NULL, "bone_mat");
1048   RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
1049   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1050   RNA_def_property_ui_text(prop, "Bone Matrix", "3x3 bone matrix");
1051
1052   prop = RNA_def_property(srna, "matrix_local", PROP_FLOAT, PROP_MATRIX);
1053   RNA_def_property_float_sdna(prop, NULL, "arm_mat");
1054   RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1055   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1056   RNA_def_property_ui_text(
1057       prop, "Bone Armature-Relative Matrix", "4x4 bone matrix relative to armature");
1058
1059   prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
1060   RNA_def_property_float_sdna(prop, NULL, "tail");
1061   RNA_def_property_array(prop, 3);
1062   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1063   RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone");
1064   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
1065
1066   prop = RNA_def_property(srna, "tail_local", PROP_FLOAT, PROP_TRANSLATION);
1067   RNA_def_property_float_sdna(prop, NULL, "arm_tail");
1068   RNA_def_property_array(prop, 3);
1069   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1070   RNA_def_property_ui_text(
1071       prop, "Armature-Relative Tail", "Location of tail end of the bone relative to armature");
1072   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
1073
1074   prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
1075   RNA_def_property_float_sdna(prop, NULL, "head");
1076   RNA_def_property_array(prop, 3);
1077   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1078   RNA_def_property_ui_text(
1079       prop, "Head", "Location of head end of the bone relative to its parent");
1080   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
1081
1082   prop = RNA_def_property(srna, "head_local", PROP_FLOAT, PROP_TRANSLATION);
1083   RNA_def_property_float_sdna(prop, NULL, "arm_head");
1084   RNA_def_property_array(prop, 3);
1085   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1086   RNA_def_property_ui_text(
1087       prop, "Armature-Relative Head", "Location of head end of the bone relative to armature");
1088   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
1089
1090   RNA_api_bone(srna);
1091 }
1092
1093 static void rna_def_edit_bone(BlenderRNA *brna)
1094 {
1095   StructRNA *srna;
1096   PropertyRNA *prop;
1097
1098   srna = RNA_def_struct(brna, "EditBone", NULL);
1099   RNA_def_struct_sdna(srna, "EditBone");
1100   RNA_def_struct_idprops_func(srna, "rna_EditBone_idprops");
1101   RNA_def_struct_ui_text(srna, "Edit Bone", "Editmode bone in an Armature data-block");
1102   RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
1103
1104   RNA_define_verify_sdna(0); /* not in sdna */
1105
1106   prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1107   RNA_def_property_struct_type(prop, "EditBone");
1108   RNA_def_property_pointer_funcs(
1109       prop, "rna_EditBone_parent_get", "rna_EditBone_parent_set", NULL, NULL);
1110   RNA_def_property_flag(prop, PROP_EDITABLE);
1111   RNA_def_property_ui_text(prop, "Parent", "Parent edit bone (in same Armature)");
1112   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1113
1114   prop = RNA_def_property(srna, "roll", PROP_FLOAT, PROP_ANGLE);
1115   RNA_def_property_float_sdna(prop, NULL, "roll");
1116   RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
1117   RNA_def_property_ui_text(prop, "Roll", "Bone rotation around head-tail axis");
1118   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1119   RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1120
1121   prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
1122   RNA_def_property_float_sdna(prop, NULL, "head");
1123   RNA_def_property_array(prop, 3);
1124   RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone");
1125   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1126   RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1127
1128   prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
1129   RNA_def_property_float_sdna(prop, NULL, "tail");
1130   RNA_def_property_array(prop, 3);
1131   RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone");
1132   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1133   RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1134
1135   rna_def_bone_common(srna, 1);
1136   rna_def_bone_curved_common(srna, 0);
1137
1138   prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1139   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_HIDDEN_A);
1140   RNA_def_property_ui_text(prop, "Hide", "Bone is not visible when in Edit Mode");
1141   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1142   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1143
1144   prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
1145   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_EDITMODE_LOCKED);
1146   RNA_def_property_ui_text(prop, "Lock", "Bone is not able to be transformed when in Edit Mode");
1147   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1148   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1149
1150   prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1151   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED);
1152   RNA_def_property_ui_text(prop, "Select", "");
1153   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1154   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1155
1156   prop = RNA_def_property(srna, "select_head", PROP_BOOLEAN, PROP_NONE);
1157   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ROOTSEL);
1158   RNA_def_property_ui_text(prop, "Head Select", "");
1159   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1160   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1161
1162   prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
1163   RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_TIPSEL);
1164   RNA_def_property_ui_text(prop, "Tail Select", "");
1165   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1166   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1167
1168   /* calculated and read only, not actual data access */
1169   prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
1170   /*RNA_def_property_float_sdna(prop, NULL, "");  */ /* doesn't access any real data */
1171   RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1172   // RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1173   RNA_def_property_flag(prop, PROP_THICK_WRAP); /* no reference to original data */
1174   RNA_def_property_ui_text(
1175       prop,
1176       "Editbone Matrix",
1177       "Matrix combining loc/rot of the bone (head position, direction and roll), "
1178       "in armature space (WARNING: does not include/support bone's length/size)");
1179   RNA_def_property_float_funcs(prop, "rna_EditBone_matrix_get", "rna_EditBone_matrix_set", NULL);
1180
1181   RNA_api_armature_edit_bone(srna);
1182
1183   RNA_define_verify_sdna(1);
1184 }
1185
1186 /* armature.bones.* */
1187 static void rna_def_armature_bones(BlenderRNA *brna, PropertyRNA *cprop)
1188 {
1189   StructRNA *srna;
1190   PropertyRNA *prop;
1191
1192   /*  FunctionRNA *func; */
1193   /*  PropertyRNA *parm; */
1194
1195   RNA_def_property_srna(cprop, "ArmatureBones");
1196   srna = RNA_def_struct(brna, "ArmatureBones", NULL);
1197   RNA_def_struct_sdna(srna, "bArmature");
1198   RNA_def_struct_ui_text(srna, "Armature Bones", "Collection of armature bones");
1199
1200   prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1201   RNA_def_property_struct_type(prop, "Bone");
1202   RNA_def_property_pointer_sdna(prop, NULL, "act_bone");
1203   RNA_def_property_flag(prop, PROP_EDITABLE);
1204   RNA_def_property_ui_text(prop, "Active Bone", "Armature's active bone");
1205   RNA_def_property_pointer_funcs(prop, NULL, "rna_Armature_act_bone_set", NULL, NULL);
1206
1207   /* todo, redraw */
1208   /*      RNA_def_property_collection_active(prop, prop_act); */
1209 }
1210
1211 /* armature.bones.* */
1212 static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop)
1213 {
1214   StructRNA *srna;
1215   PropertyRNA *prop;
1216
1217   FunctionRNA *func;
1218   PropertyRNA *parm;
1219
1220   RNA_def_property_srna(cprop, "ArmatureEditBones");
1221   srna = RNA_def_struct(brna, "ArmatureEditBones", NULL);
1222   RNA_def_struct_sdna(srna, "bArmature");
1223   RNA_def_struct_ui_text(srna, "Armature EditBones", "Collection of armature edit bones");
1224
1225   prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1226   RNA_def_property_struct_type(prop, "EditBone");
1227   RNA_def_property_pointer_sdna(prop, NULL, "act_edbone");
1228   RNA_def_property_flag(prop, PROP_EDITABLE);
1229   RNA_def_property_ui_text(prop, "Active EditBone", "Armatures active edit bone");
1230   /*RNA_def_property_update(prop, 0, "rna_Armature_act_editbone_update"); */
1231   RNA_def_property_pointer_funcs(prop, NULL, "rna_Armature_act_edit_bone_set", NULL, NULL);
1232
1233   /* todo, redraw */
1234   /*      RNA_def_property_collection_active(prop, prop_act); */
1235
1236   /* add target */
1237   func = RNA_def_function(srna, "new", "rna_Armature_edit_bone_new");
1238   RNA_def_function_flag(func, FUNC_USE_REPORTS);
1239   RNA_def_function_ui_description(func, "Add a new bone");
1240   parm = RNA_def_string(func, "name", "Object", 0, "", "New name for the bone");
1241   RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1242   /* return type */
1243   parm = RNA_def_pointer(func, "bone", "EditBone", "", "Newly created edit bone");
1244   RNA_def_function_return(func, parm);
1245
1246   /* remove target */
1247   func = RNA_def_function(srna, "remove", "rna_Armature_edit_bone_remove");
1248   RNA_def_function_flag(func, FUNC_USE_REPORTS);
1249   RNA_def_function_ui_description(func, "Remove an existing bone from the armature");
1250   /* target to remove*/
1251   parm = RNA_def_pointer(func, "bone", "EditBone", "", "EditBone to remove");
1252   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1253   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1254 }
1255
1256 static void rna_def_armature(BlenderRNA *brna)
1257 {
1258   StructRNA *srna;
1259   PropertyRNA *prop;
1260
1261   FunctionRNA *func;
1262   PropertyRNA *parm;
1263
1264   static const EnumPropertyItem prop_drawtype_items[] = {
1265       {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Display bones as octahedral shape (default)"},
1266       {ARM_LINE, "STICK", 0, "Stick", "Display bones as simple 2D lines with dots"},
1267       {ARM_B_BONE,
1268        "BBONE",
1269        0,
1270        "B-Bone",
1271        "Display bones as boxes, showing subdivision and B-Splines"},
1272       {ARM_ENVELOPE,
1273        "ENVELOPE",
1274        0,
1275        "Envelope",
1276        "Display bones as extruded spheres, showing deformation influence volume"},
1277       {ARM_WIRE,
1278        "WIRE",
1279        0,
1280        "Wire",
1281        "Display bones as thin wires, showing subdivision and B-Splines"},
1282       {0, NULL, 0, NULL, NULL},
1283   };
1284   static const EnumPropertyItem prop_pose_position_items[] = {
1285       {0, "POSE", 0, "Pose Position", "Show armature in posed state"},
1286       {ARM_RESTPOS,
1287        "REST",
1288        0,
1289        "Rest Position",
1290        "Show Armature in binding pose state (no posing possible)"},
1291       {0, NULL, 0, NULL, NULL},
1292   };
1293
1294   srna = RNA_def_struct(brna, "Armature", "ID");
1295   RNA_def_struct_ui_text(
1296       srna,
1297       "Armature",
1298       "Armature data-block containing a hierarchy of bones, usually used for rigging characters");
1299   RNA_def_struct_ui_icon(srna, ICON_ARMATURE_DATA);
1300   RNA_def_struct_sdna(srna, "bArmature");
1301
1302   func = RNA_def_function(srna, "transform", "rna_Armature_transform");
1303   RNA_def_function_flag(func, FUNC_USE_MAIN);
1304   RNA_def_function_ui_description(func, "Transform armature bones by a matrix");
1305   parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
1306   RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1307
1308   /* Animation Data */
1309   rna_def_animdata_common(srna);
1310
1311   /* Collections */
1312   prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
1313   RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
1314   RNA_def_property_collection_funcs(prop,
1315                                     NULL,
1316                                     "rna_Armature_bones_next",
1317                                     NULL,
1318                                     NULL,
1319                                     NULL,
1320                                     NULL,
1321                                     "rna_Armature_bones_lookup_string",
1322                                     NULL);
1323   RNA_def_property_struct_type(prop, "Bone");
1324   RNA_def_property_ui_text(prop, "Bones", "");
1325   rna_def_armature_bones(brna, prop);
1326
1327   prop = RNA_def_property(srna, "edit_bones", PROP_COLLECTION, PROP_NONE);
1328   RNA_def_property_collection_sdna(prop, NULL, "edbo", NULL);
1329   RNA_def_property_struct_type(prop, "EditBone");
1330   RNA_def_property_ui_text(prop, "Edit Bones", "");
1331   rna_def_armature_edit_bones(brna, prop);
1332
1333   /* Enum values */
1334   prop = RNA_def_property(srna, "pose_position", PROP_ENUM, PROP_NONE);
1335   RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
1336   RNA_def_property_enum_items(prop, prop_pose_position_items);
1337   RNA_def_property_ui_text(
1338       prop, "Pose Position", "Show armature in binding pose or final posed state");
1339   RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1340   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1341
1342   prop = RNA_def_property(srna, "display_type", PROP_ENUM, PROP_NONE);
1343   RNA_def_property_enum_sdna(prop, NULL, "drawtype");
1344   RNA_def_property_enum_items(prop, prop_drawtype_items);
1345   RNA_def_property_ui_text(prop, "Display Type", "");
1346   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1347   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1348
1349   /* Boolean values */
1350   /* layer */
1351   prop = RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_LAYER_MEMBER);
1352   RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
1353   RNA_def_property_array(prop, 32);
1354   RNA_def_property_ui_text(prop, "Visible Layers", "Armature layer visibility");
1355   RNA_def_property_boolean_funcs(prop, NULL, "rna_Armature_layer_set");
1356   RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Armature_update_layers");
1357   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1358
1359   /* layer protection */
1360   prop = RNA_def_property(srna, "layers_protected", PROP_BOOLEAN, PROP_LAYER);
1361   RNA_def_property_boolean_sdna(prop, NULL, "layer_protected", 1);
1362   RNA_def_property_array(prop, 32);
1363   RNA_def_property_ui_text(prop,
1364                            "Layer Proxy Protection",
1365                            "Protected layers in Proxy Instances are restored to Proxy settings "
1366                            "on file reload and undo");
1367   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1368
1369   /* flag */
1370   prop = RNA_def_property(srna, "show_axes", PROP_BOOLEAN, PROP_NONE);
1371   RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWAXES);
1372   RNA_def_property_ui_text(prop, "Display Axes", "Display bone axes");
1373   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1374   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1375
1376   prop = RNA_def_property(srna, "show_names", PROP_BOOLEAN, PROP_NONE);
1377   RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWNAMES);
1378   RNA_def_property_ui_text(prop, "Display Names", "Display bone names");
1379   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1380   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1381
1382   prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
1383   RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_MIRROR_EDIT);
1384   RNA_def_property_ui_text(
1385       prop, "X-Axis Mirror", "Apply changes to matching bone on opposite side of X-Axis");
1386   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1387   RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
1388
1389   prop = RNA_def_property(srna, "show_bone_custom_shapes", PROP_BOOLEAN, PROP_NONE);
1390   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ARM_NO_CUSTOM);
1391   RNA_def_property_ui_text(
1392       prop, "Display Custom Bone Shapes", "Display bones with their custom shapes");
1393   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1394
1395   prop = RNA_def_property(srna, "show_group_colors", PROP_BOOLEAN, PROP_NONE);
1396   RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_COL_CUSTOM);
1397   RNA_def_property_ui_text(prop, "Display Bone Group Colors", "Display bone group colors");
1398   RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1399
1400   prop = RNA_def_property(srna, "is_editmode", PROP_BOOLEAN, PROP_NONE);
1401   RNA_def_property_boolean_funcs(prop, "rna_Armature_is_editmode_get", NULL);
1402   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1403   RNA_def_property_ui_text(prop, "Is Editmode", "True when used in editmode");
1404 }
1405
1406 void RNA_def_armature(BlenderRNA *brna)
1407 {
1408   rna_def_armature(brna);
1409   rna_def_bone(brna);
1410   rna_def_edit_bone(brna);
1411 }
1412
1413 #endif