[Bf-blender-cvs] [fe1342a] master: Use temp .blend file copybuffer for pose copy-paste

Sergey Sharybin noreply at git.blender.org
Thu Sep 15 09:52:20 CEST 2016


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();




More information about the Bf-blender-cvs mailing list