Files
test2/source/blender/modifiers/intern/MOD_meshsequencecache.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

526 lines
16 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup modifiers
*/
#include <cstring>
#include "BLI_math_vector.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.hh"
#include "DNA_cachefile_types.h"
#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_cachefile.hh"
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
#include "BKE_geometry_set.hh"
#include "BKE_lib_query.hh"
#include "BKE_mesh.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
#include "RNA_access.hh"
#include "RNA_prototypes.hh"
#include "DEG_depsgraph_build.hh"
#include "DEG_depsgraph_query.hh"
#include "GEO_mesh_primitive_cuboid.hh"
#include "MOD_modifiertypes.hh"
#include "MOD_ui_common.hh"
#if defined(WITH_USD) || defined(WITH_ALEMBIC)
2024-01-15 12:44:04 -05:00
# include "BKE_lib_id.hh"
#endif
#ifdef WITH_ALEMBIC
# include "ABC_alembic.h"
#endif
#ifdef WITH_USD
# include "usd.hh"
#endif
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
using namespace blender;
Mesh: Remove redundant custom data pointers For copy-on-write, we want to share attribute arrays between meshes where possible. Mutable pointers like `Mesh.mvert` make that difficult by making ownership vague. They also make code more complex by adding redundancy. The simplest solution is just removing them and retrieving layers from `CustomData` as needed. Similar changes have already been applied to curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of the pointers generally makes code more obvious and more reusable. Mesh data is now accessed with a C++ API (`Mesh::edges()` or `Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`). The CoW changes this commit makes possible are described in T95845 and T95842, and started in D14139 and D14140. The change also simplifies the ongoing mesh struct-of-array refactors from T95965. **RNA/Python Access Performance** Theoretically, accessing mesh elements with the RNA API may become slower, since the layer needs to be found on every random access. However, overhead is already high enough that this doesn't make a noticible differenc, and performance is actually improved in some cases. Random access can be up to 10% faster, but other situations might be a bit slower. Generally using `foreach_get/set` are the best way to improve performance. See the differential revision for more discussion about Python performance. Cycles has been updated to use raw pointers and the internal Blender mesh types, mostly because there is no sense in having this overhead when it's already compiled with Blender. In my tests this roughly halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million face grid). Differential Revision: https://developer.blender.org/D15488
2022-09-05 11:56:34 -05:00
static void init_data(ModifierData *md)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mcmd, modifier));
mcmd->cache_file = nullptr;
mcmd->object_path[0] = '\0';
mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
MEMCPY_STRUCT_AFTER(mcmd, DNA_struct_default_get(MeshSeqCacheModifierData), modifier);
}
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
const MeshSeqCacheModifierData *mcmd = (const MeshSeqCacheModifierData *)md;
#endif
MeshSeqCacheModifierData *tmcmd = (MeshSeqCacheModifierData *)target;
BKE_modifier_copydata_generic(md, target, flag);
tmcmd->reader = nullptr;
tmcmd->reader_object_path[0] = '\0';
}
static void free_data(ModifierData *md)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
if (mcmd->reader) {
mcmd->reader_object_path[0] = '\0';
BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
}
static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
/* leave it up to the modifier to check the file is valid on calculation */
return (mcmd->cache_file == nullptr) || (mcmd->object_path[0] == '\0');
}
#if defined(WITH_USD) || defined(WITH_ALEMBIC)
/* Return true if the modifier evaluation is for the ORCO mesh and the mesh hasn't changed
* topology.
*/
static bool can_use_mesh_for_orco_evaluation(MeshSeqCacheModifierData *mcmd,
const ModifierEvalContext *ctx,
const Mesh *mesh,
const float time,
const char **r_err_str)
{
if ((ctx->flag & MOD_APPLY_ORCO) == 0) {
return false;
}
CacheFile *cache_file = mcmd->cache_file;
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
if (!ABC_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, r_err_str)) {
return true;
}
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
if (!blender::io::usd::USD_mesh_topology_changed(
mcmd->reader, ctx->object, mesh, time, r_err_str))
{
return true;
}
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
return false;
}
static Mesh *generate_bounding_box_mesh(const std::optional<Bounds<float3>> &bounds,
Material **mat,
short totcol)
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
{
if (!bounds) {
return nullptr;
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
}
Mesh *result = geometry::create_cuboid_mesh(bounds->max - bounds->min, 2, 2, 2);
if (mat) {
result->mat = static_cast<Material **>(MEM_dupallocN(mat));
result->totcol = totcol;
}
bke::mesh_translate(*result, math::midpoint(bounds->min, bounds->max), false);
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
return result;
}
#endif
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
static void modify_geometry_set(ModifierData *md,
const ModifierEvalContext *ctx,
bke::GeometrySet *geometry_set)
{
#if defined(WITH_USD) || defined(WITH_ALEMBIC)
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
CacheFile *cache_file = mcmd->cache_file;
const float frame = DEG_get_ctime(ctx->depsgraph);
const double time = BKE_cachefile_time_offset(cache_file, frame, FPS);
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
const char *err_str = nullptr;
if (!mcmd->reader || !STREQ(mcmd->reader_object_path, mcmd->object_path)) {
STRNCPY(mcmd->reader_object_path, mcmd->object_path);
BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
if (!mcmd->reader) {
BKE_modifier_set_error(
ctx->object, md, "Could not create cache reader for file %s", cache_file->filepath);
return;
}
}
if (geometry_set->has_mesh()) {
const Mesh *mesh = geometry_set->get_mesh();
if (can_use_mesh_for_orco_evaluation(mcmd, ctx, mesh, time, &err_str)) {
return;
}
}
/* Do not process data if using a render procedural, return a box instead for displaying in the
* viewport. */
if (BKE_cache_file_uses_render_procedural(cache_file, scene)) {
Mesh *bbox = nullptr;
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
if (geometry_set->has_mesh()) {
const Mesh *mesh = geometry_set->get_mesh();
bbox = generate_bounding_box_mesh(mesh->bounds_min_max(), mesh->mat, mesh->totcol);
}
else if (geometry_set->has_pointcloud()) {
const PointCloud *pointcloud = geometry_set->get_pointcloud();
bbox = generate_bounding_box_mesh(
pointcloud->bounds_min_max(), pointcloud->mat, pointcloud->totcol);
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
}
*geometry_set = bke::GeometrySet::from_mesh(bbox);
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
return;
}
/* Time (in frames or seconds) between two velocity samples. Automatically computed to
* scale the velocity vectors at render time for generating proper motion blur data. */
2025-01-13 09:40:30 +01:00
# ifdef WITH_ALEMBIC
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
float velocity_scale = mcmd->velocity_scale;
if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_FRAME) {
velocity_scale *= FPS;
}
2025-01-13 09:40:30 +01:00
# endif
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC: {
# ifdef WITH_ALEMBIC
ABCReadParams params;
params.time = time;
params.read_flags = mcmd->read_flag;
params.velocity_name = mcmd->cache_file->velocity_name;
params.velocity_scale = velocity_scale;
ABC_read_geometry(mcmd->reader, ctx->object, *geometry_set, &params, &err_str);
# endif
break;
}
case CACHEFILE_TYPE_USD: {
# ifdef WITH_USD
const blender::io::usd::USDMeshReadParams params = blender::io::usd::create_mesh_read_params(
time * FPS, mcmd->read_flag);
blender::io::usd::USD_read_geometry(
mcmd->reader, ctx->object, *geometry_set, params, &err_str);
# endif
break;
}
case CACHE_FILE_TYPE_INVALID:
break;
}
if (err_str) {
BKE_modifier_set_error(ctx->object, md, "%s", err_str);
}
#else
UNUSED_VARS(ctx, md, geometry_set);
return;
#endif
}
static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
#if defined(WITH_USD) || defined(WITH_ALEMBIC)
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
2017-08-09 11:51:21 +02:00
/* Only used to check whether we are operating on org data or not... */
Mesh *object_mesh = (ctx->object->type == OB_MESH) ? static_cast<Mesh *>(ctx->object->data) :
nullptr;
Mesh *org_mesh = mesh;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
CacheFile *cache_file = mcmd->cache_file;
const float frame = DEG_get_ctime(ctx->depsgraph);
const double time = BKE_cachefile_time_offset(cache_file, double(frame), FPS);
const char *err_str = nullptr;
if (!mcmd->reader || !STREQ(mcmd->reader_object_path, mcmd->object_path)) {
STRNCPY(mcmd->reader_object_path, mcmd->object_path);
BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
if (!mcmd->reader) {
2020-05-08 19:02:03 +10:00
BKE_modifier_set_error(
ctx->object, md, "Could not create reader for file %s", cache_file->filepath);
return mesh;
}
}
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
/* Do not process data if using a render procedural, return a box instead for displaying in the
* viewport. */
if (BKE_cache_file_uses_render_procedural(cache_file, scene)) {
return generate_bounding_box_mesh(org_mesh->bounds_min_max(), org_mesh->mat, org_mesh->totcol);
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
}
/* If this invocation is for the ORCO mesh, and the mesh hasn't changed topology, we
* must return the mesh as-is instead of deforming it. */
if (can_use_mesh_for_orco_evaluation(mcmd, ctx, mesh, time, &err_str)) {
return mesh;
}
if (object_mesh != nullptr) {
Mesh: Move positions to a generic attribute **Changes** As described in T93602, this patch removes all use of the `MVert` struct, replacing it with a generic named attribute with the name `"position"`, consistent with other geometry types. Variable names have been changed from `verts` to `positions`, to align with the attribute name and the more generic design (positions are not vertices, they are just an attribute stored on the point domain). This change is made possible by previous commits that moved all other data out of `MVert` to runtime data or other generic attributes. What remains is mostly a simple type change. Though, the type still shows up 859 times, so the patch is quite large. One compromise is that now `CD_MASK_BAREMESH` now contains `CD_PROP_FLOAT3`. With the general move towards generic attributes over custom data types, we are removing use of these type masks anyway. **Benefits** The most obvious benefit is reduced memory usage and the benefits that brings in memory-bound situations. `float3` is only 3 bytes, in comparison to `MVert` which was 4. When there are millions of vertices this starts to matter more. The other benefits come from using a more generic type. Instead of writing algorithms specifically for `MVert`, code can just use arrays of vectors. This will allow eliminating many temporary arrays or wrappers used to extract positions. Many possible improvements aren't implemented in this patch, though I did switch simplify or remove the process of creating temporary position arrays in a few places. The design clarity that "positions are just another attribute" brings allows removing explicit copying of vertices in some procedural operations-- they are just processed like most other attributes. **Performance** This touches so many areas that it's hard to benchmark exhaustively, but I observed some areas as examples. * The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster. * The Spring splash screen went from ~4.3 to ~4.5 fps. * The subdivision surface modifier/node was slightly faster RNA access through Python may be slightly slower, since now we need a name lookup instead of just a custom data type lookup for each index. **Future Improvements** * Remove uses of "vert_coords" functions: * `BKE_mesh_vert_coords_alloc` * `BKE_mesh_vert_coords_get` * `BKE_mesh_vert_coords_apply{_with_mat4}` * Remove more hidden copying of positions * General simplification now possible in many areas * Convert more code to C++ to use `float3` instead of `float[3]` * Currently `reinterpret_cast` is used for those C-API functions Differential Revision: https://developer.blender.org/D15982
2023-01-10 00:10:43 -05:00
const Span<float3> mesh_positions = mesh->vert_positions();
Mesh: Move edges to a generic attribute Implements #95966, as the final step of #95965. This commit changes the storage of mesh edge vertex indices from the `MEdge` type to the generic `int2` attribute type. This follows the general design for geometry and the attribute system, where the data storage type and the usage semantics are separated. The main benefit of the change is reduced memory usage-- the requirements of storing mesh edges is reduced by 1/3. For example, this saves 8MB on a 1 million vertex grid. This also gives performance benefits to any memory-bound mesh processing algorithm that uses edges. Another benefit is that all of the edge's vertex indices are contiguous. In a few cases, it's helpful to process all of them as `Span<int>` rather than `Span<int2>`. Similarly, the type is more likely to match a generic format used by a library, or code that shouldn't know about specific Blender `Mesh` types. Various Notes: - The `.edge_verts` name is used to reflect a mapping between domains, similar to `.corner_verts`, etc. The period means that it the data shouldn't change arbitrarily by the user or procedural operations. - `edge[0]` is now used instead of `edge.v1` - Signed integers are used instead of unsigned to reduce the mixing of signed-ness, which can be error prone. - All of the previously used core mesh data types (`MVert`, `MEdge`, `MLoop`, `MPoly` are now deprecated. Only generic types are used). - The `vec2i` DNA type is used in the few C files where necessary. Pull Request: https://projects.blender.org/blender/blender/pulls/106638
2023-04-17 13:47:41 +02:00
const Span<blender::int2> mesh_edges = mesh->edges();
const blender::OffsetIndices mesh_faces = mesh->faces();
const Span<float3> me_positions = object_mesh->vert_positions();
const Span<blender::int2> me_edges = object_mesh->edges();
const blender::OffsetIndices me_faces = object_mesh->faces();
/* TODO(sybren+bastien): possibly check relevant custom data layers (UV/color depending on
Mesh: Remove redundant custom data pointers For copy-on-write, we want to share attribute arrays between meshes where possible. Mutable pointers like `Mesh.mvert` make that difficult by making ownership vague. They also make code more complex by adding redundancy. The simplest solution is just removing them and retrieving layers from `CustomData` as needed. Similar changes have already been applied to curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of the pointers generally makes code more obvious and more reusable. Mesh data is now accessed with a C++ API (`Mesh::edges()` or `Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`). The CoW changes this commit makes possible are described in T95845 and T95842, and started in D14139 and D14140. The change also simplifies the ongoing mesh struct-of-array refactors from T95965. **RNA/Python Access Performance** Theoretically, accessing mesh elements with the RNA API may become slower, since the layer needs to be found on every random access. However, overhead is already high enough that this doesn't make a noticible differenc, and performance is actually improved in some cases. Random access can be up to 10% faster, but other situations might be a bit slower. Generally using `foreach_get/set` are the best way to improve performance. See the differential revision for more discussion about Python performance. Cycles has been updated to use raw pointers and the internal Blender mesh types, mostly because there is no sense in having this overhead when it's already compiled with Blender. In my tests this roughly halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million face grid). Differential Revision: https://developer.blender.org/D15488
2022-09-05 11:56:34 -05:00
* flags) and duplicate those too.
* XXX(Hans): This probably isn't true anymore with various copy-on-eval improvements, etc. */
Mesh: Move positions to a generic attribute **Changes** As described in T93602, this patch removes all use of the `MVert` struct, replacing it with a generic named attribute with the name `"position"`, consistent with other geometry types. Variable names have been changed from `verts` to `positions`, to align with the attribute name and the more generic design (positions are not vertices, they are just an attribute stored on the point domain). This change is made possible by previous commits that moved all other data out of `MVert` to runtime data or other generic attributes. What remains is mostly a simple type change. Though, the type still shows up 859 times, so the patch is quite large. One compromise is that now `CD_MASK_BAREMESH` now contains `CD_PROP_FLOAT3`. With the general move towards generic attributes over custom data types, we are removing use of these type masks anyway. **Benefits** The most obvious benefit is reduced memory usage and the benefits that brings in memory-bound situations. `float3` is only 3 bytes, in comparison to `MVert` which was 4. When there are millions of vertices this starts to matter more. The other benefits come from using a more generic type. Instead of writing algorithms specifically for `MVert`, code can just use arrays of vectors. This will allow eliminating many temporary arrays or wrappers used to extract positions. Many possible improvements aren't implemented in this patch, though I did switch simplify or remove the process of creating temporary position arrays in a few places. The design clarity that "positions are just another attribute" brings allows removing explicit copying of vertices in some procedural operations-- they are just processed like most other attributes. **Performance** This touches so many areas that it's hard to benchmark exhaustively, but I observed some areas as examples. * The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster. * The Spring splash screen went from ~4.3 to ~4.5 fps. * The subdivision surface modifier/node was slightly faster RNA access through Python may be slightly slower, since now we need a name lookup instead of just a custom data type lookup for each index. **Future Improvements** * Remove uses of "vert_coords" functions: * `BKE_mesh_vert_coords_alloc` * `BKE_mesh_vert_coords_get` * `BKE_mesh_vert_coords_apply{_with_mat4}` * Remove more hidden copying of positions * General simplification now possible in many areas * Convert more code to C++ to use `float3` instead of `float[3]` * Currently `reinterpret_cast` is used for those C-API functions Differential Revision: https://developer.blender.org/D15982
2023-01-10 00:10:43 -05:00
if ((me_positions.data() == mesh_positions.data()) || (me_edges.data() == mesh_edges.data()) ||
(me_faces.data() == mesh_faces.data()))
{
/* We need to duplicate data here, otherwise we'll modify org mesh, see #51701. */
mesh = reinterpret_cast<Mesh *>(
BKE_id_copy_ex(nullptr,
&mesh->id,
nullptr,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW));
}
}
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
bke::GeometrySet geometry_set = bke::GeometrySet::from_mesh(
mesh, bke::GeometryOwnershipType::Editable);
modify_geometry_set(md, ctx, &geometry_set);
Mesh *result = geometry_set.get_component_for_write<bke::MeshComponent>().release();
if (!ELEM(result, nullptr, mesh) && (mesh != org_mesh)) {
BKE_id_free(nullptr, mesh);
mesh = org_mesh;
}
return result ? result : mesh;
#else
UNUSED_VARS(ctx, md);
2018-11-28 16:21:24 +11:00
return mesh;
#endif
}
static bool depends_on_time(Scene *scene, ModifierData *md)
{
#if defined(WITH_USD) || defined(WITH_ALEMBIC)
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
Cycles: experimental integration of Alembic procedural in viewport rendering This patch exposes the Cycles Alembic Procedural through the MeshSequenceCache modifier in order to use and test it from Blender. To enable it, one has to switch the render feature set to experimental and activate the Procedural in the modifier. An Alembic Procedural is then created for each CacheFile from Blender set to use the Procedural, and each Blender object having a MeshSequenceCache modifier is added to list of objects of the right procedural. The procedural's parameters derive from the CacheFile's properties which are already exposed in the UI through the modifier, although more Cycles specific options might be added in the future. As there is currently no cache controls and since we load all the data at the beginning of the render session, the procedural is only available during viewport renders at the moment. When an Alembic procedural is rendered, data from the archive are not read on the Blender side. If a Cycles render is not active and the CacheFile is set to use the Cycles Procedural, bounding boxes are used to display the objects in the scene as a signal that the objects are not processed by Blender anymore. This is standard in other DCCs. However this does not reduce the memory usage from Blender as the Alembic data was already loaded either during an import or during a .blend file read. This is mostly a hack to test the Cycles Alembic procedural until we have a better Blender side mechanism for letting renderers load their own geometry, which will be based on import and export settings on Collections (T68933). Ref T79174, D3089 Reviewed By: brecht, sybren Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D10197
2021-08-19 14:34:01 +02:00
/* Do not evaluate animations if using the render engine procedural. */
return (mcmd->cache_file != nullptr) &&
!BKE_cache_file_uses_render_procedural(mcmd->cache_file, scene);
#else
UNUSED_VARS(scene, md);
return false;
#endif
}
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
walk(user_data, ob, reinterpret_cast<ID **>(&mcmd->cache_file), IDWALK_CB_USER);
}
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
if (mcmd->cache_file != nullptr) {
DEG_add_object_cache_relation(
ctx->node, mcmd->cache_file, DEG_OB_COMP_CACHE, "Mesh Cache File");
}
}
static void panel_draw(const bContext *C, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
PointerRNA cache_file_ptr = RNA_pointer_get(ptr, "cache_file");
bool has_cache_file = !RNA_pointer_is_null(&cache_file_ptr);
uiLayoutSetPropSep(layout, true);
uiTemplateCacheFile(layout, C, ptr, "cache_file");
if (has_cache_file) {
uiItemPointerR(
layout, ptr, "object_path", &cache_file_ptr, "object_paths", std::nullopt, ICON_NONE);
}
if (RNA_enum_get(&ob_ptr, "type") == OB_MESH) {
layout->prop(ptr, "read_data", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
layout->prop(ptr, "use_vertex_interpolation", UI_ITEM_NONE, std::nullopt, ICON_NONE);
}
else if (RNA_enum_get(&ob_ptr, "type") == OB_CURVES) {
layout->prop(ptr, "use_vertex_interpolation", UI_ITEM_NONE, std::nullopt, ICON_NONE);
}
modifier_error_message_draw(layout, ptr);
}
static void velocity_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
PointerRNA fileptr;
if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) {
return;
}
uiLayoutSetPropSep(layout, true);
uiTemplateCacheFileVelocity(layout, &fileptr);
layout->prop(ptr, "velocity_scale", UI_ITEM_NONE, std::nullopt, ICON_NONE);
}
static void time_panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
PointerRNA fileptr;
if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) {
return;
}
uiLayoutSetPropSep(layout, true);
uiTemplateCacheFileTimeSettings(layout, &fileptr);
}
static void render_procedural_panel_draw(const bContext *C, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
PointerRNA fileptr;
if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) {
return;
}
uiLayoutSetPropSep(layout, true);
uiTemplateCacheFileProcedural(layout, C, &fileptr);
}
static void override_layers_panel_draw(const bContext *C, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
PointerRNA fileptr;
if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) {
return;
}
uiLayoutSetPropSep(layout, true);
uiTemplateCacheFileLayers(layout, C, &fileptr);
}
static void panel_register(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(
region_type, eModifierType_MeshSequenceCache, panel_draw);
modifier_subpanel_register(region_type, "time", "Time", nullptr, time_panel_draw, panel_type);
modifier_subpanel_register(region_type,
"render_procedural",
"Render Procedural",
nullptr,
render_procedural_panel_draw,
panel_type);
modifier_subpanel_register(
region_type, "velocity", "Velocity", nullptr, velocity_panel_draw, panel_type);
modifier_subpanel_register(region_type,
"override_layers",
"Override Layers",
2022-03-23 21:09:07 +01:00
nullptr,
override_layers_panel_draw,
panel_type);
}
static void blend_read(BlendDataReader * /*reader*/, ModifierData *md)
{
MeshSeqCacheModifierData *msmcd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
msmcd->reader = nullptr;
msmcd->reader_object_path[0] = '\0';
}
ModifierTypeInfo modifierType_MeshSequenceCache = {
/*idname*/ "MeshSequenceCache",
/*name*/ N_("MeshSequenceCache"),
/*struct_name*/ "MeshSeqCacheModifierData",
/*struct_size*/ sizeof(MeshSeqCacheModifierData),
/*srna*/ &RNA_MeshSequenceCacheModifier,
/*type*/ ModifierTypeType::Constructive,
/*flags*/
(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs),
/*icon*/ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */
/*copy_data*/ copy_data,
/*deform_verts*/ nullptr,
/*deform_matrices*/ nullptr,
/*deform_verts_EM*/ nullptr,
/*deform_matrices_EM*/ nullptr,
/*modify_mesh*/ modify_mesh,
Alembic/USD: Use GeometrySets to import data This rewrites the Alembic and USD data importers to work with and output GeometrySets instead of Meshes. The main motivation for this change is to be able to import properly point clouds, which are currently imported as Meshes, and curves data, which suffer from a lot of issues due to limitations of legacy curves structures (fixed by the new curves data-block) and are also converted to Meshes. Further, for Curves, it will allow importing arbitrary attributes. This patch was primarily meant for Alembic, but changes to USD import were necessary as they share the same modifier. For Alembic: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Points are imported as PointClouds For USD: There should be no behavioral changes for Meshes Curves are imported as the new Curves object type Note that the current USD importer does not support loading PointClouds, so this patch does not add support for it. For both Alembic and USD, knots arrays are not read anymore, as the new Curves object does not expose the ability to set them. Improvements can be made in the future if and when example assets are provided. This fixes at least the following: #58704: Animated Alembic curves don't update on render #112308: Curves have offset animations (alembic / USD) #118261: wrong motion blur from usd in cycles and reverting to the first frame when disabeling motion blur Co-authored-by: Jesse Yurkovich <jesse.y@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/115623
2024-02-28 03:02:38 +01:00
/*modify_geometry_set*/ modify_geometry_set,
/*init_data*/ init_data,
/*required_data_mask*/ nullptr,
/*free_data*/ free_data,
/*is_disabled*/ is_disabled,
/*update_depsgraph*/ update_depsgraph,
/*depends_on_time*/ depends_on_time,
/*depends_on_normals*/ nullptr,
/*foreach_ID_link*/ foreach_ID_link,
/*foreach_tex_link*/ nullptr,
/*free_runtime_data*/ nullptr,
/*panel_register*/ panel_register,
/*blend_write*/ nullptr,
/*blend_read*/ blend_read,
/*foreach_cache*/ nullptr,
};