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:
authorCampbell Barton <ideasman42@gmail.com>2016-01-09 01:12:06 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-01-09 01:17:18 +0300
commit70028e73dcbf4494c7584be3266268eb44c0ac4b (patch)
tree7401908b40b70705c415e35b4794eb8b8cbfc986 /source/blender/blenloader
parent2d973f44e2fd47fa2fd4c1f59247c56517fcb26c (diff)
Readfile: use hash lookup for bones
Bone loop for reconstructing links was O(n^2)
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 84565fcb89f..fd144c0ebc0 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3185,18 +3185,23 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
{
- bPoseChannel *pchan;
bArmature *arm = ob->data;
- int rebuild = 0;
if (!pose || !arm)
return;
/* always rebuild to match proxy or lib changes, but on Undo */
- if (fd->memfile == NULL)
- if (ob->proxy || (ob->id.lib==NULL && arm->id.lib))
- rebuild = 1;
-
+ bool rebuild = false;
+
+ if (fd->memfile == NULL) {
+ if (ob->proxy || (ob->id.lib==NULL && arm->id.lib)) {
+ rebuild = true;
+ }
+ }
+
+ /* avoid string */
+ GHash *bone_hash = BKE_armature_bone_from_name_map(arm);
+
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer)
@@ -3204,28 +3209,32 @@ 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 = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
- if (bone)
+ Bone *bone = BLI_ghash_lookup(bone_hash, pose->proxy_act_bone);
+ if (bone) {
arm->act_bone = bone;
+ }
}
}
-
- for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
+
+ for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
lib_link_constraints(fd, (ID *)ob, &pchan->constraints);
-
- /* hurms... loop in a loop, but yah... later... (ton) */
- pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
+
+ pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
pchan->custom = newlibadr_us(fd, arm->id.lib, pchan->custom);
- if (pchan->bone == NULL)
- rebuild= 1;
- else if (ob->id.lib==NULL && arm->id.lib) {
+ if (UNLIKELY(pchan->bone == NULL)) {
+ rebuild = true;
+ }
+ else if ((ob->id.lib == NULL) && arm->id.lib) {
/* local pose selection copied to armature, bit hackish */
pchan->bone->flag &= ~BONE_SELECTED;
pchan->bone->flag |= pchan->selectflag;
}
}
+
+ BLI_ghash_free(bone_hash, NULL, NULL);
+
if (rebuild) {
DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_pose_tag_recalc(bmain, pose);