Blender  V3.3
deg_eval_runtime_backup_object.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2019 Blender Foundation. All rights reserved. */
3 
9 
10 #include <cstring>
11 
12 #include "DNA_mesh_types.h"
13 
14 #include "BLI_listbase.h"
15 
16 #include "BKE_action.h"
17 #include "BKE_object.h"
18 
19 namespace blender::deg {
20 
22  : base_flag(0), base_local_view_bits(0)
23 {
24  /* TODO(sergey): Use something like BKE_object_runtime_reset(). */
25  memset(&runtime, 0, sizeof(runtime));
26 }
27 
29 {
30  /* Store evaluated mesh and curve_cache, and make sure we don't free it. */
31  runtime = object->runtime;
33  /* Keep bbox (for now at least). */
34  object->runtime.bb = runtime.bb;
35  /* Object update will override actual object->data to an evaluated version.
36  * Need to make sure we don't have data set to evaluated one before free
37  * anything. */
38  object->data = runtime.data_orig;
39  /* Make a backup of base flags. */
40  base_flag = object->base_flag;
41  base_local_view_bits = object->base_local_view_bits;
42  /* Backup runtime data of all modifiers. */
44  /* Backup runtime data of all pose channels. */
46 }
47 
49 {
50  LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
51  if (modifier_data->runtime == nullptr) {
52  continue;
53  }
54 
55  const SessionUUID &session_uuid = modifier_data->session_uuid;
57 
58  modifier_runtime_data.add(session_uuid, ModifierDataBackup(modifier_data));
59  modifier_data->runtime = nullptr;
60  }
61 }
62 
64 {
65  if (object->pose != nullptr) {
66  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
67  const SessionUUID &session_uuid = pchan->runtime.session_uuid;
69 
70  pose_channel_runtime_data.add(session_uuid, pchan->runtime);
71  BKE_pose_channel_runtime_reset(&pchan->runtime);
72  }
73  }
74 }
75 
77 {
78  ID *data_orig = object->runtime.data_orig;
79  ID *data_eval = runtime.data_eval;
80  BoundBox *bb = object->runtime.bb;
81  object->runtime = runtime;
82  object->runtime.data_orig = data_orig;
83  object->runtime.bb = bb;
84  if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_CURVES_LEGACY, OB_FONT) && data_eval != nullptr) {
85  if (object->id.recalc & ID_RECALC_GEOMETRY) {
86  /* If geometry is tagged for update it means, that part of
87  * evaluated mesh are not valid anymore. In this case we can not
88  * have any "persistent" pointers to point to an invalid data.
89  *
90  * We restore object's data datablock to an original copy of
91  * that datablock. */
92  object->data = data_orig;
93 
94  /* After that, immediately free the invalidated caches. */
96  }
97  else {
98  /* Do same thing as object update: override actual object data pointer with evaluated
99  * datablock, but only if the evaluated data has the same type as the original data. */
100  if (GS(((ID *)object->data)->name) == GS(data_eval->name)) {
101  object->data = data_eval;
102  }
103 
104  /* Evaluated mesh simply copied edit_mesh pointer from
105  * original mesh during update, need to make sure no dead
106  * pointers are left behind. */
107  if (object->type == OB_MESH) {
108  Mesh *mesh_eval = (Mesh *)data_eval;
109  Mesh *mesh_orig = (Mesh *)data_orig;
110  mesh_eval->edit_mesh = mesh_orig->edit_mesh;
111  }
112  }
113  }
114  else if (ELEM(object->type, OB_CURVES, OB_POINTCLOUD, OB_VOLUME)) {
115  if (object->id.recalc & ID_RECALC_GEOMETRY) {
116  /* Free evaluated caches. */
117  object->data = data_orig;
119  }
120  else {
121  object->data = object->runtime.data_eval;
122  }
123  }
124 
125  object->base_flag = base_flag;
126  object->base_local_view_bits = base_local_view_bits;
127  /* Restore modifier's runtime data.
128  * NOTE: Data of unused modifiers will be freed there. */
131 }
132 
134 {
135  LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
136  const SessionUUID &session_uuid = modifier_data->session_uuid;
138 
139  optional<ModifierDataBackup> backup = modifier_runtime_data.pop_try(session_uuid);
140  if (backup.has_value()) {
141  modifier_data->runtime = backup->runtime;
142  }
143  }
144 
146  const ModifierTypeInfo *modifier_type_info = BKE_modifier_get_info(backup.type);
147  BLI_assert(modifier_type_info != nullptr);
148  modifier_type_info->freeRuntimeData(backup.runtime);
149  }
150 }
151 
153 {
154  if (object->pose != nullptr) {
155  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
156  const SessionUUID &session_uuid = pchan->runtime.session_uuid;
157  optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(session_uuid);
158  if (runtime.has_value()) {
159  pchan->runtime = *runtime;
160  }
161  }
162  }
165  }
166 }
167 
168 } // namespace blender::deg
Blender kernel action and pose functionality.
void BKE_pose_channel_runtime_reset(struct bPoseChannel_Runtime *runtime)
Definition: action.c:1052
void BKE_pose_channel_runtime_free(struct bPoseChannel_Runtime *runtime)
Definition: action.c:1064
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.cc:1774
void BKE_object_runtime_reset(struct Object *object)
Definition: object.cc:5090
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
Definition: session_uuid.c:38
#define ELEM(...)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ OB_LATTICE
@ OB_FONT
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:250
ValueIterator values() const
Definition: BLI_map.hh:840
std::optional< Value > pop_try(const Key &key)
Definition: BLI_map.hh:374
Map< SessionUUID, bPoseChannel_Runtime > pose_channel_runtime_data
Map< SessionUUID, ModifierDataBackup > modifier_runtime_data
AnimationBackup * backup
#define GS(x)
Definition: iris.c:225
Definition: DNA_ID.h:368
int recalc
Definition: DNA_ID.h:390
char name[66]
Definition: DNA_ID.h:378
struct ID_Runtime runtime
Definition: DNA_ID.h:445
struct BMEditMesh * edit_mesh
void(* freeRuntimeData)(void *runtime_data)
Definition: BKE_modifier.h:355
struct ID * data_eval
struct ID * data_orig
struct BoundBox * bb
struct bPose * pose
ListBase modifiers
void * data
ListBase chanbase