Blender V4.3
rna_armature.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10
11#include "BLI_math_base.h"
13
14#include "BLT_translation.hh"
15
16#include "RNA_access.hh"
17#include "RNA_define.hh"
18
19#include "rna_internal.hh"
20
21#include "DNA_armature_types.h"
22#include "DNA_object_types.h"
23#include "DNA_scene_types.h"
24
25#include "ED_anim_api.hh"
26
27#include "WM_api.hh"
28#include "WM_types.hh"
29
30/* Bone Collection Color Sets */
32 {0, "DEFAULT", 0, "Default Colors", ""},
33 {1, "THEME01", ICON_COLORSET_01_VEC, "01 - Theme Color Set", ""},
34 {2, "THEME02", ICON_COLORSET_02_VEC, "02 - Theme Color Set", ""},
35 {3, "THEME03", ICON_COLORSET_03_VEC, "03 - Theme Color Set", ""},
36 {4, "THEME04", ICON_COLORSET_04_VEC, "04 - Theme Color Set", ""},
37 {5, "THEME05", ICON_COLORSET_05_VEC, "05 - Theme Color Set", ""},
38 {6, "THEME06", ICON_COLORSET_06_VEC, "06 - Theme Color Set", ""},
39 {7, "THEME07", ICON_COLORSET_07_VEC, "07 - Theme Color Set", ""},
40 {8, "THEME08", ICON_COLORSET_08_VEC, "08 - Theme Color Set", ""},
41 {9, "THEME09", ICON_COLORSET_09_VEC, "09 - Theme Color Set", ""},
42 {10, "THEME10", ICON_COLORSET_10_VEC, "10 - Theme Color Set", ""},
43 {11, "THEME11", ICON_COLORSET_11_VEC, "11 - Theme Color Set", ""},
44 {12, "THEME12", ICON_COLORSET_12_VEC, "12 - Theme Color Set", ""},
45 {13, "THEME13", ICON_COLORSET_13_VEC, "13 - Theme Color Set", ""},
46 {14, "THEME14", ICON_COLORSET_14_VEC, "14 - Theme Color Set", ""},
47 {15, "THEME15", ICON_COLORSET_15_VEC, "15 - Theme Color Set", ""},
48 {16, "THEME16", ICON_COLORSET_16_VEC, "16 - Theme Color Set", ""},
49 {17, "THEME17", ICON_COLORSET_17_VEC, "17 - Theme Color Set", ""},
50 {18, "THEME18", ICON_COLORSET_18_VEC, "18 - Theme Color Set", ""},
51 {19, "THEME19", ICON_COLORSET_19_VEC, "19 - Theme Color Set", ""},
52 {20, "THEME20", ICON_COLORSET_20_VEC, "20 - Theme Color Set", ""},
53 {-1, "CUSTOM", 0, "Custom Color Set", ""},
54 {0, nullptr, 0, nullptr, nullptr},
55};
56#ifdef RNA_RUNTIME
57constexpr int COLOR_SETS_MAX_THEMED_INDEX = 20;
58#endif
59
60#ifdef RNA_RUNTIME
61
62# include <fmt/format.h>
63
64# include "BLI_math_vector.h"
65
66# include "BKE_action.hh"
67# include "BKE_context.hh"
68# include "BKE_global.hh"
69# include "BKE_idprop.hh"
70# include "BKE_main.hh"
71
72# include "BKE_armature.hh"
73# include "ED_armature.hh"
74
76
77# include "DEG_depsgraph.hh"
78# include "DEG_depsgraph_build.hh"
79
80# ifndef NDEBUG
81# include "ANIM_armature_iter.hh"
82# endif
83
84static void rna_Armature_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
85{
86 ID *id = ptr->owner_id;
87
89}
90
91static void rna_Armature_update_data(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
92{
93 ID *id = ptr->owner_id;
94
95 DEG_id_tag_update(id, 0);
97 // WM_main_add_notifier(NC_OBJECT|ND_POSE, nullptr);
98}
99
100static void rna_Armature_dependency_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
101{
102 ID *id = ptr->owner_id;
103
105
106 DEG_id_tag_update(id, 0);
108}
109
110static void rna_Armature_act_bone_set(PointerRNA *ptr, PointerRNA value, ReportList * /*reports*/)
111{
112 bArmature *arm = (bArmature *)ptr->data;
113
114 if (value.owner_id == nullptr && value.data == nullptr) {
115 arm->act_bone = nullptr;
116 }
117 else {
118 if (value.owner_id != &arm->id) {
119 Object *ob = (Object *)value.owner_id;
120
121 if (GS(ob->id.name) != ID_OB || (ob->data != arm)) {
122 printf("ERROR: armature set active bone - new active doesn't come from this armature\n");
123 return;
124 }
125 }
126
127 arm->act_bone = static_cast<Bone *>(value.data);
128 arm->act_bone->flag |= BONE_SELECTED;
129 }
130}
131
132static void rna_Armature_act_edit_bone_set(PointerRNA *ptr,
133 PointerRNA value,
134 ReportList * /*reports*/)
135{
136 bArmature *arm = (bArmature *)ptr->data;
137
138 if (value.owner_id == nullptr && value.data == nullptr) {
139 arm->act_edbone = nullptr;
140 }
141 else {
142 if (value.owner_id != &arm->id) {
143 /* raise an error! */
144 }
145 else {
146 arm->act_edbone = static_cast<EditBone *>(value.data);
147 ((EditBone *)arm->act_edbone)->flag |= BONE_SELECTED;
148 }
149 }
150}
151
152static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, const char *name)
153{
154 if (arm->edbo == nullptr) {
155 BKE_reportf(reports,
156 RPT_ERROR,
157 "Armature '%s' not in edit mode, cannot add an editbone",
158 arm->id.name + 2);
159 return nullptr;
160 }
161 return ED_armature_ebone_add(arm, name);
162}
163
164static void rna_Armature_edit_bone_remove(bArmature *arm,
165 ReportList *reports,
166 PointerRNA *ebone_ptr)
167{
168 EditBone *ebone = static_cast<EditBone *>(ebone_ptr->data);
169 if (arm->edbo == nullptr) {
170 BKE_reportf(reports,
171 RPT_ERROR,
172 "Armature '%s' not in edit mode, cannot remove an editbone",
173 arm->id.name + 2);
174 return;
175 }
176
177 if (BLI_findindex(arm->edbo, ebone) == -1) {
178 BKE_reportf(reports,
179 RPT_ERROR,
180 "Armature '%s' does not contain bone '%s'",
181 arm->id.name + 2,
182 ebone->name);
183 return;
184 }
185
186 ED_armature_ebone_remove(arm, ebone);
187 RNA_POINTER_INVALIDATE(ebone_ptr);
188}
189
190static void rna_iterator_bone_collections_all_begin(CollectionPropertyIterator *iter,
192{
193 bArmature *arm = (bArmature *)ptr->data;
195 arm->collection_array,
196 sizeof(BoneCollection *),
198 false,
199 nullptr);
200}
201static int rna_iterator_bone_collections_all_length(PointerRNA *ptr)
202{
203 bArmature *arm = (bArmature *)ptr->data;
204 return arm->collection_array_num;
205}
206
207static void rna_iterator_bone_collections_roots_begin(CollectionPropertyIterator *iter,
209{
210 bArmature *arm = (bArmature *)ptr->data;
212 arm->collection_array,
213 sizeof(BoneCollection *),
215 false,
216 nullptr);
217}
218static int rna_iterator_bone_collections_roots_length(PointerRNA *ptr)
219{
220 bArmature *arm = (bArmature *)ptr->data;
221 return arm->collection_root_count;
222}
223
224static void rna_BoneCollections_active_set(PointerRNA *ptr,
225 PointerRNA value,
226 struct ReportList * /*reports*/)
227{
228 bArmature *arm = (bArmature *)ptr->data;
229 BoneCollection *bcoll = (BoneCollection *)value.data;
231}
232
233static void rna_iterator_bone_collection_children_begin(CollectionPropertyIterator *iter,
235{
236 bArmature *arm = (bArmature *)ptr->owner_id;
237 const BoneCollection *bcoll = (BoneCollection *)ptr->data;
239 arm->collection_array + bcoll->child_index,
240 sizeof(BoneCollection *),
241 bcoll->child_count,
242 false,
243 nullptr);
244}
245static int rna_iterator_bone_collection_children_length(PointerRNA *ptr)
246{
247 const BoneCollection *bcoll = (BoneCollection *)ptr->data;
248 return bcoll->child_count;
249}
250
251static PointerRNA rna_BoneCollection_parent_get(PointerRNA *ptr)
252{
253 bArmature *arm = (bArmature *)ptr->owner_id;
254 const BoneCollection *bcoll = (BoneCollection *)ptr->data;
255
256 /* Note that this performs two scans of the array. This might look bad, but as
257 * long as `Object.children` still loops in Python over all of
258 * `bpy.data.objects`, this should also be acceptable. */
259 using namespace blender::animrig;
260 const int bcoll_index = armature_bonecoll_find_index(arm, bcoll);
261 const int parent_index = armature_bonecoll_find_parent_index(arm, bcoll_index);
262
263 if (parent_index < 0) {
264 return PointerRNA_NULL;
265 }
266
267 BoneCollection *parent = arm->collection_array[parent_index];
268 return RNA_pointer_create(&arm->id, &RNA_BoneCollection, parent);
269}
270
271static void rna_BoneCollection_parent_set(PointerRNA *ptr,
272 PointerRNA value,
273 struct ReportList *reports)
274{
275 using namespace blender::animrig;
276
278 BoneCollection *to_parent = (BoneCollection *)value.data;
279
280 bArmature *armature = (bArmature *)ptr->owner_id;
281
282 const int from_bcoll_index = armature_bonecoll_find_index(armature, self);
283 const int from_parent_index = armature_bonecoll_find_parent_index(armature, from_bcoll_index);
284 const int to_parent_index = armature_bonecoll_find_index(armature, to_parent);
285
286 if (to_parent_index >= 0) {
287 /* No need to check for parenthood cycles when the bone collection is turned into a root. */
288 if (to_parent_index == from_bcoll_index ||
289 armature_bonecoll_is_descendant_of(armature, from_bcoll_index, to_parent_index))
290 {
291 BKE_report(reports, RPT_ERROR, "Cannot make a bone collection a descendant of itself");
292 return;
293 }
294 }
295
297 armature, from_bcoll_index, -1, from_parent_index, to_parent_index);
298
300}
301
302static int rna_BoneCollections_active_index_get(PointerRNA *ptr)
303{
304 bArmature *arm = (bArmature *)ptr->data;
305 return arm->runtime.active_collection_index;
306}
307
308static void rna_BoneCollections_active_index_set(PointerRNA *ptr, const int bone_collection_index)
309{
310 bArmature *arm = (bArmature *)ptr->data;
311 ANIM_armature_bonecoll_active_index_set(arm, bone_collection_index);
312
314}
315
316static void rna_BoneCollections_active_index_range(
317 PointerRNA *ptr, int *min, int *max, int * /*softmin*/, int * /*softmax*/)
318{
319 bArmature *arm = (bArmature *)ptr->data;
320
321 /* TODO: Figure out what this function actually is used for, as we may want to protect the first
322 * collection (i.e. the default collection that should remain first). */
323 *min = 0;
324 *max = max_ii(0, arm->collection_array_num - 1);
325}
326
327static BoneCollection *rna_BoneCollections_new(bArmature *armature,
328 ReportList *reports,
329 const char *name,
330 BoneCollection *parent)
331{
332 if (parent == nullptr) {
333 BoneCollection *bcoll = ANIM_armature_bonecoll_new(armature, name);
335 return bcoll;
336 }
337
338 const int32_t parent_index = blender::animrig::armature_bonecoll_find_index(armature, parent);
339 if (parent_index < 0) {
340 BKE_reportf(reports,
341 RPT_ERROR,
342 "Bone collection '%s' not found in Armature '%s'",
343 parent->name,
344 armature->id.name + 2);
345 return nullptr;
346 }
347
348 BoneCollection *bcoll = ANIM_armature_bonecoll_new(armature, name, parent_index);
350 return bcoll;
351}
352
353static void rna_BoneCollections_active_name_set(PointerRNA *ptr, const char *name)
354{
355 bArmature *arm = (bArmature *)ptr->data;
357}
358
359static void rna_BoneCollections_move(bArmature *arm, ReportList *reports, int from, int to)
360{
361 const int count = arm->collection_array_num;
362 if (from < 0 || from >= count || to < 0 || to >= count ||
363 (from != to && !ANIM_armature_bonecoll_move_to_index(arm, from, to)))
364 {
365 BKE_reportf(reports, RPT_ERROR, "Cannot move collection from index '%d' to '%d'", from, to);
366 }
367
369}
370
371static void rna_BoneCollection_name_set(PointerRNA *ptr, const char *name)
372{
373 bArmature *arm = (bArmature *)ptr->owner_id;
374 BoneCollection *bcoll = (BoneCollection *)ptr->data;
375
376 ANIM_armature_bonecoll_name_set(arm, bcoll, name);
377}
378
379static void rna_BoneCollection_is_visible_set(PointerRNA *ptr, const bool is_visible)
380{
381 bArmature *arm = (bArmature *)ptr->owner_id;
382 BoneCollection *bcoll = (BoneCollection *)ptr->data;
383
384 ANIM_armature_bonecoll_is_visible_set(arm, bcoll, is_visible);
385}
386
387static bool rna_BoneCollection_is_visible_effectively_get(PointerRNA *ptr)
388{
389 const bArmature *arm = (bArmature *)ptr->owner_id;
390 const BoneCollection *bcoll = (BoneCollection *)ptr->data;
392}
393
394static void rna_BoneCollection_is_solo_set(PointerRNA *ptr, const bool is_solo)
395{
396 bArmature *arm = (bArmature *)ptr->owner_id;
397 BoneCollection *bcoll = (BoneCollection *)ptr->data;
398
399 ANIM_armature_bonecoll_solo_set(arm, bcoll, is_solo);
400}
401
402static void rna_BoneCollection_is_expanded_set(PointerRNA *ptr, const bool is_expanded)
403{
404 BoneCollection *bcoll = (BoneCollection *)ptr->data;
405 ANIM_armature_bonecoll_is_expanded_set(bcoll, is_expanded);
406}
407
408static std::optional<std::string> rna_BoneCollection_path(const PointerRNA *ptr)
409{
410 const BoneCollection *bcoll = (const BoneCollection *)ptr->data;
411 char name_esc[sizeof(bcoll->name) * 2];
412 BLI_str_escape(name_esc, bcoll->name, sizeof(name_esc));
413 return fmt::format("collections_all[\"{}\"]", name_esc);
414}
415
416static IDProperty **rna_BoneCollection_idprops(PointerRNA *ptr)
417{
418 BoneCollection *bcoll = static_cast<BoneCollection *>(ptr->data);
419 return &bcoll->prop;
420}
421
422static void rna_BoneCollectionMemberships_clear(Bone *bone)
423{
426}
427
428static bool rna_BoneCollection_is_editable_get(PointerRNA *ptr)
429{
430 bArmature *arm = reinterpret_cast<bArmature *>(ptr->owner_id);
431 BoneCollection *bcoll = static_cast<BoneCollection *>(ptr->data);
432 return ANIM_armature_bonecoll_is_editable(arm, bcoll);
433}
434
435static int rna_BoneCollection_index_get(PointerRNA *ptr)
436{
437 bArmature *arm = reinterpret_cast<bArmature *>(ptr->owner_id);
438 BoneCollection *bcoll = static_cast<BoneCollection *>(ptr->data);
440}
441
442static int rna_BoneCollection_child_number_get(PointerRNA *ptr)
443{
444 bArmature *arm = reinterpret_cast<bArmature *>(ptr->owner_id);
445 BoneCollection *bcoll = static_cast<BoneCollection *>(ptr->data);
447}
448static void rna_BoneCollection_child_number_set(PointerRNA *ptr, const int new_child_number)
449{
450 bArmature *arm = reinterpret_cast<bArmature *>(ptr->owner_id);
451 BoneCollection *bcoll = static_cast<BoneCollection *>(ptr->data);
452 blender::animrig::armature_bonecoll_child_number_set(arm, bcoll, new_child_number);
454}
455
456/* BoneCollection.bones iterator functions. */
457
458static void rna_BoneCollection_bones_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
459{
460 bArmature *arm = (bArmature *)ptr->owner_id;
461 if (arm->edbo) {
462 iter->valid = false;
463 BKE_reportf(nullptr, RPT_WARNING, "`Collection.bones` is not available in armature edit mode");
464 return;
465 }
466
467 BoneCollection *bcoll = (BoneCollection *)ptr->data;
468 rna_iterator_listbase_begin(iter, &bcoll->bones, nullptr);
469}
470
471static PointerRNA rna_BoneCollection_bones_get(CollectionPropertyIterator *iter)
472{
473 ListBaseIterator *lb_iter = &iter->internal.listbase;
474 BoneCollectionMember *member = (BoneCollectionMember *)lb_iter->link;
475 return rna_pointer_inherit_refine(&iter->parent, &RNA_Bone, member->bone);
476}
477
478/* Bone.collections iterator functions. */
479
480static void rna_Bone_collections_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
481{
482 Bone *bone = (Bone *)ptr->data;
483 ListBase /*BoneCollectionReference*/ bone_collection_refs = bone->runtime.collections;
484 rna_iterator_listbase_begin(iter, &bone_collection_refs, nullptr);
485}
486
487static PointerRNA rna_Bone_collections_get(CollectionPropertyIterator *iter)
488{
489 ListBaseIterator *lb_iter = &iter->internal.listbase;
491 return rna_pointer_inherit_refine(&iter->parent, &RNA_BoneCollection, bcoll_ref->bcoll);
492}
493
494/* EditBone.collections iterator functions. */
495
496static void rna_EditBone_collections_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
497{
498 EditBone *ebone = (EditBone *)ptr->data;
499 ListBase /*BoneCollectionReference*/ bone_collection_refs = ebone->bone_collections;
500 rna_iterator_listbase_begin(iter, &bone_collection_refs, nullptr);
501}
502
503/* Armature.collections library override support. */
504static bool rna_Armature_collections_override_apply(Main *bmain,
506{
507 PointerRNA *ptr_src = &rnaapply_ctx.ptr_src;
508 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
509 PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
510 PointerRNA *ptr_item_dst = &rnaapply_ctx.ptr_item_dst;
511 PointerRNA *ptr_item_src = &rnaapply_ctx.ptr_item_src;
513
514 switch (opop->operation) {
516 /* This is the case this function was written for: adding new bone collections. It will be
517 * handled below this switch. */
518 break;
520 /* NOTE(@sybren): These are stored by Blender when overridable properties are changed on the
521 * root collections, However, these are *also* created on the `armature.collections_all`
522 * property, which is actually where these per-collection overrides are handled.
523 * This doesn't seem to be proper behavior, but I also don't want to spam the console about
524 * this as this is not something a user could fix. */
525 return false;
526 default:
527 /* Any other operation is simply not supported, and also not expected to exist. */
528 printf("Unsupported RNA override operation on armature collections, ignoring\n");
529 return false;
530 }
531
532 const bArmature *arm_src = (bArmature *)ptr_src->owner_id;
533 bArmature *arm_dst = (bArmature *)ptr_dst->owner_id;
534 BoneCollection *bcoll_anchor = static_cast<BoneCollection *>(ptr_item_dst->data);
535 BoneCollection *bcoll_src = static_cast<BoneCollection *>(ptr_item_src->data);
537 arm_dst, arm_src, bcoll_anchor, bcoll_src);
538
539 if (!ID_IS_LINKED(&arm_dst->id)) {
540 /* Mark this bone collection as local override, so that certain operations can be allowed. */
542 }
543
544 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
545 return true;
546}
547
548static std::optional<std::string> rna_BoneColor_path_posebone(const PointerRNA *ptr)
549{
550 /* Find the bPoseChan that owns this BoneColor. */
551 const uint8_t *bcolor_ptr = static_cast<const uint8_t *>(ptr->data);
552 const uint8_t *bone_ptr = bcolor_ptr - offsetof(bPoseChannel, color);
553 const bPoseChannel *bone = reinterpret_cast<const bPoseChannel *>(bone_ptr);
554
555# ifndef NDEBUG
556 /* Sanity check that the above pointer magic actually worked. */
557 BLI_assert(GS(ptr->owner_id->name) == ID_OB);
558 const Object *ob = reinterpret_cast<const Object *>(ptr->owner_id);
559 bool found = false;
560 LISTBASE_FOREACH (bPoseChannel *, checkBone, &ob->pose->chanbase) {
561 if (&checkBone->color == ptr->data) {
562 BLI_assert_msg(checkBone == bone,
563 "pointer magic to find the pose bone failed (found the wrong bone)");
564 found = true;
565 break;
566 }
567 }
568 BLI_assert_msg(found, "pointer magic to find the pose bone failed (did not find the bone)");
569# endif
570
571 char name_esc[sizeof(bone->name) * 2];
572 BLI_str_escape(name_esc, bone->name, sizeof(name_esc));
573 return fmt::format("pose.bones[\"{}\"].color", name_esc);
574}
575
576static std::optional<std::string> rna_BoneColor_path_bone(const PointerRNA *ptr)
577{
578 /* Find the Bone that owns this BoneColor. */
579 const uint8_t *bcolor_ptr = static_cast<const uint8_t *>(ptr->data);
580 const uint8_t *bone_ptr = bcolor_ptr - offsetof(Bone, color);
581 const Bone *bone = reinterpret_cast<const Bone *>(bone_ptr);
582
583# ifndef NDEBUG
584 /* Sanity check that the above pointer magic actually worked. */
585 BLI_assert(GS(ptr->owner_id->name) == ID_AR);
586 const bArmature *arm = reinterpret_cast<const bArmature *>(ptr->owner_id);
587
588 bool found = false;
589 blender::animrig::ANIM_armature_foreach_bone(&arm->bonebase, [&](const Bone *checkBone) {
590 if (&checkBone->color == ptr->data) {
591 BLI_assert_msg(checkBone == bone,
592 "pointer magic to find the pose bone failed (found the wrong bone)");
593 found = true;
594 }
595 });
596 BLI_assert_msg(found, "pointer magic to find the pose bone failed (did not find the bone)");
597# endif
598
599 char name_esc[sizeof(bone->name) * 2];
600 BLI_str_escape(name_esc, bone->name, sizeof(name_esc));
601 return fmt::format("bones[\"{}\"].color", name_esc);
602}
603
604static std::optional<std::string> rna_BoneColor_path_editbone(const PointerRNA *ptr)
605{
606 /* Find the Bone that owns this BoneColor. */
607 const uint8_t *bcolor_ptr = static_cast<const uint8_t *>(ptr->data);
608 const uint8_t *bone_ptr = bcolor_ptr - offsetof(EditBone, color);
609 const EditBone *bone = reinterpret_cast<const EditBone *>(bone_ptr);
610
611# ifndef NDEBUG
612 /* Sanity check that the above pointer magic actually worked. */
613 BLI_assert(GS(ptr->owner_id->name) == ID_AR);
614 const bArmature *arm = reinterpret_cast<const bArmature *>(ptr->owner_id);
615
616 bool found = false;
617 LISTBASE_FOREACH (const EditBone *, checkBone, arm->edbo) {
618 if (&checkBone->color == ptr->data) {
619 BLI_assert_msg(checkBone == bone,
620 "pointer magic to find the pose bone failed (found the wrong bone)");
621 found = true;
622 break;
623 }
624 }
625 BLI_assert_msg(found, "pointer magic to find the pose bone failed (did not find the bone)");
626# endif
627
628 char name_esc[sizeof(bone->name) * 2];
629 BLI_str_escape(name_esc, bone->name, sizeof(name_esc));
630 return fmt::format("bones[\"{}\"].color", name_esc);
631}
632
633static std::optional<std::string> rna_BoneColor_path(const PointerRNA *ptr)
634{
635 const ID *owner = ptr->owner_id;
636 BLI_assert_msg(owner, "expecting all bone colors to have an owner");
637
638 switch (GS(owner->name)) {
639 case ID_OB:
640 return rna_BoneColor_path_posebone(ptr);
641 case ID_AR: {
642 const bArmature *arm = reinterpret_cast<const bArmature *>(owner);
643 if (arm->edbo == nullptr) {
644 return rna_BoneColor_path_bone(ptr);
645 }
646 return rna_BoneColor_path_editbone(ptr);
647 }
648 default:
649 BLI_assert_msg(false, "expected object or armature");
650 return std::nullopt;
651 }
652}
653
654void rna_BoneColor_palette_index_set(PointerRNA *ptr, const int new_palette_index)
655{
656 if (new_palette_index < -1 || new_palette_index > COLOR_SETS_MAX_THEMED_INDEX) {
657 BKE_reportf(nullptr, RPT_ERROR, "Invalid color palette index: %d", new_palette_index);
658 return;
659 }
660
661 BoneColor *bcolor = static_cast<BoneColor *>(ptr->data);
662 bcolor->palette_index = new_palette_index;
663
664 ID *id = ptr->owner_id;
667}
668
669bool rna_BoneColor_is_custom_get(PointerRNA *ptr)
670{
671 BoneColor *bcolor = static_cast<BoneColor *>(ptr->data);
672 return bcolor->palette_index < 0;
673}
674
675static void rna_BoneColor_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
676{
677 /* Ugly hack to trigger the setting of the SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC flag on the
678 * animation editors, which in turn calls ANIM_sync_animchannels_to_data(C) with the right
679 * context.
680 *
681 * Without this, changes to the bone colors are not reflected on the bActionGroup colors.
682 */
684}
685
686static void rna_Armature_redraw_data(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
687{
688 ID *id = ptr->owner_id;
689
692}
693
694/* Unselect bones when hidden or not selectable. */
695static void rna_EditBone_hide_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
696{
697 bArmature *arm = (bArmature *)ptr->owner_id;
698 EditBone *ebone = static_cast<EditBone *>(ptr->data);
699
700 if (ebone->flag & (BONE_HIDDEN_A | BONE_UNSELECTABLE)) {
702 }
703
706}
707
708/* Unselect bones when hidden or not selectable. */
709static void rna_Bone_hide_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
710{
711 bArmature *arm = (bArmature *)ptr->owner_id;
712 Bone *bone = (Bone *)ptr->data;
713
714 if (bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE)) {
716 }
717
720}
721
722/* called whenever a bone is renamed */
723static void rna_Bone_update_renamed(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
724{
725 ID *id = ptr->owner_id;
726
727 /* Redraw Outliner / Dopesheet. */
729
730 /* update animation channels */
732}
733
734static void rna_Bone_select_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
735{
736 ID *id = ptr->owner_id;
737
738 /* 1) special updates for cases where rigs try to hook into armature drawing stuff
739 * e.g. Mask Modifier - 'Armature' option
740 * 2) tag armature for copy-on-evaluation, so that selection status (set by addons)
741 * will update properly, like standard tools do already
742 */
743 if (id) {
744 if (GS(id->name) == ID_AR) {
745 bArmature *arm = (bArmature *)id;
746
747 if (arm->flag & ARM_HAS_VIZ_DEPS) {
749 }
750
752 }
753 else if (GS(id->name) == ID_OB) {
754 Object *ob = (Object *)id;
755 bArmature *arm = (bArmature *)ob->data;
756
757 if (arm->flag & ARM_HAS_VIZ_DEPS) {
759 }
760
762 }
763 }
764
766
767 /* spaces that show animation data of the selected bone need updating */
769}
770
771static std::optional<std::string> rna_Bone_path(const PointerRNA *ptr)
772{
773 const ID *id = ptr->owner_id;
774 const Bone *bone = (const Bone *)ptr->data;
775 char name_esc[sizeof(bone->name) * 2];
776
777 BLI_str_escape(name_esc, bone->name, sizeof(name_esc));
778
779 /* special exception for trying to get the path where ID-block is Object
780 * - this will be assumed to be from a Pose Bone...
781 */
782 if (id) {
783 if (GS(id->name) == ID_OB) {
784 return fmt::format("pose.bones[\"{}\"].bone", name_esc);
785 }
786 }
787
788 /* from armature... */
789 return fmt::format("bones[\"{}\"]", name_esc);
790}
791
792static IDProperty **rna_Bone_idprops(PointerRNA *ptr)
793{
794 Bone *bone = static_cast<Bone *>(ptr->data);
795 return &bone->prop;
796}
797
798static IDProperty **rna_EditBone_idprops(PointerRNA *ptr)
799{
800 EditBone *ebone = static_cast<EditBone *>(ptr->data);
801 return &ebone->prop;
802}
803
804static void rna_EditBone_name_set(PointerRNA *ptr, const char *value)
805{
806 bArmature *arm = (bArmature *)ptr->owner_id;
807 EditBone *ebone = (EditBone *)ptr->data;
808 char oldname[sizeof(ebone->name)], newname[sizeof(ebone->name)];
809
810 /* need to be on the stack */
811 STRNCPY_UTF8(newname, value);
812 STRNCPY(oldname, ebone->name);
813
815 ED_armature_bone_rename(G_MAIN, arm, oldname, newname);
816}
817
818static void rna_Bone_name_set(PointerRNA *ptr, const char *value)
819{
820 bArmature *arm = (bArmature *)ptr->owner_id;
821 Bone *bone = (Bone *)ptr->data;
822 char oldname[sizeof(bone->name)], newname[sizeof(bone->name)];
823
824 /* need to be on the stack */
825 STRNCPY_UTF8(newname, value);
826 STRNCPY(oldname, bone->name);
827
829 ED_armature_bone_rename(G_MAIN, arm, oldname, newname);
830}
831
832static void rna_EditBone_connected_check(EditBone *ebone)
833{
834 if (ebone->parent) {
835 if (ebone->flag & BONE_CONNECTED) {
836 /* Attach this bone to its parent */
837 copy_v3_v3(ebone->head, ebone->parent->tail);
838
839 if (ebone->flag & BONE_ROOTSEL) {
840 ebone->parent->flag |= BONE_TIPSEL;
841 }
842 }
843 else if (!(ebone->parent->flag & BONE_ROOTSEL)) {
844 ebone->parent->flag &= ~BONE_TIPSEL;
845 }
846 }
847}
848
849static void rna_EditBone_connected_set(PointerRNA *ptr, bool value)
850{
851 EditBone *ebone = (EditBone *)(ptr->data);
852
853 if (value) {
854 ebone->flag |= BONE_CONNECTED;
855 }
856 else {
857 ebone->flag &= ~BONE_CONNECTED;
858 }
859
860 rna_EditBone_connected_check(ebone);
861}
862
863static PointerRNA rna_EditBone_parent_get(PointerRNA *ptr)
864{
865 EditBone *data = (EditBone *)(ptr->data);
866 return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->parent);
867}
868
869static void rna_EditBone_parent_set(PointerRNA *ptr, PointerRNA value, ReportList * /*reports*/)
870{
871 EditBone *ebone = (EditBone *)(ptr->data);
872 EditBone *pbone, *parbone = (EditBone *)value.data;
873
874 if (parbone == nullptr) {
875 if (ebone->parent && !(ebone->parent->flag & BONE_ROOTSEL)) {
876 ebone->parent->flag &= ~BONE_TIPSEL;
877 }
878
879 ebone->parent = nullptr;
880 ebone->flag &= ~BONE_CONNECTED;
881 }
882 else {
883 /* within same armature */
884 if (value.owner_id != ptr->owner_id) {
885 return;
886 }
887
888 /* make sure this is a valid child */
889 if (parbone == ebone) {
890 return;
891 }
892
893 for (pbone = parbone->parent; pbone; pbone = pbone->parent) {
894 if (pbone == ebone) {
895 return;
896 }
897 }
898
899 ebone->parent = parbone;
900 rna_EditBone_connected_check(ebone);
901 }
902}
903
904static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values)
905{
906 EditBone *ebone = (EditBone *)(ptr->data);
907 ED_armature_ebone_to_mat4(ebone, (float(*)[4])values);
908}
909
910static void rna_EditBone_matrix_set(PointerRNA *ptr, const float *values)
911{
912 EditBone *ebone = (EditBone *)(ptr->data);
913 ED_armature_ebone_from_mat4(ebone, (float(*)[4])values);
914}
915
916static float rna_EditBone_length_get(PointerRNA *ptr)
917{
918 EditBone *ebone = (EditBone *)(ptr->data);
919 return len_v3v3(ebone->head, ebone->tail);
920}
921
922static void rna_EditBone_length_set(PointerRNA *ptr, float length)
923{
924 EditBone *ebone = (EditBone *)(ptr->data);
925 float delta[3];
926
927 sub_v3_v3v3(delta, ebone->tail, ebone->head);
928 if (normalize_v3(delta) == 0.0f) {
929 /* Zero length means directional information is lost. Choose arbitrary direction to avoid
930 * getting stuck. */
931 delta[2] = 1.0f;
932 }
933
934 madd_v3_v3v3fl(ebone->tail, ebone->head, delta, length);
935}
936
937static void rna_Bone_bbone_handle_update(Main *bmain, Scene *scene, PointerRNA *ptr)
938{
939 bArmature *arm = (bArmature *)ptr->owner_id;
940 Bone *bone = (Bone *)ptr->data;
941
942 /* Update all users of this armature after changing B-Bone handles. */
943 for (Object *obt = static_cast<Object *>(bmain->objects.first); obt;
944 obt = static_cast<Object *>(obt->id.next))
945 {
946 if (obt->data == arm && obt->pose) {
947 bPoseChannel *pchan = BKE_pose_channel_find_name(obt->pose, bone->name);
948
949 if (pchan && pchan->bone == bone) {
950 BKE_pchan_rebuild_bbone_handles(obt->pose, pchan);
952 }
953 }
954 }
955
956 rna_Armature_dependency_update(bmain, scene, ptr);
957}
958
959static PointerRNA rna_EditBone_bbone_prev_get(PointerRNA *ptr)
960{
961 EditBone *data = (EditBone *)(ptr->data);
962 return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_prev);
963}
964
965static void rna_EditBone_bbone_prev_set(PointerRNA *ptr,
966 PointerRNA value,
967 ReportList * /*reports*/)
968{
969 EditBone *ebone = (EditBone *)(ptr->data);
970 EditBone *hbone = (EditBone *)value.data;
971
972 /* Within the same armature? */
973 if (hbone == nullptr || value.owner_id == ptr->owner_id) {
974 ebone->bbone_prev = hbone;
975 }
976}
977
978static void rna_Bone_bbone_prev_set(PointerRNA *ptr, PointerRNA value, ReportList * /*reports*/)
979{
980 Bone *bone = (Bone *)ptr->data;
981 Bone *hbone = (Bone *)value.data;
982
983 /* Within the same armature? */
984 if (hbone == nullptr || value.owner_id == ptr->owner_id) {
985 bone->bbone_prev = hbone;
986 }
987}
988
989static PointerRNA rna_EditBone_bbone_next_get(PointerRNA *ptr)
990{
991 EditBone *data = (EditBone *)(ptr->data);
992 return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->bbone_next);
993}
994
995static void rna_EditBone_bbone_next_set(PointerRNA *ptr,
996 PointerRNA value,
997 ReportList * /*reports*/)
998{
999 EditBone *ebone = (EditBone *)(ptr->data);
1000 EditBone *hbone = (EditBone *)value.data;
1001
1002 /* Within the same armature? */
1003 if (hbone == nullptr || value.owner_id == ptr->owner_id) {
1004 ebone->bbone_next = hbone;
1005 }
1006}
1007
1008static void rna_Bone_bbone_next_set(PointerRNA *ptr, PointerRNA value, ReportList * /*reports*/)
1009{
1010 Bone *bone = (Bone *)ptr->data;
1011 Bone *hbone = (Bone *)value.data;
1012
1013 /* Within the same armature? */
1014 if (hbone == nullptr || value.owner_id == ptr->owner_id) {
1015 bone->bbone_next = hbone;
1016 }
1017}
1018
1019static PointerRNA rna_EditBone_color_get(PointerRNA *ptr)
1020{
1021 EditBone *data = (EditBone *)(ptr->data);
1022 return rna_pointer_inherit_refine(ptr, &RNA_BoneColor, &data->color);
1023}
1024
1025static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr)
1026{
1027 bArmature *arm = (bArmature *)ptr->owner_id;
1028 EditBone *ebone = (EditBone *)ptr->data;
1029 EditBone *child;
1030
1031 /* update our parent */
1032 if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1033 copy_v3_v3(ebone->parent->tail, ebone->head);
1034 }
1035
1036 /* update our children if necessary */
1037 for (child = static_cast<EditBone *>(arm->edbo->first); child; child = child->next) {
1038 if (child->parent == ebone && (child->flag & BONE_CONNECTED)) {
1039 copy_v3_v3(child->head, ebone->tail);
1040 }
1041 }
1042
1043 if (arm->flag & ARM_MIRROR_EDIT) {
1045 }
1046
1047 rna_Armature_update_data(bmain, scene, ptr);
1048}
1049
1050static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
1051{
1053 Bone *bone = (Bone *)internal->link;
1054
1055 if (bone->childbase.first) {
1056 internal->link = (Link *)bone->childbase.first;
1057 }
1058 else if (bone->next) {
1059 internal->link = (Link *)bone->next;
1060 }
1061 else {
1062 internal->link = nullptr;
1063
1064 do {
1065 bone = bone->parent;
1066 if (bone && bone->next) {
1067 internal->link = (Link *)bone->next;
1068 break;
1069 }
1070 } while (bone);
1071 }
1072
1073 iter->valid = (internal->link != nullptr);
1074}
1075
1076/* not essential, but much faster than the default lookup function */
1077static bool rna_Armature_bones_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
1078{
1079 bArmature *arm = (bArmature *)ptr->data;
1080 Bone *bone = BKE_armature_find_bone_name(arm, key);
1081 if (bone) {
1082 *r_ptr = RNA_pointer_create(ptr->owner_id, &RNA_Bone, bone);
1083 return true;
1084 }
1085 else {
1086 return false;
1087 }
1088}
1089
1090static bool rna_Armature_is_editmode_get(PointerRNA *ptr)
1091{
1092 bArmature *arm = (bArmature *)ptr->owner_id;
1093 return (arm->edbo != nullptr);
1094}
1095
1096static void rna_Armature_transform(bArmature *arm, const float mat[16])
1097{
1098 ED_armature_transform(arm, (const float(*)[4])mat, true);
1099}
1100
1101static int rna_Armature_relation_line_position_get(PointerRNA *ptr)
1102{
1103 bArmature *arm = (bArmature *)ptr->data;
1104 /* Translate the bitflag to an EnumPropertyItem prop_relation_lines_items item ID. */
1105 return (arm->flag & ARM_DRAW_RELATION_FROM_HEAD) ? 1 : 0;
1106}
1107
1108static void rna_Armature_relation_line_position_set(PointerRNA *ptr, const int value)
1109{
1110 bArmature *arm = (bArmature *)ptr->data;
1111
1112 /* Translate the EnumPropertyItem prop_relation_lines_items item ID to a bitflag */
1113 switch (value) {
1114 case 0:
1116 break;
1117 case 1:
1119 break;
1120 default:
1121 return;
1122 }
1123}
1124
1125#else
1126
1128{
1129 StructRNA *srna;
1130 PropertyRNA *prop;
1131
1132 srna = RNA_def_struct(brna, "BoneColor", nullptr);
1133 RNA_def_struct_ui_text(srna, "BoneColor", "Theme color or custom color of a bone");
1134 RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
1135 RNA_def_struct_path_func(srna, "rna_BoneColor_path");
1136
1137 prop = RNA_def_property(srna, "palette", PROP_ENUM, PROP_NONE);
1138 RNA_def_property_enum_sdna(prop, nullptr, "palette_index");
1140 RNA_def_property_enum_funcs(prop, nullptr, "rna_BoneColor_palette_index_set", nullptr);
1143 RNA_def_property_ui_text(prop, "Color Set", "Color palette to use");
1144 RNA_def_property_update(prop, 0, "rna_BoneColor_update");
1145
1146 prop = RNA_def_property(srna, "is_custom", PROP_BOOLEAN, PROP_NONE);
1147 RNA_def_property_boolean_funcs(prop, "rna_BoneColor_is_custom_get", nullptr);
1150 prop,
1151 "Use Custom Color",
1152 "A color palette is user-defined, instead of using a theme-defined one");
1153
1154 prop = RNA_def_property(srna, "custom", PROP_POINTER, PROP_NONE);
1156 RNA_def_property_struct_type(prop, "ThemeBoneColorSet");
1160 prop, "Custom", "The custom bone colors, used when palette is 'CUSTOM'");
1161 RNA_def_property_update(prop, 0, "rna_BoneColor_update");
1162}
1163
1164void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone, bool is_editbone)
1165{
1166 /* NOTE: The pose-mode values get applied over the top of the edit-mode ones. */
1167
1168# define RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone) \
1169 { \
1170 if (is_posebone) { \
1171 RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); \
1172 } \
1173 else if (is_editbone) { \
1174 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); \
1175 } \
1176 else { \
1177 RNA_def_property_update(prop, 0, "rna_Armature_update_data"); \
1178 } \
1179 } \
1180 ((void)0)
1181
1182 PropertyRNA *prop;
1183
1184 /* Roll In/Out */
1185 prop = RNA_def_property(srna, "bbone_rollin", PROP_FLOAT, PROP_ANGLE);
1186 RNA_def_property_float_sdna(prop, nullptr, "roll1");
1187 RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
1189 prop, "Roll In", "Roll offset for the start of the B-Bone, adjusts twist");
1190 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1191
1192 prop = RNA_def_property(srna, "bbone_rollout", PROP_FLOAT, PROP_ANGLE);
1193 RNA_def_property_float_sdna(prop, nullptr, "roll2");
1194 RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
1196 prop, "Roll Out", "Roll offset for the end of the B-Bone, adjusts twist");
1197 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1198
1199 if (is_posebone == false) {
1200 prop = RNA_def_property(srna, "use_endroll_as_inroll", PROP_BOOLEAN, PROP_NONE);
1202 prop, "Inherit End Roll", "Add Roll Out of the Start Handle bone to the Roll In value");
1203 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_flag", BBONE_ADD_PARENT_END_ROLL);
1205 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1206 }
1207
1208 /* Curve X/Y Offsets */
1209 prop = RNA_def_property(srna, "bbone_curveinx", PROP_FLOAT, PROP_NONE);
1210 RNA_def_property_float_sdna(prop, nullptr, "curve_in_x");
1213 prop, "In X", "X-axis handle offset for start of the B-Bone's curve, adjusts curvature");
1214 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1215
1216 prop = RNA_def_property(srna, "bbone_curveinz", PROP_FLOAT, PROP_NONE);
1217 RNA_def_property_float_sdna(prop, nullptr, "curve_in_z");
1220 prop, "In Z", "Z-axis handle offset for start of the B-Bone's curve, adjusts curvature");
1221 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1222
1223 prop = RNA_def_property(srna, "bbone_curveoutx", PROP_FLOAT, PROP_NONE);
1224 RNA_def_property_float_sdna(prop, nullptr, "curve_out_x");
1227 prop, "Out X", "X-axis handle offset for end of the B-Bone's curve, adjusts curvature");
1228 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1229
1230 prop = RNA_def_property(srna, "bbone_curveoutz", PROP_FLOAT, PROP_NONE);
1231 RNA_def_property_float_sdna(prop, nullptr, "curve_out_z");
1234 prop, "Out Z", "Z-axis handle offset for end of the B-Bone's curve, adjusts curvature");
1235 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1236
1237 /* Ease In/Out */
1238 prop = RNA_def_property(srna, "bbone_easein", PROP_FLOAT, PROP_NONE);
1239 RNA_def_property_float_sdna(prop, nullptr, "ease1");
1240 RNA_def_property_ui_range(prop, -5.0f, 5.0f, 1, 3);
1241 RNA_def_property_float_default(prop, is_posebone ? 0.0f : 1.0f);
1242 RNA_def_property_ui_text(prop, "Ease In", "Length of first Bézier Handle (for B-Bones only)");
1244 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1245
1246 prop = RNA_def_property(srna, "bbone_easeout", PROP_FLOAT, PROP_NONE);
1247 RNA_def_property_float_sdna(prop, nullptr, "ease2");
1248 RNA_def_property_ui_range(prop, -5.0f, 5.0f, 1, 3);
1249 RNA_def_property_float_default(prop, is_posebone ? 0.0f : 1.0f);
1250 RNA_def_property_ui_text(prop, "Ease Out", "Length of second Bézier Handle (for B-Bones only)");
1252 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1253
1254 if (is_posebone == false) {
1255 prop = RNA_def_property(srna, "use_scale_easing", PROP_BOOLEAN, PROP_NONE);
1257 prop, "Scale Easing", "Multiply the final easing values by the Scale In/Out Y factors");
1258 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_flag", BBONE_SCALE_EASING);
1259 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1260 }
1261
1262 /* Scale In/Out */
1263 prop = RNA_def_property(srna, "bbone_scalein", PROP_FLOAT, PROP_XYZ);
1264 RNA_def_property_float_sdna(prop, nullptr, "scale_in");
1265 RNA_def_property_array(prop, 3);
1267 RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
1270 prop,
1271 "Scale In",
1272 "Scale factors for the start of the B-Bone, adjusts thickness (for tapering effects)");
1273 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1274
1275 prop = RNA_def_property(srna, "bbone_scaleout", PROP_FLOAT, PROP_XYZ);
1276 RNA_def_property_float_sdna(prop, nullptr, "scale_out");
1277 RNA_def_property_array(prop, 3);
1279 RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
1282 prop,
1283 "Scale Out",
1284 "Scale factors for the end of the B-Bone, adjusts thickness (for tapering effects)");
1285 RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
1286
1287# undef RNA_DEF_CURVEBONE_UPDATE
1288}
1289
1290static void rna_def_bone_common(StructRNA *srna, int editbone)
1291{
1292 static const EnumPropertyItem prop_bbone_handle_type[] = {
1294 "AUTO",
1295 0,
1296 "Automatic",
1297 "Use connected parent and children to compute the handle"},
1299 "ABSOLUTE",
1300 0,
1301 "Absolute",
1302 "Use the position of the specified bone to compute the handle"},
1304 "RELATIVE",
1305 0,
1306 "Relative",
1307 "Use the offset of the specified bone from rest pose to compute the handle"},
1309 "TANGENT",
1310 0,
1311 "Tangent",
1312 "Use the orientation of the specified bone to compute the handle, ignoring the location"},
1313 {0, nullptr, 0, nullptr, nullptr},
1314 };
1315
1316 static const EnumPropertyItem prop_bbone_mapping_mode[] = {
1318 "STRAIGHT",
1319 0,
1320 "Straight",
1321 "Fast mapping that is good for most situations, but ignores the rest pose "
1322 "curvature of the B-Bone"},
1324 "CURVED",
1325 0,
1326 "Curved",
1327 "Slower mapping that gives better deformation for B-Bones that are sharply "
1328 "curved in rest pose"},
1329 {0, nullptr, 0, nullptr, nullptr},
1330 };
1331
1332 static const EnumPropertyItem prop_inherit_scale_mode[] = {
1333 {BONE_INHERIT_SCALE_FULL, "FULL", 0, "Full", "Inherit all effects of parent scaling"},
1335 "FIX_SHEAR",
1336 0,
1337 "Fix Shear",
1338 "Inherit scaling, but remove shearing of the child in the rest orientation"},
1340 "ALIGNED",
1341 0,
1342 "Aligned",
1343 "Rotate non-uniform parent scaling to align with the child, applying parent X "
1344 "scale to child X axis, and so forth"},
1346 "AVERAGE",
1347 0,
1348 "Average",
1349 "Inherit uniform scaling representing the overall change in the volume of the parent"},
1350 {BONE_INHERIT_SCALE_NONE, "NONE", 0, "None", "Completely ignore parent scaling"},
1352 "NONE_LEGACY",
1353 0,
1354 "None (Legacy)",
1355 "Ignore parent scaling without compensating for parent shear. "
1356 "Replicates the effect of disabling the original Inherit Scale checkbox."},
1357 {0, nullptr, 0, nullptr, nullptr},
1358 };
1359
1360 PropertyRNA *prop;
1361
1362 /* strings */
1363 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1364 RNA_def_property_string_sdna(prop, nullptr, "name");
1365 RNA_def_property_ui_text(prop, "Name", "");
1366 RNA_def_struct_name_property(srna, prop);
1367 if (editbone) {
1368 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_EditBone_name_set");
1369 }
1370 else {
1371 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_Bone_name_set");
1372 }
1373 RNA_def_property_update(prop, 0, "rna_Bone_update_renamed");
1374
1376
1377 prop = RNA_def_property(srna, "color", PROP_POINTER, PROP_NONE);
1378 RNA_def_property_struct_type(prop, "BoneColor");
1380 if (editbone) {
1381 RNA_def_property_pointer_funcs(prop, "rna_EditBone_color_get", nullptr, nullptr, nullptr);
1382 }
1383
1384 /* flags */
1385 prop = RNA_def_property(srna, "use_connect", PROP_BOOLEAN, PROP_NONE);
1386 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_CONNECTED);
1387 if (editbone) {
1388 RNA_def_property_boolean_funcs(prop, nullptr, "rna_EditBone_connected_set");
1389 }
1390 else {
1392 }
1394 prop, "Connected", "When bone has a parent, bone's head is stuck to the parent's tail");
1395 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1396
1397 prop = RNA_def_property(srna, "use_inherit_rotation", PROP_BOOLEAN, PROP_NONE);
1398 RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", BONE_HINGE);
1400 prop, "Inherit Rotation", "Bone inherits rotation or scale from parent bone");
1401 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1402
1403 prop = RNA_def_property(srna, "use_envelope_multiply", PROP_BOOLEAN, PROP_NONE);
1404 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_MULT_VG_ENV);
1406 prop,
1407 "Multiply Vertex Group with Envelope",
1408 "When deforming bone, multiply effects of Vertex Group weights with Envelope influence");
1409 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1410
1411 prop = RNA_def_property(srna, "use_deform", PROP_BOOLEAN, PROP_NONE);
1413 RNA_def_property_ui_text(prop, "Deform", "Enable Bone to deform geometry");
1414 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1415
1416 prop = RNA_def_property(srna, "inherit_scale", PROP_ENUM, PROP_NONE);
1418 prop, "Inherit Scale", "Specifies how the bone inherits scaling from the parent bone");
1419 RNA_def_property_enum_sdna(prop, nullptr, "inherit_scale_mode");
1420 RNA_def_property_enum_items(prop, prop_inherit_scale_mode);
1421 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1422
1423 prop = RNA_def_property(srna, "use_local_location", PROP_BOOLEAN, PROP_NONE);
1424 RNA_def_property_ui_text(prop, "Local Location", "Bone location is set in local space");
1426 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1427
1428 prop = RNA_def_property(srna, "use_relative_parent", PROP_BOOLEAN, PROP_NONE);
1430 prop, "Relative Parenting", "Object children will use relative transform, like deform");
1432 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1433
1434 prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
1435 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_DRAWWIRE);
1437 prop,
1438 "Display Wire",
1439 "Bone is always displayed in wireframe regardless of viewport shading mode "
1440 "(useful for non-obstructive custom bone shapes)");
1441 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1442
1443 /* XXX: use_cyclic_offset is deprecated in 2.5. May/may not return */
1444 prop = RNA_def_property(srna, "use_cyclic_offset", PROP_BOOLEAN, PROP_NONE);
1447 prop,
1448 "Cyclic Offset",
1449 "When bone doesn't have a parent, it receives cyclic offset effects (Deprecated)");
1450 // "When bone doesn't have a parent, it receives cyclic offset effects");
1451 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1452
1453 prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
1454 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_UNSELECTABLE);
1455 RNA_def_property_ui_text(prop, "Selectable", "Bone is able to be selected");
1456 if (editbone) {
1457 RNA_def_property_update(prop, 0, "rna_EditBone_hide_update");
1458 }
1459 else {
1460 RNA_def_property_update(prop, 0, "rna_Bone_hide_update");
1461 }
1462
1463 /* Number values */
1464 /* envelope deform settings */
1465 prop = RNA_def_property(srna, "envelope_distance", PROP_FLOAT, PROP_DISTANCE);
1466 if (editbone) {
1467 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1468 }
1469 else {
1470 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1471 }
1472 RNA_def_property_float_sdna(prop, nullptr, "dist");
1473 RNA_def_property_range(prop, 0.0f, 1000.0f);
1475 prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only)");
1476
1477 prop = RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE);
1478 RNA_def_property_float_sdna(prop, nullptr, "weight");
1479 RNA_def_property_range(prop, 0.0f, 1000.0f);
1481 prop, "Envelope Deform Weight", "Bone deformation weight (for Envelope deform only)");
1482 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1483
1484 prop = RNA_def_property(srna, "head_radius", PROP_FLOAT, PROP_DISTANCE);
1485 if (editbone) {
1486 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1487 }
1488 else {
1489 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1490 }
1491 RNA_def_property_float_sdna(prop, nullptr, "rad_head");
1492 /* XXX: range is 0 to limit, where `limit = 10000.0f * std::max(1.0, view3d->grid)`. */
1493 // RNA_def_property_range(prop, 0, 1000);
1494 RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
1496 prop, "Envelope Head Radius", "Radius of head of bone (for Envelope deform only)");
1497
1498 prop = RNA_def_property(srna, "tail_radius", PROP_FLOAT, PROP_DISTANCE);
1499 if (editbone) {
1500 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1501 }
1502 else {
1503 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1504 }
1505 RNA_def_property_float_sdna(prop, nullptr, "rad_tail");
1506 /* XXX range is 0 to limit, where limit = `10000.0f * std::max(1.0, view3d->grid)`. */
1507 // RNA_def_property_range(prop, 0, 1000);
1508 RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
1510 prop, "Envelope Tail Radius", "Radius of tail of bone (for Envelope deform only)");
1511
1512 /* b-bones deform settings */
1513 prop = RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE);
1514 if (editbone) {
1515 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1516 }
1517 else {
1518 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1519 }
1520 RNA_def_property_int_sdna(prop, nullptr, "segments");
1521 RNA_def_property_range(prop, 1, 32);
1523 prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only)");
1524
1525 prop = RNA_def_property(srna, "bbone_mapping_mode", PROP_ENUM, PROP_NONE);
1526 RNA_def_property_enum_sdna(prop, nullptr, "bbone_mapping_mode");
1527 RNA_def_property_enum_items(prop, prop_bbone_mapping_mode);
1530 prop,
1531 "B-Bone Vertex Mapping Mode",
1532 "Selects how the vertices are mapped to B-Bone segments based on their position");
1533 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1534
1535 prop = RNA_def_property(srna, "bbone_x", PROP_FLOAT, PROP_NONE);
1536 if (editbone) {
1537 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1538 }
1539 else {
1540 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1541 }
1542 RNA_def_property_float_sdna(prop, nullptr, "xwidth");
1544 RNA_def_property_ui_text(prop, "B-Bone Display X Width", "B-Bone X size");
1545
1546 prop = RNA_def_property(srna, "bbone_z", PROP_FLOAT, PROP_NONE);
1547 if (editbone) {
1548 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1549 }
1550 else {
1551 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1552 }
1553 RNA_def_property_float_sdna(prop, nullptr, "zwidth");
1555 RNA_def_property_ui_text(prop, "B-Bone Display Z Width", "B-Bone Z size");
1556
1557 /* B-Bone Start Handle settings. */
1558 prop = RNA_def_property(srna, "bbone_handle_type_start", PROP_ENUM, PROP_NONE);
1559 RNA_def_property_enum_sdna(prop, nullptr, "bbone_prev_type");
1560 RNA_def_property_enum_items(prop, prop_bbone_handle_type);
1563 prop, "B-Bone Start Handle Type", "Selects how the start handle of the B-Bone is computed");
1564 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1565
1566 prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE);
1567 RNA_def_property_pointer_sdna(prop, nullptr, "bbone_prev");
1568 RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
1569 if (editbone) {
1571 prop, "rna_EditBone_bbone_prev_get", "rna_EditBone_bbone_prev_set", nullptr, nullptr);
1572 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1573 }
1574 else {
1575 RNA_def_property_pointer_funcs(prop, nullptr, "rna_Bone_bbone_prev_set", nullptr, nullptr);
1576 RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
1577 }
1581 prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve");
1582
1583 prop = RNA_def_property(srna, "bbone_handle_use_scale_start", PROP_BOOLEAN, PROP_NONE);
1585 prop,
1586 "Start Handle Scale",
1587 "Multiply B-Bone Scale In channels by the local scale values of the start handle. "
1588 "This is done after the Scale Easing option and isn't affected by it.");
1589 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_prev_flag", BBONE_HANDLE_SCALE_X);
1590 RNA_def_property_array(prop, 3);
1591 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1592
1593 prop = RNA_def_property(srna, "bbone_handle_use_ease_start", PROP_BOOLEAN, PROP_NONE);
1595 prop,
1596 "Start Handle Ease",
1597 "Multiply the B-Bone Ease In channel by the local Y scale value of the start handle. "
1598 "This is done after the Scale Easing option and isn't affected by it.");
1599 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_prev_flag", BBONE_HANDLE_SCALE_EASE);
1600 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1601
1602 /* B-Bone End Handle settings. */
1603 prop = RNA_def_property(srna, "bbone_handle_type_end", PROP_ENUM, PROP_NONE);
1604 RNA_def_property_enum_sdna(prop, nullptr, "bbone_next_type");
1605 RNA_def_property_enum_items(prop, prop_bbone_handle_type);
1608 prop, "B-Bone End Handle Type", "Selects how the end handle of the B-Bone is computed");
1609 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1610
1611 prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE);
1612 RNA_def_property_pointer_sdna(prop, nullptr, "bbone_next");
1613 RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
1614 if (editbone) {
1616 prop, "rna_EditBone_bbone_next_get", "rna_EditBone_bbone_next_set", nullptr, nullptr);
1617 RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
1618 }
1619 else {
1620 RNA_def_property_pointer_funcs(prop, nullptr, "rna_Bone_bbone_next_set", nullptr, nullptr);
1621 RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
1622 }
1626 prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve");
1627
1628 prop = RNA_def_property(srna, "bbone_handle_use_scale_end", PROP_BOOLEAN, PROP_NONE);
1630 prop,
1631 "End Handle Scale",
1632 "Multiply B-Bone Scale Out channels by the local scale values of the end handle. "
1633 "This is done after the Scale Easing option and isn't affected by it.");
1634 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_next_flag", BBONE_HANDLE_SCALE_X);
1635 RNA_def_property_array(prop, 3);
1636 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1637
1638 prop = RNA_def_property(srna, "bbone_handle_use_ease_end", PROP_BOOLEAN, PROP_NONE);
1640 prop,
1641 "End Handle Ease",
1642 "Multiply the B-Bone Ease Out channel by the local Y scale value of the end handle. "
1643 "This is done after the Scale Easing option and isn't affected by it.");
1644 RNA_def_property_boolean_sdna(prop, nullptr, "bbone_next_flag", BBONE_HANDLE_SCALE_EASE);
1645 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
1646
1648}
1649
1652{
1653 StructRNA *srna;
1654 FunctionRNA *func;
1655
1656 RNA_def_property_srna(cprop, "BoneCollectionMemberships");
1657 srna = RNA_def_struct(brna, "BoneCollectionMemberships", nullptr);
1658 RNA_def_struct_sdna(srna, "Bone");
1660 srna, "Bone Collection Memberships", "The Bone Collections that contain this Bone");
1661
1662 /* Bone.collections.clear(...) */
1663 func = RNA_def_function(srna, "clear", "rna_BoneCollectionMemberships_clear");
1664 RNA_def_function_ui_description(func, "Remove this bone from all bone collections");
1665}
1666
1667/* Err... bones should not be directly edited (only edit-bones should be...). */
1668static void rna_def_bone(BlenderRNA *brna)
1669{
1670 StructRNA *srna;
1671 PropertyRNA *prop;
1672
1673 srna = RNA_def_struct(brna, "Bone", nullptr);
1674 RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature data-block");
1675 RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
1676 RNA_def_struct_path_func(srna, "rna_Bone_path");
1677 RNA_def_struct_idprops_func(srna, "rna_Bone_idprops");
1678
1679 /* pointers/collections */
1680 /* parent (pointer) */
1681 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1682 RNA_def_property_struct_type(prop, "Bone");
1683 RNA_def_property_pointer_sdna(prop, nullptr, "parent");
1685 RNA_def_property_ui_text(prop, "Parent", "Parent bone (in same Armature)");
1686 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1687
1688 /* children (collection) */
1689 prop = RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
1690 RNA_def_property_collection_sdna(prop, nullptr, "childbase", nullptr);
1691 RNA_def_property_struct_type(prop, "Bone");
1693 RNA_def_property_ui_text(prop, "Children", "Bones which are children of this bone");
1694
1695 prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
1696 RNA_def_property_struct_type(prop, "BoneCollection");
1698 "rna_Bone_collections_begin",
1699 "rna_iterator_listbase_next",
1700 "rna_iterator_listbase_end",
1701 "rna_Bone_collections_get",
1702 nullptr,
1703 nullptr,
1704 nullptr,
1705 nullptr);
1707 RNA_def_property_ui_text(prop, "Collections", "Bone Collections that contain this bone");
1709
1710 rna_def_bone_common(srna, 0);
1711 rna_def_bone_curved_common(srna, false, false);
1712
1714
1715 /* XXX should we define this in PoseChannel wrapping code instead?
1716 * But PoseChannels directly get some of their flags from here... */
1717 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1718 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_HIDDEN_P);
1720 prop,
1721 "Hide",
1722 "Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes)");
1723 RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
1724 RNA_def_property_update(prop, 0, "rna_Bone_hide_update");
1725
1726 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1727 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_SELECTED);
1728 RNA_def_property_ui_text(prop, "Select", "");
1730 prop,
1731 PROP_ANIMATABLE); /* XXX: review whether this could be used for interesting effects... */
1732 RNA_def_property_update(prop, 0, "rna_Bone_select_update");
1733
1734 prop = RNA_def_property(srna, "select_head", PROP_BOOLEAN, PROP_NONE);
1735 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_ROOTSEL);
1736 RNA_def_property_ui_text(prop, "Select Head", "");
1738 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1739
1740 prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
1741 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_TIPSEL);
1742 RNA_def_property_ui_text(prop, "Select Tail", "");
1744 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1745
1746 /* XXX better matrix descriptions possible (Arystan) */
1747 prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
1748 RNA_def_property_float_sdna(prop, nullptr, "bone_mat");
1752 prop, "Bone Matrix", "3" BLI_STR_UTF8_MULTIPLICATION_SIGN "3 bone matrix");
1753
1754 prop = RNA_def_property(srna, "matrix_local", PROP_FLOAT, PROP_MATRIX);
1755 RNA_def_property_float_sdna(prop, nullptr, "arm_mat");
1759 "Bone Armature-Relative Matrix",
1761 "4 bone matrix relative to armature");
1762
1763 prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
1764 RNA_def_property_float_sdna(prop, nullptr, "tail");
1765 RNA_def_property_array(prop, 3);
1768 prop, "Tail", "Location of tail end of the bone relative to its parent");
1770
1771 prop = RNA_def_property(srna, "tail_local", PROP_FLOAT, PROP_TRANSLATION);
1772 RNA_def_property_float_sdna(prop, nullptr, "arm_tail");
1773 RNA_def_property_array(prop, 3);
1776 prop, "Armature-Relative Tail", "Location of tail end of the bone relative to armature");
1778
1779 prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
1780 RNA_def_property_float_sdna(prop, nullptr, "head");
1781 RNA_def_property_array(prop, 3);
1784 prop, "Head", "Location of head end of the bone relative to its parent");
1786
1787 prop = RNA_def_property(srna, "head_local", PROP_FLOAT, PROP_TRANSLATION);
1788 RNA_def_property_float_sdna(prop, nullptr, "arm_head");
1789 RNA_def_property_array(prop, 3);
1792 prop, "Armature-Relative Head", "Location of head end of the bone relative to armature");
1794
1795 prop = RNA_def_property(srna, "length", PROP_FLOAT, PROP_DISTANCE);
1796 RNA_def_property_float_sdna(prop, nullptr, "length");
1798 RNA_def_property_ui_text(prop, "Length", "Length of the bone");
1799
1801
1802 RNA_api_bone(srna);
1803}
1804
1806{
1807 StructRNA *srna;
1808 PropertyRNA *prop;
1809
1810 srna = RNA_def_struct(brna, "EditBone", nullptr);
1811 RNA_def_struct_sdna(srna, "EditBone");
1812 RNA_def_struct_idprops_func(srna, "rna_EditBone_idprops");
1813 RNA_def_struct_ui_text(srna, "Edit Bone", "Edit mode bone in an armature data-block");
1814 RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
1815
1816 prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
1817 RNA_def_property_struct_type(prop, "BoneCollection");
1819 "rna_EditBone_collections_begin",
1820 "rna_iterator_listbase_next",
1821 "rna_iterator_listbase_end",
1822 "rna_Bone_collections_get",
1823 nullptr,
1824 nullptr,
1825 nullptr,
1826 nullptr);
1829 RNA_def_property_ui_text(prop, "Collections", "Bone Collections that contain this bone");
1830
1831 RNA_define_verify_sdna(false); /* not in sdna */
1832
1833 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1834 RNA_def_property_struct_type(prop, "EditBone");
1836 prop, "rna_EditBone_parent_get", "rna_EditBone_parent_set", nullptr, nullptr);
1838 RNA_def_property_ui_text(prop, "Parent", "Parent edit bone (in same Armature)");
1839 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1840
1841 prop = RNA_def_property(srna, "roll", PROP_FLOAT, PROP_ANGLE);
1842 RNA_def_property_float_sdna(prop, nullptr, "roll");
1843 RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
1844 RNA_def_property_ui_text(prop, "Roll", "Bone rotation around head-tail axis");
1846 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1847
1848 prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
1849 RNA_def_property_float_sdna(prop, nullptr, "head");
1851 RNA_def_property_array(prop, 3);
1852 RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone");
1854 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1855
1856 prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
1857 RNA_def_property_float_sdna(prop, nullptr, "tail");
1859 RNA_def_property_array(prop, 3);
1860 RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone");
1862 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1863
1864 prop = RNA_def_property(srna, "length", PROP_FLOAT, PROP_DISTANCE);
1866 prop, "rna_EditBone_length_get", "rna_EditBone_length_set", nullptr);
1869 RNA_def_property_ui_text(prop, "Length", "Length of the bone. Changing moves the tail end.");
1871 RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
1872
1873 rna_def_bone_common(srna, 1);
1874 rna_def_bone_curved_common(srna, false, true);
1875
1876 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1877 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_HIDDEN_A);
1878 RNA_def_property_ui_text(prop, "Hide", "Bone is not visible when in Edit Mode");
1880 RNA_def_property_update(prop, 0, "rna_EditBone_hide_update");
1881
1882 prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
1884 RNA_def_property_ui_text(prop, "Lock", "Bone is not able to be transformed when in Edit Mode");
1886 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1887
1888 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1889 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_SELECTED);
1890 RNA_def_property_ui_text(prop, "Select", "");
1892 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1893
1894 prop = RNA_def_property(srna, "select_head", PROP_BOOLEAN, PROP_NONE);
1895 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_ROOTSEL);
1896 RNA_def_property_ui_text(prop, "Head Select", "");
1898 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1899
1900 prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
1901 RNA_def_property_boolean_sdna(prop, nullptr, "flag", BONE_TIPSEL);
1902 RNA_def_property_ui_text(prop, "Tail Select", "");
1904 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
1905
1906 /* calculated and read only, not actual data access */
1907 prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
1908 // RNA_def_property_float_sdna(prop, nullptr, ""); /* Doesn't access any real data. */
1910 // RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1911 RNA_def_property_flag(prop, PROP_THICK_WRAP); /* no reference to original data */
1913 prop,
1914 "Edit Bone Matrix",
1915 "Matrix combining location and rotation of the bone (head position, direction and roll), "
1916 "in armature space (does not include/support bone's length/size)");
1918 prop, "rna_EditBone_matrix_get", "rna_EditBone_matrix_set", nullptr);
1919
1921
1923}
1924
1925/* `armature.bones.*`. */
1927{
1928 StructRNA *srna;
1929 PropertyRNA *prop;
1930
1931 // FunctionRNA *func;
1932 // PropertyRNA *parm;
1933
1934 RNA_def_property_srna(cprop, "ArmatureBones");
1935 srna = RNA_def_struct(brna, "ArmatureBones", nullptr);
1936 RNA_def_struct_sdna(srna, "bArmature");
1937 RNA_def_struct_ui_text(srna, "Armature Bones", "Collection of armature bones");
1938
1939 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1940 RNA_def_property_struct_type(prop, "Bone");
1941 RNA_def_property_pointer_sdna(prop, nullptr, "act_bone");
1943 RNA_def_property_ui_text(prop, "Active Bone", "Armature's active bone");
1944 RNA_def_property_pointer_funcs(prop, nullptr, "rna_Armature_act_bone_set", nullptr, nullptr);
1945 RNA_def_property_update(prop, 0, "rna_Armature_update");
1946
1947 /* TODO: redraw. */
1948 // RNA_def_property_collection_active(prop, prop_act);
1949}
1950
1951/* `armature.bones.*`. */
1953{
1954 StructRNA *srna;
1955 PropertyRNA *prop;
1956
1957 FunctionRNA *func;
1958 PropertyRNA *parm;
1959
1960 RNA_def_property_srna(cprop, "ArmatureEditBones");
1961 srna = RNA_def_struct(brna, "ArmatureEditBones", nullptr);
1962 RNA_def_struct_sdna(srna, "bArmature");
1963 RNA_def_struct_ui_text(srna, "Armature EditBones", "Collection of armature edit bones");
1964
1965 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1966 RNA_def_property_struct_type(prop, "EditBone");
1967 RNA_def_property_pointer_sdna(prop, nullptr, "act_edbone");
1969 RNA_def_property_ui_text(prop, "Active EditBone", "Armatures active edit bone");
1970 RNA_def_property_update(prop, 0, "rna_Armature_update");
1972 prop, nullptr, "rna_Armature_act_edit_bone_set", nullptr, nullptr);
1973
1974 /* TODO: redraw. */
1975 // RNA_def_property_collection_active(prop, prop_act);
1976
1977 /* add target */
1978 func = RNA_def_function(srna, "new", "rna_Armature_edit_bone_new");
1980 RNA_def_function_ui_description(func, "Add a new bone");
1981 parm = RNA_def_string(func, "name", "Object", 0, "", "New name for the bone");
1983 /* return type */
1984 parm = RNA_def_pointer(func, "bone", "EditBone", "", "Newly created edit bone");
1985 RNA_def_function_return(func, parm);
1986
1987 /* remove target */
1988 func = RNA_def_function(srna, "remove", "rna_Armature_edit_bone_remove");
1990 RNA_def_function_ui_description(func, "Remove an existing bone from the armature");
1991 /* Target to remove. */
1992 parm = RNA_def_pointer(func, "bone", "EditBone", "", "EditBone to remove");
1995}
1996
1999{
2000 StructRNA *srna;
2001 PropertyRNA *prop;
2002
2003 FunctionRNA *func;
2004 PropertyRNA *parm;
2005
2006 RNA_def_property_srna(cprop, "BoneCollections");
2007 srna = RNA_def_struct(brna, "BoneCollections", nullptr);
2008 RNA_def_struct_sdna(srna, "bArmature");
2010 srna, "Armature Bone Collections", "The Bone Collections of this Armature");
2011
2012 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
2013 RNA_def_property_struct_type(prop, "BoneCollection");
2014 RNA_def_property_pointer_sdna(prop, nullptr, "runtime.active_collection");
2018 prop, nullptr, "rna_BoneCollections_active_set", nullptr, nullptr);
2019 RNA_def_property_ui_text(prop, "Active Collection", "Armature's active bone collection");
2021
2022 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
2023 RNA_def_property_int_sdna(prop, nullptr, "runtime.active_collection_index");
2027 prop,
2028 "Active Collection Index",
2029 "The index of the Armature's active bone collection; -1 when there "
2030 "is no active collection. Note that this is indexing the underlying array of bone "
2031 "collections, which may not be in the order you expect. Root collections are listed first, "
2032 "and siblings are always sequential. Apart from that, bone collections can be in any order, "
2033 "and thus incrementing or decrementing this index can make the active bone collection jump "
2034 "around in unexpected ways. For a more predictable interface, use ``active`` or "
2035 "``active_name``.");
2037 "rna_BoneCollections_active_index_get",
2038 "rna_BoneCollections_active_index_set",
2039 "rna_BoneCollections_active_index_range");
2041
2042 prop = RNA_def_property(srna, "active_name", PROP_STRING, PROP_NONE);
2043 RNA_def_property_string_sdna(prop, nullptr, "active_collection_name");
2044 /* TODO: For some reason the overrides system doesn't register a new operation when this property
2045 * changes. Needs further investigation to figure out why & fix it. */
2048 "Active Collection Name",
2049 "The name of the Armature's active bone collection; empty when there "
2050 "is no active collection");
2051 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_BoneCollections_active_name_set");
2053
2054 prop = RNA_def_property(srna, "is_solo_active", PROP_BOOLEAN, PROP_NONE);
2057 prop,
2058 "Solo Active",
2059 "Read-only flag that indicates there is at least one bone collection marked as 'solo'");
2061
2062 /* Armature.collections.new(...) */
2063 func = RNA_def_function(srna, "new", "rna_BoneCollections_new");
2064 RNA_def_function_ui_description(func, "Add a new empty bone collection to the armature");
2066 parm = RNA_def_string(func,
2067 "name",
2068 nullptr,
2069 0,
2070 "Name",
2071 "Name of the new collection. Blender will ensure it is unique within the "
2072 "collections of the Armature.");
2074 parm = RNA_def_pointer(
2075 func,
2076 "parent",
2077 "BoneCollection",
2078 "Parent Collection",
2079 "If not None, the new bone collection becomes a child of this collection");
2080 /* Return value. */
2081 parm = RNA_def_pointer(
2082 func, "bonecollection", "BoneCollection", "", "Newly created bone collection");
2083 RNA_def_function_return(func, parm);
2084
2085 /* Armature.collections.remove(...) */
2086 func = RNA_def_function(srna, "remove", "ANIM_armature_bonecoll_remove");
2088 func,
2089 "Remove the bone collection from the armature. If this bone collection has any children, "
2090 "they will be reassigned to their grandparent; in other words, the children will take the "
2091 "place of the removed bone collection.");
2092 parm = RNA_def_pointer(func,
2093 "bone_collection",
2094 "BoneCollection",
2095 "Bone Collection",
2096 "The bone collection to remove");
2098
2099 /* Armature.collections.move(...) */
2100 func = RNA_def_function(srna, "move", "rna_BoneCollections_move");
2102 "Move a bone collection to a different position in the "
2103 "collection list. This can only be used to reorder siblings, "
2104 "and not to change parent-child relationships.");
2106 parm = RNA_def_int(
2107 func, "from_index", -1, INT_MIN, INT_MAX, "From Index", "Index to move", 0, 10000);
2109 parm = RNA_def_int(func, "to_index", -1, INT_MIN, INT_MAX, "To Index", "Target index", 0, 10000);
2111}
2112
2114{
2115 StructRNA *srna;
2116 PropertyRNA *prop;
2117
2118 FunctionRNA *func;
2119 PropertyRNA *parm;
2120
2121 static const EnumPropertyItem prop_drawtype_items[] = {
2122 {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Display bones as octahedral shape (default)"},
2123 {ARM_LINE, "STICK", 0, "Stick", "Display bones as simple 2D lines with dots"},
2124 {ARM_B_BONE,
2125 "BBONE",
2126 0,
2127 "B-Bone",
2128 "Display bones as boxes, showing subdivision and B-Splines"},
2129 {ARM_ENVELOPE,
2130 "ENVELOPE",
2131 0,
2132 "Envelope",
2133 "Display bones as extruded spheres, showing deformation influence volume"},
2134 {ARM_WIRE,
2135 "WIRE",
2136 0,
2137 "Wire",
2138 "Display bones as thin wires, showing subdivision and B-Splines"},
2139 {0, nullptr, 0, nullptr, nullptr},
2140 };
2141 static const EnumPropertyItem prop_pose_position_items[] = {
2142 {0, "POSE", 0, "Pose Position", "Show armature in posed state"},
2143 {ARM_RESTPOS,
2144 "REST",
2145 0,
2146 "Rest Position",
2147 "Show Armature in binding pose state (no posing possible)"},
2148 {0, nullptr, 0, nullptr, nullptr},
2149 };
2150 static const EnumPropertyItem prop_relation_lines_items[] = {
2151 {0, "TAIL", 0, "Tail", "Draw the relationship line from the parent tail to the child head"},
2152 {1, "HEAD", 0, "Head", "Draw the relationship line from the parent head to the child head"},
2153 {0, nullptr, 0, nullptr, nullptr},
2154 };
2155
2156 srna = RNA_def_struct(brna, "Armature", "ID");
2158 srna,
2159 "Armature",
2160 "Armature data-block containing a hierarchy of bones, usually used for rigging characters");
2161 RNA_def_struct_ui_icon(srna, ICON_ARMATURE_DATA);
2162 RNA_def_struct_sdna(srna, "bArmature");
2163
2164 func = RNA_def_function(srna, "transform", "rna_Armature_transform");
2165 RNA_def_function_ui_description(func, "Transform armature bones by a matrix");
2166 parm = RNA_def_float_matrix(func, "matrix", 4, 4, nullptr, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
2168
2169 /* Animation Data */
2171
2173
2174 /* Collection Properties */
2175 prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
2176 RNA_def_property_collection_sdna(prop, nullptr, "bonebase", nullptr);
2178 nullptr,
2179 "rna_Armature_bones_next",
2180 nullptr,
2181 nullptr,
2182 nullptr,
2183 nullptr,
2184 "rna_Armature_bones_lookup_string",
2185 nullptr);
2186 RNA_def_property_struct_type(prop, "Bone");
2187 RNA_def_property_ui_text(prop, "Bones", "");
2188 rna_def_armature_bones(brna, prop);
2189
2190 prop = RNA_def_property(srna, "edit_bones", PROP_COLLECTION, PROP_NONE);
2191 RNA_def_property_collection_sdna(prop, nullptr, "edbo", nullptr);
2192 RNA_def_property_struct_type(prop, "EditBone");
2193 RNA_def_property_ui_text(prop, "Edit Bones", "");
2194 rna_def_armature_edit_bones(brna, prop);
2195
2196 /* Bone Collection properties. */
2197 prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
2198 RNA_def_property_struct_type(prop, "BoneCollection");
2200 "rna_iterator_bone_collections_roots_begin",
2201 "rna_iterator_array_next",
2202 "rna_iterator_array_end",
2203 "rna_iterator_array_dereference_get",
2204 "rna_iterator_bone_collections_roots_length",
2205 nullptr, /* TODO */
2206 nullptr, /* TODO */
2207 nullptr);
2208 RNA_def_property_ui_text(prop, "Bone Collections (Roots)", "");
2211 prop, nullptr, nullptr, "rna_Armature_collections_override_apply");
2214 rna_def_armature_collections(brna, prop);
2215
2216 prop = RNA_def_property(srna, "collections_all", PROP_COLLECTION, PROP_NONE);
2217 RNA_def_property_struct_type(prop, "BoneCollection");
2219 "rna_iterator_bone_collections_all_begin",
2220 "rna_iterator_array_next",
2221 "rna_iterator_array_end",
2222 "rna_iterator_array_dereference_get",
2223 "rna_iterator_bone_collections_all_length",
2224 nullptr, /* TODO */
2225 nullptr, /* TODO */
2226 nullptr);
2228 prop, "Bone Collections (All)", "List of all bone collections of the armature");
2230 /* Overrides on `armature.collections_all` are only there to override specific properties, like
2231 * is_visible.
2232 *
2233 * New Bone collections are added as overrides via the `armature.collections` (the roots)
2234 * property. It's up to its 'apply' function to also copy the children of a
2235 * library-override-added root. */
2237
2238 /* Enum values */
2239 prop = RNA_def_property(srna, "pose_position", PROP_ENUM, PROP_NONE);
2240 RNA_def_property_enum_bitflag_sdna(prop, nullptr, "flag");
2241 RNA_def_property_enum_items(prop, prop_pose_position_items);
2243 prop, "Pose Position", "Show armature in binding pose or final posed state");
2244 RNA_def_property_update(prop, 0, "rna_Armature_update_data");
2246
2247 prop = RNA_def_property(srna, "display_type", PROP_ENUM, PROP_NONE);
2248 RNA_def_property_enum_sdna(prop, nullptr, "drawtype");
2249 RNA_def_property_enum_items(prop, prop_drawtype_items);
2250 RNA_def_property_ui_text(prop, "Display Type", "");
2251 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2253
2254 /* flag */
2255 prop = RNA_def_property(srna, "show_axes", PROP_BOOLEAN, PROP_NONE);
2256 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ARM_DRAWAXES);
2257 RNA_def_property_ui_text(prop, "Display Axes", "Display bone axes");
2258 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2260
2261 prop = RNA_def_property(srna, "axes_position", PROP_FLOAT, PROP_FACTOR);
2262 RNA_def_property_float_sdna(prop, nullptr, "axes_position");
2263 RNA_def_property_range(prop, 0.0, 1.0);
2264 RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 1);
2266 "Axes Position",
2267 "The position for the axes on the bone. Increasing the value moves it "
2268 "closer to the tip; decreasing moves it closer to the root.");
2269 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2270
2271 RNA_define_verify_sdna(false); /* This property does not live in DNA. */
2272 prop = RNA_def_property(srna, "relation_line_position", PROP_ENUM, PROP_NONE);
2273 RNA_def_property_enum_items(prop, prop_relation_lines_items);
2275 "Relation Line Position",
2276 "The start position of the relation lines from parent to child bones");
2277 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2280 "rna_Armature_relation_line_position_get",
2281 "rna_Armature_relation_line_position_set",
2282 nullptr);
2283 RNA_define_verify_sdna(true); /* Restore default. */
2284
2285 prop = RNA_def_property(srna, "show_names", PROP_BOOLEAN, PROP_NONE);
2286 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ARM_DRAWNAMES);
2287 RNA_def_property_ui_text(prop, "Display Names", "Display bone names");
2288 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2290
2291 prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
2292 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ARM_MIRROR_EDIT);
2294 prop, "X-Axis Mirror", "Apply changes to matching bone on opposite side of X-Axis");
2295 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2297
2298 prop = RNA_def_property(srna, "show_bone_custom_shapes", PROP_BOOLEAN, PROP_NONE);
2301 prop, "Display Custom Bone Shapes", "Display bones with their custom shapes");
2302 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2303
2304 prop = RNA_def_property(srna, "show_bone_colors", PROP_BOOLEAN, PROP_NONE);
2305 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ARM_COL_CUSTOM);
2306 RNA_def_property_ui_text(prop, "Display Bone Colors", "Display bone colors");
2307 RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
2308
2309 prop = RNA_def_property(srna, "is_editmode", PROP_BOOLEAN, PROP_NONE);
2310 RNA_def_property_boolean_funcs(prop, "rna_Armature_is_editmode_get", nullptr);
2312 RNA_def_property_ui_text(prop, "Is Editmode", "True when used in editmode");
2313
2315}
2316
2318{
2319 StructRNA *srna;
2320 PropertyRNA *prop;
2321
2322 srna = RNA_def_struct(brna, "BoneCollection", nullptr);
2323 RNA_def_struct_ui_text(srna, "BoneCollection", "Bone collection in an Armature data-block");
2324 RNA_def_struct_path_func(srna, "rna_BoneCollection_path");
2325 RNA_def_struct_idprops_func(srna, "rna_BoneCollection_idprops");
2326
2327 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2328 RNA_def_property_string_sdna(prop, nullptr, "name");
2329 RNA_def_property_ui_text(prop, "Name", "Unique within the Armature");
2330 RNA_def_struct_name_property(srna, prop);
2331 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_BoneCollection_name_set");
2333
2334 prop = RNA_def_property(srna, "is_expanded", PROP_BOOLEAN, PROP_NONE);
2337 prop, "Expanded", "This bone collection is expanded in the bone collections tree view");
2340 RNA_def_property_boolean_funcs(prop, nullptr, "rna_BoneCollection_is_expanded_set");
2342
2343 prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE);
2346 prop, "Visible", "Bones in this collection will be visible in pose/object mode");
2349 RNA_def_property_boolean_funcs(prop, nullptr, "rna_BoneCollection_is_visible_set");
2351
2352 prop = RNA_def_property(srna, "is_visible_ancestors", PROP_BOOLEAN, PROP_NONE);
2355 "Ancestors Effectively Visible",
2356 "True when all of the ancestors of this bone collection are marked as "
2357 "visible; always True for root bone collections");
2359
2360 prop = RNA_def_property(srna, "is_visible_effectively", PROP_BOOLEAN, PROP_NONE);
2361 RNA_def_property_boolean_funcs(prop, "rna_BoneCollection_is_visible_effectively_get", nullptr);
2363 prop,
2364 "Effective Visibility",
2365 "Whether this bone collection is effectively visible in the viewport. This is True when "
2366 "this bone collection and all of its ancestors are visible, or when it is marked as "
2367 "'solo'.");
2369
2370 prop = RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE);
2371 RNA_def_property_boolean_sdna(prop, nullptr, "flags", BONE_COLLECTION_SOLO);
2373 prop, "Solo", "Show only this bone collection, and others also marked as 'solo'");
2376 RNA_def_property_boolean_funcs(prop, nullptr, "rna_BoneCollection_is_solo_set");
2378
2379 prop = RNA_def_property(srna, "is_local_override", PROP_BOOLEAN, PROP_NONE);
2382 prop,
2383 "Is Local Override",
2384 "This collection was added via a library override in the current blend file");
2386
2387 prop = RNA_def_property(srna, "is_editable", PROP_BOOLEAN, PROP_NONE);
2388 RNA_def_property_boolean_funcs(prop, "rna_BoneCollection_is_editable_get", nullptr);
2390 "Is Editable",
2391 "This collection is owned by a local Armature, or was added via a "
2392 "library override in the current blend file");
2394
2395 prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
2396 RNA_def_property_struct_type(prop, "Bone");
2398 "rna_BoneCollection_bones_begin",
2399 "rna_iterator_listbase_next",
2400 "rna_iterator_listbase_end",
2401 "rna_BoneCollection_bones_get",
2402 nullptr,
2403 nullptr,
2404 nullptr,
2405 nullptr);
2409 "Bones",
2410 "Bones assigned to this bone collection. In armature edit mode this "
2411 "will always return an empty list of bones, as the bone collection "
2412 "memberships are only synchronized when exiting edit mode.");
2413
2414 prop = RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
2415 RNA_def_property_struct_type(prop, "BoneCollection");
2417 "rna_iterator_bone_collection_children_begin",
2418 "rna_iterator_array_next",
2419 "rna_iterator_array_end",
2420 "rna_iterator_array_dereference_get",
2421 "rna_iterator_bone_collection_children_length",
2422 nullptr, /* TODO */
2423 nullptr, /* TODO */
2424 nullptr);
2427
2428 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
2429 RNA_def_property_struct_type(prop, "BoneCollection");
2433 prop, "rna_BoneCollection_parent_get", "rna_BoneCollection_parent_set", nullptr, nullptr);
2435 "Parent",
2436 "Parent bone collection. Note that accessing this requires a scan of "
2437 "all the bone collections to find the parent.");
2438
2439 prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
2440 RNA_def_property_int_funcs(prop, "rna_BoneCollection_index_get", nullptr, nullptr);
2444 prop,
2445 "Index",
2446 "Index of this bone collection in the armature.collections_all array. Note that finding "
2447 "this index requires a scan of all the bone collections, so do access this with care.");
2448
2449 prop = RNA_def_property(srna, "child_number", PROP_INT, PROP_NONE);
2452 prop, "rna_BoneCollection_child_number_get", "rna_BoneCollection_child_number_set", nullptr);
2454 prop,
2455 "Child Number",
2456 "Index of this collection into its parent's list of children. Note that finding "
2457 "this index requires a scan of all the bone collections, so do access this with care.");
2458
2460}
2461
2463{
2464 rna_def_bonecolor(brna);
2466 rna_def_armature(brna);
2467 rna_def_bone(brna);
2468 rna_def_edit_bone(brna);
2469}
2470
2471#endif
Iterators for armatures.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_armature_bonecoll_active_set(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_is_editable(const bArmature *armature, const BoneCollection *bcoll)
BoneCollection * ANIM_armature_bonecoll_insert_copy_after(bArmature *armature_dst, const bArmature *armature_src, const BoneCollection *anchor_in_dst, const BoneCollection *bcoll_to_copy)
void ANIM_armature_bonecoll_is_expanded_set(BoneCollection *bcoll, bool is_expanded)
void ANIM_armature_bonecoll_active_name_set(bArmature *armature, const char *name)
void ANIM_armature_bonecoll_unassign_all(Bone *bone)
bool ANIM_armature_bonecoll_move_to_index(bArmature *armature, int from_index, int to_index)
bool ANIM_armature_bonecoll_is_visible_effectively(const bArmature *armature, const BoneCollection *bcoll)
void ANIM_armature_bonecoll_name_set(bArmature *armature, BoneCollection *bcoll, const char *name)
void ANIM_armature_bonecoll_solo_set(bArmature *armature, BoneCollection *bcoll, bool is_solo)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, int parent_index=-1)
void ANIM_armature_bonecoll_is_visible_set(bArmature *armature, BoneCollection *bcoll, bool is_visible)
void ANIM_armature_bonecoll_active_index_set(bArmature *armature, int bone_collection_index)
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pchan_rebuild_bbone_handles(bPose *pose, bPoseChannel *pchan)
Definition armature.cc:2750
Bone * BKE_armature_find_bone_name(bArmature *arm, const char *name)
Definition armature.cc:779
#define G_MAIN
bool BKE_id_is_in_global_main(ID *id)
Definition lib_id.cc:2433
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define LISTBASE_FOREACH(type, var, list)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
#define M_PI
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE float normalize_v3(float n[3])
#define STRNCPY(dst, src)
Definition BLI_string.h:593
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define BLI_STR_UTF8_MULTIPLICATION_SIGN
#define BLT_I18NCONTEXT_ID_ARMATURE
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ LIBOVERRIDE_OP_REPLACE
Definition DNA_ID.h:229
@ LIBOVERRIDE_OP_INSERT_AFTER
Definition DNA_ID.h:239
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
@ ID_AR
@ ID_OB
@ BONE_COLLECTION_VISIBLE
@ BONE_COLLECTION_ANCESTORS_VISIBLE
@ BONE_COLLECTION_SOLO
@ BONE_COLLECTION_EXPANDED
@ BONE_COLLECTION_OVERRIDE_LIBRARY_LOCAL
@ BBONE_MAPPING_STRAIGHT
@ BBONE_MAPPING_CURVED
@ BBONE_HANDLE_AUTO
@ BBONE_HANDLE_TANGENT
@ BBONE_HANDLE_ABSOLUTE
@ BBONE_HANDLE_RELATIVE
@ BONE_ROOTSEL
@ BONE_DRAWWIRE
@ BONE_SELECTED
@ BONE_NO_CYCLICOFFSET
@ BONE_UNSELECTABLE
@ BONE_HIDDEN_A
@ BONE_EDITMODE_LOCKED
@ BONE_NO_LOCAL_LOCATION
@ BONE_MULT_VG_ENV
@ BONE_HIDDEN_P
@ BONE_TIPSEL
@ BONE_NO_DEFORM
@ BONE_CONNECTED
@ BONE_RELATIVE_PARENTING
@ BONE_HINGE
@ ARM_DRAW_RELATION_FROM_HEAD
@ ARM_NO_CUSTOM
@ ARM_HAS_VIZ_DEPS
@ ARM_COL_CUSTOM
@ ARM_DRAWNAMES
@ ARM_BCOLL_SOLO_ACTIVE
@ ARM_MIRROR_EDIT
@ ARM_DRAWAXES
@ ARM_RESTPOS
@ ARM_B_BONE
@ ARM_ENVELOPE
@ BBONE_ADD_PARENT_END_ROLL
@ BBONE_SCALE_EASING
@ BBONE_HANDLE_SCALE_EASE
@ BBONE_HANDLE_SCALE_X
@ BONE_INHERIT_SCALE_FULL
@ BONE_INHERIT_SCALE_NONE
@ BONE_INHERIT_SCALE_FIX_SHEAR
@ BONE_INHERIT_SCALE_NONE_LEGACY
@ BONE_INHERIT_SCALE_ALIGNED
@ BONE_INHERIT_SCALE_AVERAGE
Object is a sort of wrapper for general info.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
#define RNA_POINTER_INVALIDATE(ptr)
ParameterFlag
Definition RNA_types.hh:396
@ PARM_RNAPTR
Definition RNA_types.hh:399
@ PARM_REQUIRED
Definition RNA_types.hh:397
@ FUNC_USE_REPORTS
Definition RNA_types.hh:680
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_BOOLEAN
Definition RNA_types.hh:65
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_INT
Definition RNA_types.hh:66
@ PROP_STRING
Definition RNA_types.hh:68
@ PROP_POINTER
Definition RNA_types.hh:70
@ PROP_COLLECTION
Definition RNA_types.hh:71
#define RNA_TRANSLATION_PREC_DEFAULT
Definition RNA_types.hh:127
@ PROPOVERRIDE_OVERRIDABLE_LIBRARY
Definition RNA_types.hh:355
@ PROPOVERRIDE_NO_COMPARISON
Definition RNA_types.hh:363
@ PROPOVERRIDE_IGNORE
Definition RNA_types.hh:375
@ PROPOVERRIDE_LIBRARY_INSERTION
Definition RNA_types.hh:380
PropertyFlag
Definition RNA_types.hh:201
@ PROP_THICK_WRAP
Definition RNA_types.hh:312
@ PROP_ANIMATABLE
Definition RNA_types.hh:220
@ PROP_PROPORTIONAL
Definition RNA_types.hh:250
@ PROP_EDITABLE
Definition RNA_types.hh:207
@ PROP_LIB_EXCEPTION
Definition RNA_types.hh:213
@ PROP_NEVER_NULL
Definition RNA_types.hh:266
@ PROP_PTR_NO_OWNERSHIP
Definition RNA_types.hh:284
@ PROP_MATRIX
Definition RNA_types.hh:168
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_DISTANCE
Definition RNA_types.hh:159
@ PROP_ANGLE
Definition RNA_types.hh:155
@ PROP_NONE
Definition RNA_types.hh:136
@ PROP_FACTOR
Definition RNA_types.hh:154
@ PROP_TRANSLATION
Definition RNA_types.hh:164
constexpr PointerRNA PointerRNA_NULL
Definition RNA_types.hh:45
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
#define NC_ANIMATION
Definition WM_types.hh:355
#define ND_POSE
Definition WM_types.hh:425
#define ND_BONE_COLLECTION
Definition WM_types.hh:441
#define NA_RENAME
Definition WM_types.hh:554
#define ND_BONE_SELECT
Definition WM_types.hh:427
#define NC_OBJECT
Definition WM_types.hh:346
#define ND_ANIMCHAN
Definition WM_types.hh:463
EditBone * ED_armature_ebone_add(bArmature *arm, const char *name)
void ED_armature_transform(bArmature *arm, const float mat[4][4], const bool do_props)
void ED_armature_bone_rename(Main *bmain, bArmature *arm, const char *oldnamep, const char *newnamep)
void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bool check_select)
void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4])
void ED_armature_ebone_remove(bArmature *arm, EditBone *exBone)
void ED_armature_ebone_from_mat4(EditBone *ebone, const float mat[4][4])
PyObject * self
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
#define printf
#define offsetof(t, d)
int count
#define GS(x)
Definition iris.cc:202
static void ANIM_armature_foreach_bone(ListBase *bones, CB callback)
int armature_bonecoll_child_number_find(const bArmature *armature, const ::BoneCollection *bcoll)
int armature_bonecoll_find_index(const bArmature *armature, const ::BoneCollection *bcoll)
bool armature_bonecoll_is_descendant_of(const bArmature *armature, int potential_parent_index, int potential_descendant_index)
int armature_bonecoll_find_parent_index(const bArmature *armature, int bcoll_index)
int armature_bonecoll_child_number_set(bArmature *armature, ::BoneCollection *bcoll, int new_child_number)
int armature_bonecoll_move_to_parent(bArmature *armature, int from_bcoll_index, int to_child_num, int from_parent_index, int to_parent_index)
void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, bool free_ptr, IteratorSkipFunc skip)
void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
PointerRNA rna_pointer_inherit_refine(const PointerRNA *ptr, StructRNA *type, void *data)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
void rna_def_animdata_common(StructRNA *srna)
static void rna_def_armature_collections(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_bone_collection_memberships(BlenderRNA *brna, PropertyRNA *cprop)
void RNA_def_armature(BlenderRNA *brna)
static void rna_def_bone(BlenderRNA *brna)
static void rna_def_bonecollection(BlenderRNA *brna)
const EnumPropertyItem rna_enum_color_palettes_items[]
#define RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone)
static void rna_def_bone_common(StructRNA *srna, int editbone)
static void rna_def_edit_bone(BlenderRNA *brna)
static void rna_def_armature(BlenderRNA *brna)
static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop)
void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone, bool is_editbone)
static void rna_def_armature_bones(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_bonecolor(BlenderRNA *brna)
void RNA_api_armature_edit_bone(StructRNA *srna)
void RNA_api_bone(StructRNA *srna)
void RNA_api_bonecollection(StructRNA *srna)
void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_define_lib_overridable(const bool make_overridable)
void RNA_def_struct_path_func(StructRNA *srna, const char *path)
void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t bit)
void RNA_def_parameter_clear_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_define_verify_sdna(bool verify)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
void RNA_def_property_srna(PropertyRNA *prop, const char *type)
PropertyRNA * RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, const int rows, const int columns, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
const float rna_default_scale_3d[3]
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
void RNA_def_property_array(PropertyRNA *prop, int length)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
const int rna_matrix_dimsize_4x4[]
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_def_function_flag(FunctionRNA *func, int flag)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
const int rna_matrix_dimsize_3x3[]
void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
void RNA_def_struct_idprops_func(StructRNA *srna, const char *idproperties)
void RNA_def_property_override_funcs(PropertyRNA *prop, const char *diff, const char *store, const char *apply)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t booleanbit)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
signed int int32_t
Definition stdint.h:77
unsigned char uint8_t
Definition stdint.h:78
struct IDProperty * prop
char name[64]
IDProperty * prop
union CollectionPropertyIterator::@007202232026116251301165241340012352366154236373 internal
ListBaseIterator listbase
Definition RNA_types.hh:455
char name[64]
float tail[3]
IDProperty * prop
EditBone * parent
EditBone * next
EditBone * bbone_prev
EditBone * bbone_next
float head[3]
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
void * first
struct bPose * pose
ID * owner_id
Definition RNA_types.hh:40
void * data
Definition RNA_types.hh:42
IDOverrideLibraryPropertyOperation * liboverride_operation
struct BoneCollection ** collection_array
ListBase * edbo
struct Bone * bone
ListBase chanbase
float max
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126