Blender  V2.93
deg_eval_runtime_backup_object.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 Blender Foundation.
17  * All rights reserved.
18  */
19 
25 
26 #include <cstring>
27 
28 #include "DNA_mesh_types.h"
29 
30 #include "BLI_listbase.h"
31 
32 #include "BKE_action.h"
33 #include "BKE_object.h"
34 
35 namespace blender::deg {
36 
38  : base_flag(0), base_local_view_bits(0)
39 {
40  /* TODO(sergey): Use something like BKE_object_runtime_reset(). */
41  memset(&runtime, 0, sizeof(runtime));
42 }
43 
45 {
46  /* Store evaluated mesh and curve_cache, and make sure we don't free it. */
47  runtime = object->runtime;
49  /* Keep bbox (for now at least). */
50  object->runtime.bb = runtime.bb;
51  /* Object update will override actual object->data to an evaluated version.
52  * Need to make sure we don't have data set to evaluated one before free
53  * anything. */
54  object->data = runtime.data_orig;
55  /* Make a backup of base flags. */
56  base_flag = object->base_flag;
57  base_local_view_bits = object->base_local_view_bits;
58  /* Backup runtime data of all modifiers. */
60  /* Backup runtime data of all pose channels. */
62 }
63 
65 {
66  LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
67  if (modifier_data->runtime == nullptr) {
68  continue;
69  }
70 
71  const SessionUUID &session_uuid = modifier_data->session_uuid;
73 
74  BLI_assert(modifier_data->orig_modifier_data != nullptr);
75  modifier_runtime_data.add(session_uuid, ModifierDataBackup(modifier_data));
76  modifier_data->runtime = nullptr;
77  }
78 }
79 
81 {
82  if (object->pose != nullptr) {
83  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
84  const SessionUUID &session_uuid = pchan->runtime.session_uuid;
86 
87  pose_channel_runtime_data.add(session_uuid, pchan->runtime);
88  BKE_pose_channel_runtime_reset(&pchan->runtime);
89  }
90  }
91 }
92 
94 {
95  ID *data_orig = object->runtime.data_orig;
96  ID *data_eval = runtime.data_eval;
97  BoundBox *bb = object->runtime.bb;
98  object->runtime = runtime;
99  object->runtime.data_orig = data_orig;
100  object->runtime.bb = bb;
101  if (ELEM(object->type, OB_MESH, OB_LATTICE) && data_eval != nullptr) {
102  if (object->id.recalc & ID_RECALC_GEOMETRY) {
103  /* If geometry is tagged for update it means, that part of
104  * evaluated mesh are not valid anymore. In this case we can not
105  * have any "persistent" pointers to point to an invalid data.
106  *
107  * We restore object's data datablock to an original copy of
108  * that datablock. */
109  object->data = data_orig;
110 
111  /* After that, immediately free the invalidated caches. */
113  }
114  else {
115  /* Do same thing as object update: override actual object data
116  * pointer with evaluated datablock. */
117  object->data = data_eval;
118 
119  /* Evaluated mesh simply copied edit_mesh pointer from
120  * original mesh during update, need to make sure no dead
121  * pointers are left behind. */
122  if (object->type == OB_MESH) {
123  Mesh *mesh_eval = (Mesh *)data_eval;
124  Mesh *mesh_orig = (Mesh *)data_orig;
125  mesh_eval->edit_mesh = mesh_orig->edit_mesh;
126  }
127  }
128  }
129  else if (ELEM(object->type, OB_HAIR, OB_POINTCLOUD, OB_VOLUME)) {
130  if (object->id.recalc & ID_RECALC_GEOMETRY) {
131  /* Free evaluated caches. */
132  object->data = data_orig;
134  }
135  else {
136  object->data = object->runtime.data_eval;
137  }
138  }
139 
140  object->base_flag = base_flag;
141  object->base_local_view_bits = base_local_view_bits;
142  /* Restore modifier's runtime data.
143  * NOTE: Data of unused modifiers will be freed there. */
146 }
147 
149 {
150  LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
151  BLI_assert(modifier_data->orig_modifier_data != nullptr);
152  const SessionUUID &session_uuid = modifier_data->session_uuid;
153  optional<ModifierDataBackup> backup = modifier_runtime_data.pop_try(session_uuid);
154  if (backup.has_value()) {
155  modifier_data->runtime = backup->runtime;
156  }
157  }
158 
160  const ModifierTypeInfo *modifier_type_info = BKE_modifier_get_info(backup.type);
161  BLI_assert(modifier_type_info != nullptr);
162  modifier_type_info->freeRuntimeData(backup.runtime);
163  }
164 }
165 
167 {
168  if (object->pose != nullptr) {
169  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
170  const SessionUUID &session_uuid = pchan->runtime.session_uuid;
171  optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(session_uuid);
172  if (runtime.has_value()) {
173  pchan->runtime = *runtime;
174  }
175  }
176  }
179  }
180 }
181 
182 } // namespace blender::deg
Blender kernel action and pose functionality.
void BKE_pose_channel_runtime_reset(struct bPoseChannel_Runtime *runtime)
Definition: action.c:1088
void BKE_pose_channel_runtime_free(struct bPoseChannel_Runtime *runtime)
Definition: action.c:1102
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(struct Object *ob)
Definition: object.c:1719
void BKE_object_runtime_reset(struct Object *object)
Definition: object.c:5107
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
Definition: session_uuid.c:52
#define ELEM(...)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ OB_LATTICE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_HAIR
@ OB_VOLUME
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:264
ValueIterator values() const
Definition: BLI_map.hh:806
std::optional< Value > pop_try(const Key &key)
Definition: BLI_map.hh:388
Map< SessionUUID, bPoseChannel_Runtime > pose_channel_runtime_data
Map< SessionUUID, ModifierDataBackup > modifier_runtime_data
AnimationBackup * backup
Definition: DNA_ID.h:273
int recalc
Definition: DNA_ID.h:295
struct BMEditMesh * edit_mesh
void(* freeRuntimeData)(void *runtime_data)
Definition: BKE_modifier.h:376
struct ID * data_eval
struct ID * data_orig
struct BoundBox * bb
struct bPose * pose
ListBase modifiers
ListBase chanbase