45constexpr auto bonecoll_default_name =
"Bones";
55 if (
name ==
nullptr ||
name[0] ==
'\0') {
65 bcoll->
flags = default_flags;
73 "bone collection still has bones assigned to it, will cause dangling pointers in "
94 BLI_addtail(&member->bone->runtime.collections, ref);
118 [&](
Bone *bone) { BLI_freelistN(&bone->runtime.collections); });
132 if (bcoll_iter != bcoll && bcoll_iter->
name ==
name) {
140 DATA_(bonecoll_default_name),
143 sizeof(bcoll->
name));
155 BLI_assert(index <= armature->collection_array_num);
179 BLI_assert(at_index <= armature->collection_root_count);
192 const int parent_index)
194 BLI_assert_msg(parent_index >= 0,
"Armature bone collection index should be 0 or larger");
196 "Parent bone collection index should not point beyond the end of the array");
209 return insert_at_index;
214 const int parent_index)
225 if (parent_index < 0) {
291 const int parent_bcoll_dst_index,
295 "this function can only add children to another collection, it cannot add roots");
312 for (
int bcoll_src_index = parent_bcoll_src->
child_index;
313 bcoll_src_index < parent_bcoll_src->child_index + parent_bcoll_src->
child_count;
320 armature_dst, bcoll_dst, parent_bcoll_dst_index);
325 "expecting children to be added to the array AFTER their parent");
327 (void)bcoll_index_dst;
337 BLI_assert_msg(new_parent_bcoll_dst_index == parent_bcoll_dst_index,
338 "did not expect parent_bcoll_dst_index to change");
343 "all children should have been copied");
344 for (
int child_num = 0; child_num < parent_bcoll_dst->
child_count; child_num++) {
345 const int bcoll_src_index = parent_bcoll_src->
child_index + child_num;
346 const int bcoll_dst_index = parent_bcoll_dst->
child_index + child_num;
365 "Armature \"%s\" has library override operation that adds non-root bone collection "
366 "\"%s\". This is unexpected, please file a bug report.\n",
367 armature_src->
id.
name + 2,
368 bcoll_to_copy->
name);
375 const int bcoll_index = anchor_index + 1;
377 bcoll_index <= armature_dst->collection_root_count,
378 "did not expect library override to add a child bone collection, only roots are expected");
399 if (bcoll ==
nullptr) {
439 if (active_name.empty()) {
446 if (bcoll->name == active_name) {
478 const int from_index,
482 from_index == to_index)
495 if (parent_index < 0) {
504 const int old_parent_child_index = parent_bcoll->
child_index;
508 parent_bcoll->
child_index = old_parent_child_index;
514 const int parent_bcoll_index,
515 const int bcoll_index)
517 if (parent_bcoll_index < 0) {
528 const int from_index,
535 if (from_parent_index != to_parent_index) {
543 armature, from_index, to_child_num, from_parent_index, to_parent_index);
547 switch (before_after) {
549 if (to_index > from_index) {
556 if (to_index < from_index) {
571 if (bcoll ==
nullptr) {
576 const int to_index = bcoll_index +
step;
588 char old_name[
sizeof(bcoll->
name)];
592 if (
name[0] ==
'\0') {
611 BLI_assert(0 <= index && index < armature->collection_array_num);
640 BLI_assert_msg(index >= 0,
"could not find bone collection after moving things around");
642 if (parent_bcoll_index >= 0) {
644 armature, parent_bcoll, parent_bcoll_index);
646 "could not find bone collection parent after moving things around");
653 if (parent_bcoll_index < 0) {
674 if (active_collection_index >= 0) {
683 else if (active_collection_index > 0 &&
685 armature, parent_bcoll_index, active_collection_index - 1))
697 const bool is_solo = bcoll->is_solo();
713template<
typename MaybeConstBoneCollection>
717 for (MaybeConstBoneCollection *bcoll : bonecolls) {
744 for (
BoneCollection *bcoll : armature->collection_children(parent_bcoll)) {
753 if (!parent_bcoll->is_visible_with_ancestors()) {
763 for (
BoneCollection *bcoll : armature->collection_children(parent_bcoll)) {
774 if (parent_bcoll ==
nullptr || parent_bcoll->is_visible_with_ancestors()) {
797 const bool is_visible)
826 bool any_bcoll_solo =
false;
827 for (
const BoneCollection *bcoll : armature->collections_span()) {
829 any_bcoll_solo =
true;
834 if (any_bcoll_solo) {
847 if (is_solo_active) {
849 return bcoll->is_solo();
852 return bcoll->is_visible_with_ancestors();
884 if (member->bone == bone) {
899 if (ref->bcoll == bcoll) {
928 bool was_found =
false;
932 if (member->bone == bone) {
943 if (ref->bcoll == bcoll) {
970 bool was_found =
false;
974 if (ref->bcoll == bcoll) {
992 LISTBASE_FOREACH (BoneCollectionReference *, ref, &bone->runtime.collections) {
993 add_membership(ref->bcoll, bone);
1056 if (bcoll == bcoll_ref->bcoll) {
1066 if (armature->
edbo) {
1121 for (
const BoneCollection *arm_bcoll : armature->collections_span()) {
1122 if (arm_bcoll == bcoll) {
1133 if (bcoll_index < armature->collection_root_count) {
1139 for (
const BoneCollection *potential_parent : armature->collections_span()) {
1140 if (potential_parent->child_index <= bcoll_index &&
1141 bcoll_index < potential_parent->child_index + potential_parent->child_count)
1161 int new_child_number)
1170 if (parent_index < 0) {
1171 parent_bcoll = &fake_armature_parent;
1178 if (new_child_number >= parent_bcoll->
child_count) {
1181 if (new_child_number < 0) {
1187 const int old_parent_child_index = parent_bcoll->
child_index;
1188 const int to_index = parent_bcoll->
child_index + new_child_number;
1191 parent_bcoll->
child_index = old_parent_child_index;
1208 const int potential_parent_index,
1209 const int potential_child_index)
1213 return potential_parent_index == -1;
1215 if (potential_parent_index < 0) {
1222 return potential_parent->
child_index <= potential_child_index &&
1223 potential_child_index < upper_bound;
1227 const int potential_parent_index,
1228 const int potential_descendant_index)
1231 "Potential descendant has to exist for this function call to make sense.");
1242 for (
int visit_index = potential_parent->
child_index; visit_index < upper_bound; visit_index++) {
1267 auto find_old = [bcolls_source](
const char *
name,
const int index) ->
const BoneCollection * {
1269 if (index < bcolls_source.
size()) {
1283 for (
int i = 0;
i < bcolls_dest.
size();
i++) {
1296 const int from_bcoll_index,
1298 const int from_parent_index,
1299 const int to_parent_index)
1301 BLI_assert(0 <= from_bcoll_index && from_bcoll_index < armature->collection_array_num);
1302 BLI_assert(-1 <= from_parent_index && from_parent_index < armature->collection_array_num);
1303 BLI_assert(-1 <= to_parent_index && to_parent_index < armature->collection_array_num);
1305 if (from_parent_index == to_parent_index) {
1307 return from_bcoll_index;
1316 armature_root.
flags = default_flags;
1324 BLI_assert_msg(-1 <= to_child_num && to_child_num <= to_parent->child_count,
1325 "to_child_num must point to an index of a child of the new parent, or the index "
1326 "of the last child + 1, or be -1 to indicate 'after last child'");
1327 if (to_child_num < 0) {
1338 to_bcoll_index = to_parent->
child_index + to_child_num;
1343 if (to_bcoll_index > from_bcoll_index) {
1351 const bool needs_post_move_child_index_bump = from_parent->
child_index == from_bcoll_index &&
1352 to_bcoll_index <= from_bcoll_index;
1355 const bool becomes_new_first_child = to_child_num == 0 || to_parent->
child_count == 0;
1364 else if (needs_post_move_child_index_bump) {
1375 if (becomes_new_first_child) {
1387 return to_bcoll_index;
1394 int *bcoll_array_dst_num,
1396 const int bcoll_array_src_num,
1397 const bool do_id_user)
1403 *bcoll_array_dst_num = bcoll_array_src_num;
1406 for (
int i = 0;
i < bcoll_array_src_num;
i++) {
1413 if (bcoll_src->
prop) {
1422 (*bcoll_array_dst)[
i] = bcoll_dst;
1424 bcoll_map.
add(bcoll_src, bcoll_dst);
1431 int *bcoll_array_num,
1432 const bool do_id_user)
1434 for (
int i = 0;
i < *bcoll_array_num;
i++) {
1455 *bcoll_array_num = 0;
1462 const int start_index,
1464 const int direction)
1466 BLI_assert_msg(direction == 1 || direction == -1,
"`direction` must be either -1 or +1");
1482 const int move_from_index = (direction > 0 ? start_index +
count : start_index - 1);
1483 const int move_to_index = (direction > 0 ? start_index : start_index +
count - 1);
1495 if (bcoll->child_index == 0 && bcoll->child_count == 0) {
1501 if (start_index <= bcoll->child_index && bcoll->child_index < start_index +
count) {
1502 bcoll->child_index += direction;
1508 if (active_index == move_from_index) {
1511 else if (start_index <= active_index && active_index < start_index +
count) {
1518 if (from_index == to_index) {
1523 BLI_assert(from_index < armature->collection_array_num);
1525 BLI_assert(to_index < armature->collection_array_num);
1527 if (from_index < to_index) {
1528 const int block_start_index = from_index + 1;
1529 const int block_count = to_index - from_index;
1533 const int block_start_index = to_index;
1534 const int block_count = from_index - to_index;
1543 if (collections[index] == bcoll) {
1546 if (index > 0 && collections[index - 1] == bcoll) {
1549 if (index < armature->collection_array_num - 1 && collections[index + 1] == bcoll) {
1557 printf(
"\033[38;5;214mBone collections of armature \"%s\":\033[0m\n", armature->
id.
name + 2);
1558 constexpr int root_ansi_color = 95;
1563 printf(
" - \033[%dmcolls[%d] = %24s\033[0m ",
1583 if (armature->
edbo) {
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_armature_bonecoll_is_expanded_set(BoneCollection *bcoll, bool is_expanded)
bool ANIM_armature_bonecoll_unassign_editbone(BoneCollection *bcoll, EditBone *ebone)
void ANIM_bonecoll_free(BoneCollection *bcoll, bool do_id_user_count=true)
bool ANIM_armature_bonecoll_unassign(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_active_index_set(bArmature *armature, int bone_collection_index)
void BKE_animdata_fix_paths_rename_all(struct ID *ref_id, const char *prefix, const char *oldName, const char *newName)
Bone * BKE_armature_find_bone_name(bArmature *arm, const char *name)
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_FreeProperty_ex(IDProperty *prop, bool do_id_user)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
#define BLI_assert_msg(a, msg)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
char * STRNCPY(char(&dst)[N], const char *src)
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ BONE_COLLECTION_VISIBLE
@ BONE_COLLECTION_SELECTABLE
@ BONE_COLLECTION_ANCESTORS_VISIBLE
@ BONE_COLLECTION_EXPANDED
@ BONE_COLLECTION_OVERRIDE_LIBRARY_LOCAL
Read Guarded memory(de)allocation.
#define ND_BONE_COLLECTION
void ANIM_armature_bonecoll_unassign_all_editbone(EditBone *ebone)
void ANIM_armature_refresh_solo_active(bArmature *armature)
static void add_membership(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_runtime_free(bArmature *armature)
void ANIM_armature_bonecoll_remove_from_index(bArmature *armature, int index)
bool ANIM_armature_bonecoll_assign_and_move(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_active_set(bArmature *armature, BoneCollection *bcoll)
static void bonecoll_insert_at_index(bArmature *armature, BoneCollection *bcoll, const int index)
static void bonecoll_insert_as_root(bArmature *armature, BoneCollection *bcoll, int at_index)
void ANIM_armature_bonecoll_is_visible_set(bArmature *armature, BoneCollection *bcoll, const bool is_visible)
void ANIM_armature_bonecoll_hide_all(bArmature *armature)
bool ANIM_armature_bonecoll_is_editable(const bArmature *armature, const BoneCollection *bcoll)
static void ancestors_visible_update(bArmature *armature, const BoneCollection *parent_bcoll, 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)
bool ANIM_armature_bonecoll_assign_and_move_editbone(BoneCollection *bcoll, EditBone *ebone)
void ANIM_armature_bonecoll_is_expanded_set(BoneCollection *bcoll, bool is_expanded)
void ANIM_armature_bonecoll_active_index_set(bArmature *armature, const int bone_collection_index)
void ANIM_bonecoll_hide(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_move(bArmature *armature, BoneCollection *bcoll, const int step)
static bool any_bone_collection_visible(const bArmature *armature, const ListBase *collection_refs)
bool ANIM_armature_bonecoll_move_to_index(bArmature *armature, const int from_index, const int to_index)
void ANIM_armature_runtime_refresh(bArmature *armature)
void ANIM_armature_bonecoll_active_name_set(bArmature *armature, const char *name)
void ANIM_armature_bonecoll_show_from_ebone(bArmature *armature, const EditBone *ebone)
static MaybeConstBoneCollection * bonecolls_get_by_name(blender::Span< MaybeConstBoneCollection * > bonecolls, const char *name)
void ANIM_armature_bonecoll_show_from_bone(bArmature *armature, const Bone *bone)
static void ancestors_visible_descendants_clear(bArmature *armature, BoneCollection *parent_bcoll)
BoneCollection * ANIM_armature_bonecoll_get_by_name(bArmature *armature, const char *name)
static int bonecoll_insert_as_child(bArmature *armature, BoneCollection *bcoll, const int parent_index)
bool ANIM_bonecoll_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
static void liboverride_recursively_add_children(bArmature *armature_dst, const bArmature *armature_src, const int parent_bcoll_dst_index, const BoneCollection *parent_bcoll_src)
int ANIM_armature_bonecoll_move_before_after_index(bArmature *armature, const int from_index, int to_index, const MoveLocation before_after)
bool ANIM_armature_bonecoll_unassign_editbone(BoneCollection *bcoll, EditBone *ebone)
static void bonecoll_ensure_name_unique(bArmature *armature, BoneCollection *bcoll)
void ANIM_armature_bonecoll_assign_active(const bArmature *armature, EditBone *ebone)
bool ANIM_armature_bonecoll_assign(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_remove(bArmature *armature, BoneCollection *bcoll)
bool ANIM_armature_bonecoll_unassign(BoneCollection *bcoll, Bone *bone)
void ANIM_armature_bonecoll_unassign_all(Bone *bone)
void ANIM_bonecoll_show(bArmature *armature, BoneCollection *bcoll)
void ANIM_armature_bonecoll_show_from_pchan(bArmature *armature, const bPoseChannel *pchan)
void ANIM_armature_bonecoll_active_runtime_refresh(bArmature *armature)
static int bonecoll_child_number(const bArmature *armature, const int parent_bcoll_index, const int bcoll_index)
static void ancestors_visible_descendants_update(bArmature *armature, BoneCollection *parent_bcoll)
static BoneCollection * copy_and_update_ownership(const bArmature *armature_dst, const BoneCollection *bcoll_to_copy)
BoneCollection * ANIM_bonecoll_new(const char *name)
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)
static void add_reference(Bone *bone, BoneCollection *bcoll)
static bool bcoll_list_contains(const ListBase *collection_refs, const BoneCollection *bcoll)
void ANIM_armature_bonecoll_show_all(bArmature *armature)
void ANIM_armature_bonecoll_solo_set(bArmature *armature, BoneCollection *bcoll, const bool is_solo)
void ANIM_bonecoll_free(BoneCollection *bcoll, const bool do_id_user_count)
void ANIM_armature_bonecoll_reconstruct(bArmature *armature)
bool ANIM_armature_bonecoll_contains_active_bone(const bArmature *armature, const BoneCollection *bcoll)
bool ANIM_bone_in_visible_collection(const bArmature *armature, const Bone *bone)
int ANIM_armature_bonecoll_get_index_by_name(bArmature *armature, const char *name)
static void add_reverse_pointers(BoneCollection *bcoll)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, const int parent_index)
static void armature_bonecoll_active_clear(bArmature *armature)
bool ANIM_armature_bonecoll_assign_editbone(BoneCollection *bcoll, EditBone *ebone)
Internal C++ functions to deal with bone collections. These are mostly here for internal use in bone_...
bool add(const Key &key, const Value &value)
constexpr int64_t size() const
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
void bonecolls_rotate_block(bArmature *armature, const int start_index, const int count, const int direction)
void bonecolls_debug_list(const bArmature *armature)
void bonecoll_unassign_and_free(bArmature *armature, BoneCollection *bcoll)
int bonecolls_find_index_near(bArmature *armature, BoneCollection *bcoll, const int index)
void bonecolls_move_to_index(bArmature *armature, const int from_index, const int to_index)
blender::Map< BoneCollection *, BoneCollection * > ANIM_bonecoll_array_copy_no_membership(BoneCollection ***bcoll_array_dst, int *bcoll_array_dst_num, BoneCollection **bcoll_array_src, int bcoll_array_src_num, bool do_id_user)
bool armature_bonecoll_is_root(const bArmature *armature, int bcoll_index)
static void ANIM_armature_foreach_bone(ListBase *bones, CB callback)
void bonecolls_copy_expanded_flag(Span< BoneCollection * > bcolls_dest, Span< const BoneCollection * > bcolls_source)
int armature_bonecoll_child_number_find(const bArmature *armature, const ::BoneCollection *bcoll)
bool bonecoll_has_children(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)
void ANIM_bonecoll_array_free(BoneCollection ***bcoll_array, int *bcoll_array_num, bool do_id_user)
int armature_bonecoll_move_to_parent(bArmature *armature, int from_bcoll_index, int to_child_num, int from_parent_index, int to_parent_index)
bool armature_bonecoll_is_child_of(const bArmature *armature, int potential_parent_index, int potential_child_index)
struct BoneCollection * bcoll
struct IDProperty * system_properties
ListBase bone_collections
int active_collection_index
struct BoneCollection * active_collection
int collection_root_count
struct BoneCollection ** collection_array
char active_collection_name[64]
struct EditBone * act_edbone
struct bArmature_Runtime runtime
void WM_main_add_notifier(uint type, void *reference)