diff options
-rw-r--r-- | source/blender/blenkernel/BKE_blender_copybuffer.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender_copybuffer.c | 25 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_transform.c | 112 | ||||
-rw-r--r-- | source/blender/editors/include/ED_util.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 1 |
5 files changed, 80 insertions, 62 deletions
diff --git a/source/blender/blenkernel/BKE_blender_copybuffer.h b/source/blender/blenkernel/BKE_blender_copybuffer.h index 8aaf295c33a..02bd96217f6 100644 --- a/source/blender/blenkernel/BKE_blender_copybuffer.h +++ b/source/blender/blenkernel/BKE_blender_copybuffer.h @@ -37,6 +37,7 @@ struct ID; void BKE_copybuffer_begin(struct Main *bmain_src); void BKE_copybuffer_tag_ID(struct ID *id); bool BKE_copybuffer_save(struct Main *bmain_src, const char *filename, struct ReportList *reports); +bool BKE_copybuffer_read(struct Main *bmain_dst, const char *libname, struct ReportList *reports); bool BKE_copybuffer_paste(struct bContext *C, const char *libname, const short flag, struct ReportList *reports); #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c index ad01fac2144..a4c28121040 100644 --- a/source/blender/blenkernel/intern/blender_copybuffer.c +++ b/source/blender/blenkernel/intern/blender_copybuffer.c @@ -85,6 +85,31 @@ bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *repo return retval; } +bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports) +{ + BlendHandle *bh = BLO_blendhandle_from_file(libname, reports); + if (bh == NULL) { + /* Error reports will have been made by BLO_blendhandle_from_file(). */ + return false; + } + /* Here appending/linking starts. */ + Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname); + BLO_library_link_copypaste(mainl, bh); + BLO_library_link_end(mainl, &bh, 0, NULL, NULL); + /* Mark all library linked objects to be updated. */ + BKE_main_lib_objects_recalc_all(bmain_dst); + IMB_colormanagement_check_file_config(bmain_dst); + /* Append, rather than linking. */ + Library *lib = BLI_findstring(&bmain_dst->library, libname, offsetof(Library, filepath)); + BKE_library_make_local(bmain_dst, lib, true, false); + /* Important we unset, otherwise these object wont + * link into other scenes from this blend file. + */ + BKE_main_id_tag_all(bmain_dst, LIB_TAG_PRE_EXISTING, false); + BLO_blendhandle_close(bh); + return true; +} + /** * \return Success. */ diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index ddf35d7dddf..fa7850bc2f4 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -39,7 +39,9 @@ #include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_appdir.h" #include "BKE_armature.h" +#include "BKE_blender_copybuffer.h" #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_depsgraph.h" @@ -248,30 +250,6 @@ void POSE_OT_visual_transform_apply(wmOperatorType *ot) /* ********************************************** */ /* Copy/Paste */ -/* Global copy/paste buffer for pose - cleared on start/end session + before every copy operation */ -static bPose *g_posebuf = NULL; - -void ED_clipboard_posebuf_free(void) -{ - if (g_posebuf) { - bPoseChannel *pchan; - - for (pchan = g_posebuf->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->prop) { - IDP_FreeProperty(pchan->prop); - MEM_freeN(pchan->prop); - } - } - - /* was copied without constraints */ - BLI_freelistN(&g_posebuf->chanbase); - BKE_pose_channels_hash_free(g_posebuf); - MEM_freeN(g_posebuf); - } - - g_posebuf = NULL; -} - /* This function is used to indicate that a bone is selected * and needs to be included in copy buffer (used to be for inserting keys) */ @@ -436,22 +414,24 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo static int pose_copy_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); - - /* sanity checking */ + char str[FILE_MAX]; + /* Sanity checking. */ if (ELEM(NULL, ob, ob->pose)) { BKE_report(op->reports, RPT_ERROR, "No pose to copy"); return OPERATOR_CANCELLED; } - - /* free existing pose buffer */ - ED_clipboard_posebuf_free(); - - /* sets chan->flag to POSE_KEY if bone selected, then copy those bones to the buffer */ - set_pose_keys(ob); - BKE_pose_copy_data(&g_posebuf, ob->pose, 0); - - + /* Sets chan->flag to POSE_KEY if bone selected. */ + set_pose_keys(ob); + /* Store the whole object to the copy buffer because pose can't be + * existing on it's own. + */ + BKE_copybuffer_begin(bmain); + BKE_copybuffer_tag_ID(&ob->id); + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer_pose.blend"); + BKE_copybuffer_save(bmain, str, op->reports); + BKE_report(op->reports, RPT_INFO, "Copied pose to buffer"); return OPERATOR_FINISHED; } @@ -479,44 +459,60 @@ static int pose_paste_exec(bContext *C, wmOperator *op) bPoseChannel *chan; const bool flip = RNA_boolean_get(op->ptr, "flipped"); bool selOnly = RNA_boolean_get(op->ptr, "selected_mask"); - - /* get KeyingSet to use */ + /* Get KeyingSet to use. */ KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID); - - /* sanity checks */ - if (ELEM(NULL, ob, ob->pose)) + /* Sanity checks. */ + if (ELEM(NULL, ob, ob->pose)) { return OPERATOR_CANCELLED; - - if (g_posebuf == NULL) { + } + /* Read copy buffer .blend file. */ + char str[FILE_MAX]; + Main *tmp_bmain = BKE_main_new(); + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer_pose.blend"); + if (!BKE_copybuffer_read(tmp_bmain, str, op->reports)) { BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty"); + BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; } - - /* if selOnly option is enabled, if user hasn't selected any bones, - * just go back to default behavior to be more in line with other pose tools + /* Make sure data from this file is usable for pose paste. */ + if (BLI_listbase_count_ex(&tmp_bmain->object, 2) != 1) { + BKE_report(op->reports, RPT_ERROR, "Copy buffer is not from pose mode"); + BKE_main_free(tmp_bmain); + return OPERATOR_CANCELLED; + } + Object *object_from = tmp_bmain->object.first; + bPose *pose_from = object_from->pose; + if (pose_from == NULL) { + BKE_report(op->reports, RPT_ERROR, "Copy buffer has no pose"); + BKE_main_free(tmp_bmain); + return OPERATOR_CANCELLED; + } + /* If selOnly option is enabled, if user hasn't selected any bones, + * just go back to default behavior to be more in line with other + * pose tools. */ if (selOnly) { - if (CTX_DATA_COUNT(C, selected_pose_bones) == 0) - selOnly = 0; + if (CTX_DATA_COUNT(C, selected_pose_bones) == 0) { + selOnly = false; + } } - - /* Safely merge all of the channels in the buffer pose into any existing pose */ - for (chan = g_posebuf->chanbase.first; chan; chan = chan->next) { + /* Safely merge all of the channels in the buffer pose into any + * existing pose. + */ + for (chan = pose_from->chanbase.first; chan; chan = chan->next) { if (chan->flag & POSE_KEY) { - /* try to perform paste on this bone */ + /* Try to perform paste on this bone. */ bPoseChannel *pchan = pose_bone_do_paste(ob, chan, selOnly, flip); - - if (pchan) { - /* keyframing tagging for successful paste */ + if (pchan != NULL) { + /* Keyframing tagging for successful paste, */ ED_autokeyframe_pchan(C, scene, ob, pchan, ks); } } } - - /* Update event for pose and deformation children */ + BKE_main_free(tmp_bmain); + /* Update event for pose and deformation children. */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - - /* notifiers for updates */ + /* Notifiers for updates, */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index b6b80b93e0b..f5968397f65 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -78,9 +78,6 @@ void undo_editmode_push(struct bContext *C, const char *name, void undo_editmode_clear(void); -/* cut-paste buffer free */ -void ED_clipboard_posebuf_free(void); - /* ************** XXX OLD CRUFT WARNING ************* */ void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 73622cda483..c11c398c616 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -527,7 +527,6 @@ void WM_exit_ext(bContext *C, const bool do_python) ANIM_fmodifiers_copybuf_free(); ED_gpencil_anim_copybuf_free(); ED_gpencil_strokes_copybuf_free(); - ED_clipboard_posebuf_free(); BKE_node_clipboard_clear(); BLF_exit(); |