Commit: fe1342ab9b4b45357b47250985ce1b72cd0dd80f
Author: Sergey Sharybin
Date:   Wed Sep 14 17:50:11 2016 +0200
Branches: master
https://developer.blender.org/rBfe1342ab9b4b45357b47250985ce1b72cd0dd80f

Use temp .blend file copybuffer for pose copy-paste

Uses similar way of storing temp data as object copy paste, just
uses different read entrypoint which does not modify current bmain.

This gives ability to easily copy-paste poses from one blender to
another one.

Hopefully doesn't introduce user-measurable differences.

Request from Peer here in the studio.

Reviewers: mont29

Reviewed By: mont29

Subscribers: hjalti, fsiddi

Differential Revision: https://developer.blender.org/D2229

===================================================================

M       source/blender/blenkernel/BKE_blender_copybuffer.h
M       source/blender/blenkernel/intern/blender_copybuffer.c
M       source/blender/editors/armature/pose_transform.c
M       source/blender/editors/include/ED_util.h
M       source/blender/windowmanager/intern/wm_init_exit.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_blender_copybuffer.h 
b/source/blender/blenkernel/BKE_blender_copybuffer.h
index 8aaf295..02bd962 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 ad01fac..a4c2812 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 ddf35d7..fa7850b 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 b6b80b9..f596839 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 73622cd..c11c398 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();

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to