Blender  V2.93
MOD_meshsequencecache.c
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 
21 #include <string.h>
22 
23 #include "BLI_string.h"
24 #include "BLI_utildefines.h"
25 
26 #include "BLT_translation.h"
27 
28 #include "DNA_cachefile_types.h"
29 #include "DNA_defaults.h"
30 #include "DNA_mesh_types.h"
31 #include "DNA_meshdata_types.h"
32 #include "DNA_modifier_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_screen_types.h"
36 
37 #include "MEM_guardedalloc.h"
38 
39 #include "BKE_cachefile.h"
40 #include "BKE_context.h"
41 #include "BKE_lib_query.h"
42 #include "BKE_scene.h"
43 #include "BKE_screen.h"
44 
45 #include "UI_interface.h"
46 #include "UI_resources.h"
47 
48 #include "RNA_access.h"
49 
50 #include "BLO_read_write.h"
51 
52 #include "DEG_depsgraph_build.h"
53 #include "DEG_depsgraph_query.h"
54 
55 #include "MOD_modifiertypes.h"
56 #include "MOD_ui_common.h"
57 
58 #ifdef WITH_ALEMBIC
59 # include "ABC_alembic.h"
60 # include "BKE_global.h"
61 # include "BKE_lib_id.h"
62 #endif
63 
64 static void initData(ModifierData *md)
65 {
67 
68  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mcmd, modifier));
69 
71 }
72 
73 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
74 {
75 #if 0
76  const MeshSeqCacheModifierData *mcmd = (const MeshSeqCacheModifierData *)md;
77 #endif
79 
80  BKE_modifier_copydata_generic(md, target, flag);
81 
82  tmcmd->reader = NULL;
83  tmcmd->reader_object_path[0] = '\0';
84 }
85 
86 static void freeData(ModifierData *md)
87 {
89 
90  if (mcmd->reader) {
91  mcmd->reader_object_path[0] = '\0';
93  }
94 
95  if (mcmd->vertex_velocities) {
97  }
98 }
99 
100 static bool isDisabled(const struct Scene *UNUSED(scene),
101  ModifierData *md,
102  bool UNUSED(useRenderParams))
103 {
105 
106  /* leave it up to the modifier to check the file is valid on calculation */
107  return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0');
108 }
109 
111 {
112 #ifdef WITH_ALEMBIC
114 
115  /* Only used to check whether we are operating on org data or not... */
116  Mesh *me = (ctx->object->type == OB_MESH) ? ctx->object->data : NULL;
117  Mesh *org_mesh = mesh;
118 
120  CacheFile *cache_file = mcmd->cache_file;
121  const float frame = DEG_get_ctime(ctx->depsgraph);
122  const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
123  const char *err_str = NULL;
124 
125  if (!mcmd->reader || !STREQ(mcmd->reader_object_path, mcmd->object_path)) {
126  STRNCPY(mcmd->reader_object_path, mcmd->object_path);
127  BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
128  if (!mcmd->reader) {
130  ctx->object, md, "Could not create Alembic reader for file %s", cache_file->filepath);
131  return mesh;
132  }
133  }
134 
135  /* If this invocation is for the ORCO mesh, and the mesh in Alembic hasn't changed topology, we
136  * must return the mesh as-is instead of deforming it. */
137  if (ctx->flag & MOD_APPLY_ORCO &&
138  !ABC_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, &err_str)) {
139  return mesh;
140  }
141 
142  if (me != NULL) {
143  MVert *mvert = mesh->mvert;
144  MEdge *medge = mesh->medge;
145  MPoly *mpoly = mesh->mpoly;
146 
147  /* TODO(sybren+bastien): possibly check relevant custom data layers (UV/color depending on
148  * flags) and duplicate those too. */
149  if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
150  /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
152  &mesh->id,
153  NULL,
156  }
157  }
158 
159  Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
160 
161  mcmd->velocity_delta = 1.0f;
163  mcmd->velocity_delta /= FPS;
164  }
165 
166  mcmd->last_lookup_time = time;
167 
168  if (result != NULL) {
169  mcmd->num_vertices = result->totvert;
170  }
171 
172  if (err_str) {
173  BKE_modifier_set_error(ctx->object, md, "%s", err_str);
174  }
175 
176  if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
178  mesh = org_mesh;
179  }
180 
181  return result ? result : mesh;
182 #else
183  UNUSED_VARS(ctx, md);
184  return mesh;
185 #endif
186 }
187 
188 static bool dependsOnTime(ModifierData *md)
189 {
190 #ifdef WITH_ALEMBIC
192  return (mcmd->cache_file != NULL);
193 #else
194  UNUSED_VARS(md);
195  return false;
196 #endif
197 }
198 
199 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
200 {
202 
203  walk(userData, ob, (ID **)&mcmd->cache_file, IDWALK_CB_USER);
204 }
205 
207 {
209 
210  if (mcmd->cache_file != NULL) {
212  ctx->node, mcmd->cache_file, DEG_OB_COMP_CACHE, "Mesh Cache File");
213  }
214 }
215 
216 static void panel_draw(const bContext *C, Panel *panel)
217 {
218  uiLayout *layout = panel->layout;
219 
220  PointerRNA ob_ptr;
222 
223  PointerRNA cache_file_ptr = RNA_pointer_get(ptr, "cache_file");
224  bool has_cache_file = !RNA_pointer_is_null(&cache_file_ptr);
225 
226  uiLayoutSetPropSep(layout, true);
227 
228  uiTemplateCacheFile(layout, C, ptr, "cache_file");
229 
230  if (has_cache_file) {
231  uiItemPointerR(layout, ptr, "object_path", &cache_file_ptr, "object_paths", NULL, ICON_NONE);
232  }
233 
234  if (RNA_enum_get(&ob_ptr, "type") == OB_MESH) {
235  uiItemR(layout, ptr, "read_data", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
236  uiItemR(layout, ptr, "use_vertex_interpolation", 0, NULL, ICON_NONE);
237  }
238 
239  uiItemR(layout, ptr, "velocity_scale", 0, NULL, ICON_NONE);
240 
241  modifier_panel_end(layout, ptr);
242 }
243 
244 static void panelRegister(ARegionType *region_type)
245 {
247 }
248 
249 static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
250 {
252  msmcd->reader = NULL;
253  msmcd->reader_object_path[0] = '\0';
254 }
255 
257  /* name */ "MeshSequenceCache",
258  /* structName */ "MeshSeqCacheModifierData",
259  /* structSize */ sizeof(MeshSeqCacheModifierData),
260  /* srna */ &RNA_MeshSequenceCacheModifier,
263  /* icon */ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */
264 
265  /* copyData */ copyData,
266 
267  /* deformVerts */ NULL,
268  /* deformMatrices */ NULL,
269  /* deformVertsEM */ NULL,
270  /* deformMatricesEM */ NULL,
271  /* modifyMesh */ modifyMesh,
272  /* modifyHair */ NULL,
273  /* modifyGeometrySet */ NULL,
274  /* modifyVolume */ NULL,
275 
276  /* initData */ initData,
277  /* requiredDataMask */ NULL,
278  /* freeData */ freeData,
279  /* isDisabled */ isDisabled,
280  /* updateDepsgraph */ updateDepsgraph,
281  /* dependsOnTime */ dependsOnTime,
282  /* dependsOnNormals */ NULL,
283  /* foreachIDLink */ foreachIDLink,
284  /* foreachTexLink */ NULL,
285  /* freeRuntimeData */ NULL,
286  /* panelRegister */ panelRegister,
287  /* blendWrite */ NULL,
288  /* blendRead */ blendRead,
289 };
struct Mesh * ABC_read_mesh(struct CacheReader *reader, struct Object *ob, struct Mesh *existing_mesh, const float time, const char **err_str, int read_flags)
bool ABC_mesh_topology_changed(struct CacheReader *reader, struct Object *ob, struct Mesh *existing_mesh, const float time, const char **err_str)
void BKE_cachefile_reader_open(struct CacheFile *cache_file, struct CacheReader **reader, struct Object *object, const char *object_path)
Definition: cachefile.c:164
void BKE_cachefile_reader_free(struct CacheFile *cache_file, struct CacheReader **reader)
Definition: cachefile.c:198
float BKE_cachefile_time_offset(const struct CacheFile *cache_file, const float time, const float fps)
@ LIB_ID_COPY_NO_PREVIEW
Definition: BKE_lib_id.h:116
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
@ LIB_ID_CREATE_NO_DEG_TAG
Definition: BKE_lib_id.h:99
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:81
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:61
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
@ MOD_APPLY_ORCO
Definition: BKE_modifier.h:133
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
#define UNUSED_VARS(...)
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
@ DEG_OB_COMP_CACHE
void DEG_add_object_cache_relation(struct DepsNodeHandle *handle, struct CacheFile *cache_file, eDepsObjectComponentType component, const char *description)
float DEG_get_ctime(const Depsgraph *graph)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ CACHEFILE_VELOCITY_UNIT_SECOND
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
struct MeshSeqCacheModifierData MeshSeqCacheModifierData
@ eModifierType_MeshSequenceCache
Object is a sort of wrapper for general info.
@ OB_MESH
#define FPS
Read Guarded memory(de)allocation.
static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
ModifierTypeInfo modifierType_MeshSequenceCache
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static bool dependsOnTime(ModifierData *md)
static void freeData(ModifierData *md)
static void panel_draw(const bContext *C, Panel *panel)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
StructRNA RNA_MeshSequenceCacheModifier
#define C
Definition: RandGen.cpp:39
@ UI_ITEM_R_EXPAND
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiTemplateCacheFile(uiLayout *layout, const struct bContext *C, struct PointerRNA *ptr, const char *propname)
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
double time
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:174
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
char filepath[1024]
Definition: DNA_ID.h:273
struct MeshCacheVertexVelocity * vertex_velocities
struct CacheReader * reader
struct CacheFile * cache_file
struct MEdge * medge
struct MVert * mvert
struct MPoly * mpoly
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
ModifierApplyFlag flag
Definition: BKE_modifier.h:155
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
void * data
struct uiLayout * layout
PointerRNA * ptr
Definition: wm_files.c:3157