diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-03-26 13:33:53 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-03-26 13:33:53 +0300 |
commit | 40e58c85092945ca71e974ce4062d90e44f7fb66 (patch) | |
tree | b102a091696741d2ab4572f1c259ae8512263d5d /source | |
parent | 6af1f968761b5d94184c68b1ea9dbf88792a1c13 (diff) |
Optimization for pose channel name lookups using a hash, makes
playback in one particular scene with 3 characters go from 10 to 13 fps.
(commit 27728 by Brecht from render25 branch)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_action.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 29 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 3 |
8 files changed, 50 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 1b38e276ca4..214b5a32cd6 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -129,6 +129,13 @@ void free_pose_channel(struct bPoseChannel *pchan); */ void free_pose_channels(struct bPose *pose); +/** + * Removes the hash for quick lookup of channels, must + * be done when adding/removing channels. + */ +void make_pose_channels_hash(struct bPose *pose); +void free_pose_channels_hash(struct bPose *pose); + /** * Removes and deallocates all data from a pose, and also frees the pose. */ diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 52f59c1681a..2d52d6061b9 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -56,8 +56,9 @@ #include "BIK_api.h" -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math.h" #include "RNA_access.h" @@ -370,6 +371,9 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) if (ELEM(NULL, pose, name) || (name[0] == 0)) return NULL; + if(pose->chanhash) + return BLI_ghash_lookup(pose->chanhash, name); + return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name)); } @@ -405,6 +409,7 @@ bPoseChannel *verify_pose_channel(bPose *pose, const char *name) chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */ BLI_addtail(&pose->chanbase, chan); + free_pose_channels_hash(pose); return chan; } @@ -519,6 +524,26 @@ void init_pose_ikparam(bPose *pose) } } +void make_pose_channels_hash(bPose *pose) +{ + if(!pose->chanhash) { + bPoseChannel *pchan; + + pose->chanhash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp); + for(pchan=pose->chanbase.first; pchan; pchan=pchan->next) + BLI_ghash_insert(pose->chanhash, pchan->name, pchan); + } +} + +void free_pose_channels_hash(bPose *pose) +{ + if(pose->chanhash) { + BLI_ghash_free(pose->chanhash, NULL, NULL); + pose->chanhash= NULL; + } +} + + void free_pose_channel(bPoseChannel *pchan) { // XXX this case here will need to be removed when the new motionpaths are ready @@ -550,6 +575,8 @@ void free_pose_channels(bPose *pose) BLI_freelistN(&pose->chanbase); } + + free_pose_channels_hash(pose); } void free_pose(bPose *pose) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 668ce9aadac..c1998d705ad 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1675,6 +1675,7 @@ void armature_rebuild_pose(Object *ob, bArmature *arm) next= pchan->next; if(pchan->bone==NULL) { free_pose_channel(pchan); + free_pose_channels_hash(pose); BLI_freelinkN(&pose->chanbase, pchan); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b9e4894a868..bb7c77408ac 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2459,7 +2459,10 @@ void object_tfm_restore(Object *ob, void *obtfm_pt) void object_handle_update(Scene *scene, Object *ob) { if(ob->recalc & OB_RECALC) { - + /* speed optimization for animation lookups */ + if(ob->pose) + make_pose_channels_hash(ob->pose); + /* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers, which is only in where_is_object now */ if(ob->recalc & OB_RECALC) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5bcf7806a49..768fe1f2c33 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3652,6 +3652,8 @@ static void direct_link_pose(FileData *fd, bPose *pose) link_list(fd, &pose->chanbase); link_list(fd, &pose->agroups); + pose->chanhash= NULL; + for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) { pchan->bone= NULL; pchan->parent= newdataadr(fd, pchan->parent); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index f3b5e49a3ef..478a711aedd 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -892,6 +892,8 @@ int join_armature_exec(bContext *C, wmOperator *op) BLI_remlink(&opose->chanbase, pchan); BLI_addtail(&pose->chanbase, pchan); + free_pose_channels_hash(opose); + free_pose_channels_hash(pose); } ED_base_object_free_and_unlink(scene, base); @@ -1095,6 +1097,7 @@ static void separate_armature_bones (Scene *scene, Object *ob, short sel) /* free any of the extra-data this pchan might have */ free_pose_channel(pchan); + free_pose_channels_hash(ob->pose); /* get rid of unneeded bone */ bone_free(arm, curbone); @@ -1802,6 +1805,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op) if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) { free_pose_channel(pchan); + free_pose_channels_hash(obedit->pose); BLI_freelinkN (&obedit->pose->chanbase, pchan); } else { diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 937dd3ee324..18b3c1095cc 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -40,6 +40,7 @@ struct SpaceLink; struct Object; struct Group; +struct GHash; /* ************************************************ */ /* Visualisation */ @@ -326,6 +327,7 @@ typedef enum eRotationModes { */ typedef struct bPose { ListBase chanbase; /* list of pose channels, PoseBones in RNA */ + struct GHash *chanhash; /* ghash for quicker string lookups */ short flag, proxy_layer; /* proxy layer: copy from armature, gets synced */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 03687a5f366..ff67597a78b 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -37,6 +37,7 @@ #include "DNA_scene_types.h" #include "BLI_math.h" +#include "BLI_ghash.h" #include "WM_types.h" @@ -525,7 +526,7 @@ PointerRNA rna_PoseBones_lookup_string(PointerRNA *ptr, const char *key) { PointerRNA rptr; bPose *pose= (bPose*)ptr->data; - bPoseChannel *pchan= BLI_findstring(&pose->chanbase, key, offsetof(bPoseChannel, name)); + bPoseChannel *pchan= get_pose_channel(pose, key); RNA_pointer_create(ptr->id.data, &RNA_PoseBone, pchan, &rptr); return rptr; } |