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