| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bke | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Blend file undo (known as 'Global Undo'). | 
					
						
							|  |  |  |  * DNA level diffing for undo. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef _WIN32
 | 
					
						
							|  |  |  | #  include <unistd.h> /* for read close */
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  include <io.h> /* for open close read */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <fcntl.h> /* for open */
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | #include <stddef.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_path_util.h"
 | 
					
						
							|  |  |  | #include "BLI_string.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 15:37:31 +01:00
										 |  |  | #include "BKE_appdir.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | #include "BKE_blender_undo.h" /* own include */
 | 
					
						
							|  |  |  | #include "BKE_blendfile.h"
 | 
					
						
							|  |  |  | #include "BKE_context.h"
 | 
					
						
							|  |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							| 
									
										
										
										
											2021-02-04 22:03:39 +01:00
										 |  |  | #include "BKE_undo_system.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 14:57:41 +11:00
										 |  |  | #include "BLO_readfile.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLO_undofile.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | #include "BLO_writefile.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:11:50 +02:00
										 |  |  | #include "DEG_depsgraph.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Global Undo
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define UNDO_DISK 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-17 12:29:36 +01:00
										 |  |  | bool BKE_memfile_undo_decode(MemFileUndoData *mfu, | 
					
						
							| 
									
										
										
										
											2021-02-04 22:03:39 +01:00
										 |  |  |                              const eUndoStepDir undo_direction, | 
					
						
							| 
									
										
										
										
											2020-03-17 12:29:36 +01:00
										 |  |  |                              const bool use_old_bmain_data, | 
					
						
							|  |  |  |                              bContext *C) | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-05 15:10:33 +02:00
										 |  |  |   Main *bmain = CTX_data_main(C); | 
					
						
							|  |  |  |   char mainstr[sizeof(bmain->name)]; | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   int success = 0, fileflags; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-05 15:10:33 +02:00
										 |  |  |   BLI_strncpy(mainstr, BKE_main_blendfile_path(bmain), sizeof(mainstr)); /* temporal store */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   fileflags = G.fileflags; | 
					
						
							|  |  |  |   G.fileflags |= G_FILE_NO_UI; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 14:44:17 +02:00
										 |  |  |   if (UNDO_DISK) { | 
					
						
							| 
									
										
										
										
											2021-03-12 00:34:21 +11:00
										 |  |  |     const struct BlendFileReadParams params = {0}; | 
					
						
							|  |  |  |     struct BlendFileData *bfd = BKE_blendfile_read(mfu->filename, ¶ms, NULL); | 
					
						
							|  |  |  |     if (bfd != NULL) { | 
					
						
							|  |  |  |       BKE_blendfile_read_setup(C, bfd, ¶ms, NULL); | 
					
						
							|  |  |  |       success = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-27 14:44:17 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2020-03-17 12:29:36 +01:00
										 |  |  |     struct BlendFileReadParams params = {0}; | 
					
						
							| 
									
										
										
										
											2021-02-04 22:03:39 +01:00
										 |  |  |     params.undo_direction = undo_direction; | 
					
						
							| 
									
										
										
										
											2020-03-17 12:29:36 +01:00
										 |  |  |     if (!use_old_bmain_data) { | 
					
						
							|  |  |  |       params.skip_flags |= BLO_READ_SKIP_UNDO_OLD_MAIN; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-12 00:34:21 +11:00
										 |  |  |     struct BlendFileData *bfd = BKE_blendfile_read_from_memfile( | 
					
						
							|  |  |  |         bmain, &mfu->memfile, ¶ms, NULL); | 
					
						
							|  |  |  |     if (bfd != NULL) { | 
					
						
							|  |  |  |       BKE_blendfile_read_setup(C, bfd, ¶ms, NULL); | 
					
						
							|  |  |  |       success = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-27 14:44:17 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 09:36:50 +02:00
										 |  |  |   /* Restore, bmain has been re-allocated. */ | 
					
						
							|  |  |  |   bmain = CTX_data_main(C); | 
					
						
							|  |  |  |   BLI_strncpy(bmain->name, mainstr, sizeof(bmain->name)); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   G.fileflags = fileflags; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   if (success) { | 
					
						
							| 
									
										
										
										
											2018-09-24 18:46:51 +02:00
										 |  |  |     /* important not to update time here, else non keyed transforms are lost */ | 
					
						
							| 
									
										
										
										
											2018-06-06 09:39:35 +02:00
										 |  |  |     DEG_on_visible_update(bmain, false); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   return success; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  | MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev) | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |   MemFileUndoData *mfu = MEM_callocN(sizeof(MemFileUndoData), __func__); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 13:18:20 +11:00
										 |  |  |   /* Include recovery information since undo-data is written out as #BLENDER_QUIT_FILE. */ | 
					
						
							| 
									
										
										
										
											2021-03-15 13:30:43 +11:00
										 |  |  |   const int fileflags = G.fileflags | G_FILE_RECOVER_WRITE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   /* disk save version */ | 
					
						
							|  |  |  |   if (UNDO_DISK) { | 
					
						
							|  |  |  |     static int counter = 0; | 
					
						
							| 
									
										
										
										
											2018-03-27 14:44:17 +02:00
										 |  |  |     char filename[FILE_MAX]; | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |     char numstr[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 14:44:17 +02:00
										 |  |  |     /* Calculate current filename. */ | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |     counter++; | 
					
						
							|  |  |  |     counter = counter % U.undosteps; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); | 
					
						
							| 
									
										
										
										
											2020-03-07 13:23:26 +11:00
										 |  |  |     BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), numstr); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 15:41:07 +10:00
										 |  |  |     /* success = */ /* UNUSED */ BLO_write_file( | 
					
						
							| 
									
										
										
										
											2021-03-15 13:30:43 +11:00
										 |  |  |         bmain, filename, fileflags, &(const struct BlendFileWriteParams){0}, NULL); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |     BLI_strncpy(mfu->filename, filename, sizeof(mfu->filename)); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |     MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : NULL; | 
					
						
							| 
									
										
										
										
											2020-03-28 21:48:07 +01:00
										 |  |  |     if (prevfile) { | 
					
						
							|  |  |  |       BLO_memfile_clear_future(prevfile); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-15 13:30:43 +11:00
										 |  |  |     /* success = */ /* UNUSED */ BLO_write_file_mem(bmain, prevfile, &mfu->memfile, fileflags); | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |     mfu->undo_size = mfu->memfile.size; | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |   bmain->is_memfile_undo_written = true; | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |   return mfu; | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  | void BKE_memfile_undo_free(MemFileUndoData *mfu) | 
					
						
							| 
									
										
										
											
												Implement grouped undo option for operators
This option makes an operator to not push a task to the undo stack if the previous stored elemen is the same operator or part of the same undo group.
The main usage is for animation, so you can change frames to inspect the
poses, and revert the previous pose without having to roll back tons of
"change frame" operator, or even see the undo stack full.
This complements rB13ee9b8e
Design with help by Sergey Sharybin.
Reviewers: sergey, mont29
Reviewed By: mont29, sergey
Subscribers: pyc0d3r, hjalti, Severin, lowercase, brecht, monio, aligorith, hadrien, jbakker
Differential Revision: https://developer.blender.org/D2330
											
										 
											2016-11-15 11:50:11 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-19 14:17:59 +01:00
										 |  |  |   BLO_memfile_free(&mfu->memfile); | 
					
						
							|  |  |  |   MEM_freeN(mfu); | 
					
						
							| 
									
										
										
										
											2016-04-24 22:42:41 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |