Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_armature.h4
-rw-r--r--source/blender/blenkernel/intern/armature.c51
-rw-r--r--source/blender/blenloader/intern/readfile.c12
-rw-r--r--source/blender/editors/armature/armature_naming.c10
-rw-r--r--source/blender/editors/armature/armature_utils.c3
-rw-r--r--source/blender/makesdna/DNA_armature_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_armature.c25
7 files changed, 80 insertions, 31 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index b5da30e725d..6839e13ffe1 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -84,7 +84,9 @@ bool BKE_pose_minmax(
int bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail);
struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name);
-struct GHash *BKE_armature_bone_from_name_map(struct bArmature *arm);
+
+void BKE_armature_bone_hash_make(struct bArmature *arm);
+void BKE_armature_bone_hash_free(struct bArmature *arm);
bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 60446bf60b6..bd9907acb24 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -125,6 +125,7 @@ void BKE_armature_free(bArmature *arm)
{
BKE_animdata_free(&arm->id, false);
+ BKE_armature_bone_hash_free(arm);
BKE_armature_bonelist_free(&arm->bonebase);
/* free editmode data */
@@ -169,25 +170,20 @@ static void copy_bonechildren(Bone *bone_dst,
}
}
-static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst, GHash **bone_hash)
+static void copy_bonechildren_custom_handles(Bone *bone_dst, bArmature *arm_dst)
{
Bone *bone_dst_child;
- /* Lazily create the name -> bone hashtable. */
- if ((bone_dst->bbone_prev || bone_dst->bbone_next) && *bone_hash == NULL) {
- *bone_hash = BKE_armature_bone_from_name_map(arm_dst);
- }
-
if (bone_dst->bbone_prev) {
- bone_dst->bbone_prev = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_prev->name);
+ bone_dst->bbone_prev = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_prev->name);
}
if (bone_dst->bbone_next) {
- bone_dst->bbone_next = BLI_ghash_lookup(*bone_hash, bone_dst->bbone_next->name);
+ bone_dst->bbone_next = BKE_armature_find_bone_name(arm_dst, bone_dst->bbone_next->name);
}
for (bone_dst_child = bone_dst->childbase.first; bone_dst_child;
bone_dst_child = bone_dst_child->next) {
- copy_bonechildren_custom_handles(bone_dst_child, arm_dst, bone_hash);
+ copy_bonechildren_custom_handles(bone_dst_child, arm_dst);
}
}
@@ -212,6 +208,8 @@ void BKE_armature_copy_data(Main *UNUSED(bmain),
/* We never handle usercount here for own data. */
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+ arm_dst->bonehash = NULL;
+
BLI_duplicatelist(&arm_dst->bonebase, &arm_src->bonebase);
/* Duplicate the childrens' lists */
@@ -224,15 +222,11 @@ void BKE_armature_copy_data(Main *UNUSED(bmain),
arm_dst->act_bone = bone_dst_act;
- /* Fix custom handle references. */
- GHash *bone_hash = NULL; /* lazily created */
+ BKE_armature_bone_hash_make(arm_dst);
+ /* Fix custom handle references. */
for (bone_dst = arm_dst->bonebase.first; bone_dst; bone_dst = bone_dst->next) {
- copy_bonechildren_custom_handles(bone_dst, arm_dst, &bone_hash);
- }
-
- if (bone_hash) {
- BLI_ghash_free(bone_hash, NULL, NULL);
+ copy_bonechildren_custom_handles(bone_dst, arm_dst);
}
arm_dst->edbo = NULL;
@@ -274,6 +268,10 @@ Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name)
return NULL;
}
+ if (arm->bonehash) {
+ return BLI_ghash_lookup(arm->bonehash, name);
+ }
+
return get_named_bone_bonechildren(&arm->bonebase, name);
}
@@ -291,7 +289,7 @@ static void armature_bone_from_name_insert_recursive(GHash *bone_hash, ListBase
* \note typically #bPose.chanhash us used via #BKE_pose_channel_find_name
* this is for the cases we can't use pose channels.
*/
-GHash *BKE_armature_bone_from_name_map(bArmature *arm)
+static GHash *armature_bone_from_name_map(bArmature *arm)
{
const int bones_count = BKE_armature_bonelist_count(&arm->bonebase);
GHash *bone_hash = BLI_ghash_str_new_ex(__func__, bones_count);
@@ -299,6 +297,21 @@ GHash *BKE_armature_bone_from_name_map(bArmature *arm)
return bone_hash;
}
+void BKE_armature_bone_hash_make(bArmature *arm)
+{
+ if (!arm->bonehash) {
+ arm->bonehash = armature_bone_from_name_map(arm);
+ }
+}
+
+void BKE_armature_bone_hash_free(bArmature *arm)
+{
+ if (arm->bonehash) {
+ BLI_ghash_free(arm->bonehash, NULL, NULL);
+ arm->bonehash = NULL;
+ }
+}
+
bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
{
if (bone->flag & flag) {
@@ -2458,11 +2471,9 @@ void BKE_pose_clear_pointers(bPose *pose)
void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
{
- GHash *bone_hash = BKE_armature_bone_from_name_map(armature);
for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
+ pchan->bone = BKE_armature_find_bone_name(armature, pchan->name);
}
- BLI_ghash_free(bone_hash, NULL, NULL);
}
/** Find the matching pose channel using the bone name, if not NULL. */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 400070f12fc..f0e70f1be27 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3763,9 +3763,6 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
}
}
- /* avoid string */
- GHash *bone_hash = BKE_armature_bone_from_name_map(arm);
-
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
@@ -3774,7 +3771,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
- Bone *bone = BLI_ghash_lookup(bone_hash, pose->proxy_act_bone);
+ Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
@@ -3784,7 +3781,7 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
lib_link_constraints(fd, (ID *)ob, &pchan->constraints);
- pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
+ pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
IDP_LibLinkProperty(pchan->prop, fd);
@@ -3799,8 +3796,6 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
}
}
- BLI_ghash_free(bone_hash, NULL, NULL);
-
if (rebuild) {
DEG_id_tag_update_ex(
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
@@ -3858,6 +3853,7 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
Bone *bone;
link_list(fd, &arm->bonebase);
+ arm->bonehash = NULL;
arm->edbo = NULL;
arm->adt = newdataadr(fd, arm->adt);
@@ -3869,6 +3865,8 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
arm->act_bone = newdataadr(fd, arm->act_bone);
arm->act_edbone = NULL;
+
+ BKE_armature_bone_hash_make(arm);
}
/** \} */
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 083967d5d41..9a1582679a4 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -180,7 +180,17 @@ void ED_armature_bone_rename(Main *bmain,
if (bone) {
unique_bone_name(arm, newname);
+
+ if (arm->bonehash) {
+ BLI_assert(BLI_ghash_haskey(arm->bonehash, bone->name));
+ BLI_ghash_remove(arm->bonehash, bone->name, NULL, NULL);
+ }
+
BLI_strncpy(bone->name, newname, MAXBONENAME);
+
+ if (arm->bonehash) {
+ BLI_ghash_insert(arm->bonehash, bone->name, bone);
+ }
}
else {
return;
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index b23081cd6fa..20dc7b6c826 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -650,6 +650,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
Object *obt;
/* armature bones */
+ BKE_armature_bone_hash_free(arm);
BKE_armature_bonelist_free(&arm->bonebase);
arm->act_bone = NULL;
@@ -754,6 +755,8 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
/* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */
armature_finalize_restpose(&arm->bonebase, arm->edbo);
+ BKE_armature_bone_hash_make(arm);
+
/* so all users of this armature should get rebuilt */
for (obt = bmain->objects.first; obt; obt = obt->id.next) {
if (obt->data == arm) {
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 8ae9aa5a041..b18ab503e94 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -104,7 +104,11 @@ typedef struct bArmature {
struct AnimData *adt;
ListBase bonebase;
- ListBase chainbase;
+
+ /** Ghash for quicker lookups of bones by name. */
+ struct GHash *bonehash;
+ void *_pad1;
+
/** Editbone listbase, we use pointer so we can check state. */
ListBase *edbo;
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index d1e3cb1c860..ffd28b4eb76 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -575,6 +575,20 @@ static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
iter->valid = (internal->link != NULL);
}
+/* not essential, but much faster then the default lookup function */
+static int rna_Armature_bones_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bArmature *arm = (bArmature *)ptr->data;
+ Bone *bone = BKE_armature_find_bone_name(arm, key);
+ if (bone) {
+ RNA_pointer_create(ptr->id.data, &RNA_Bone, bone, r_ptr);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static bool rna_Armature_is_editmode_get(PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->id.data;
@@ -1285,8 +1299,15 @@ static void rna_def_armature(BlenderRNA *brna)
/* Collections */
prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
- RNA_def_property_collection_funcs(
- prop, NULL, "rna_Armature_bones_next", NULL, NULL, NULL, NULL, NULL, NULL);
+ RNA_def_property_collection_funcs(prop,
+ NULL,
+ "rna_Armature_bones_next",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "rna_Armature_bones_lookup_string",
+ NULL);
RNA_def_property_struct_type(prop, "Bone");
RNA_def_property_ui_text(prop, "Bones", "");
rna_def_armature_bones(brna, prop);