Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht>2021-09-09 18:22:20 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-10 17:48:30 +0300
commit128eb6cbe928e58dfee1c64f340fd8d663134c26 (patch)
tree68c510ccb7bc3b60af06462392ec46da5baf53a6
parent42215d7cb8797ba5b631b9df93d07e895c4b1dda (diff)
Modifiers: export motion blur velocity through attribute
Previously fluid simulation and Alembic modifiers had a dedicated function to query the velocity for motion blur. Now use a more generic system where those modifiers output a velocity attribute. Advantages: * Geometry and particle nodes can output velocity through the same mechanism, or read the attribute coming from earlier modifiers. * The velocity can be preserved through modifiers like subdivision surface or auto smooth. * USD and Alembic previously only output velocity from fluid simulation, now they work with velocity from other sources too. * Simplifies the code for renderers like Cycles and exporters like Alembic and USD. This breaks compatibility: * External renderers and exporters accessing these velocities through the Python API now need to use the attribute instead. * Existing modifier node setups that create an attribute named "velocity" will render differently with motion blur. Differential Revision: https://developer.blender.org/D12305
-rw-r--r--intern/cycles/blender/blender_geometry.cpp4
-rw-r--r--intern/cycles/blender/blender_mesh.cpp181
-rw-r--r--intern/cycles/blender/blender_object.cpp12
-rw-r--r--intern/cycles/blender/blender_sync.h1
-rw-r--r--intern/cycles/blender/blender_util.h28
-rw-r--r--source/blender/blenkernel/BKE_attribute.h5
-rw-r--r--source/blender/blenkernel/intern/attribute.c25
-rw-r--r--source/blender/blenkernel/intern/fluid.c65
-rw-r--r--source/blender/blenkernel/intern/modifier.c1
-rw-r--r--source/blender/blenloader/intern/versioning_290.c2
-rw-r--r--source/blender/io/alembic/ABC_alembic.h14
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc56
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.h5
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.h6
-rw-r--r--source/blender/io/alembic/intern/abc_reader_curves.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_curves.h4
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc80
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.h8
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.h10
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc140
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc40
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.h2
-rw-r--r--source/blender/makesdna/DNA_fluid_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_fluid_types.h9
-rw-r--r--source/blender/makesdna/DNA_modifier_defaults.h4
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h23
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c24
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c81
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c34
30 files changed, 300 insertions, 570 deletions
diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp
index acc089a286c..b1de37dac10 100644
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@ -189,8 +189,10 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
/* Ensure we only sync instanced geometry once. */
Geometry *geom = object->get_geometry();
- if (geometry_motion_synced.find(geom) != geometry_motion_synced.end())
+ if (geometry_motion_synced.find(geom) != geometry_motion_synced.end() ||
+ geometry_motion_attribute_synced.find(geom) != geometry_motion_attribute_synced.end()) {
return;
+ }
geometry_motion_synced.insert(geom);
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9bb3447f56b..7ec430eb7fe 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -347,16 +347,57 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
}
}
-static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
+static void attr_create_motion(Mesh *mesh, BL::Attribute &b_attribute, const float motion_scale)
+{
+ if (!(b_attribute.domain() == BL::Attribute::domain_POINT) &&
+ (b_attribute.data_type() == BL::Attribute::data_type_FLOAT_VECTOR)) {
+ return;
+ }
+
+ BL::FloatVectorAttribute b_vector_attribute(b_attribute);
+ const int numverts = mesh->get_verts().size();
+
+ /* Find or add attribute */
+ float3 *P = &mesh->get_verts()[0];
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+
+ /* Only export previous and next frame, we don't have any in between data. */
+ float motion_times[2] = {-1.0f, 1.0f};
+ for (int step = 0; step < 2; step++) {
+ const float relative_time = motion_times[step] * 0.5f * motion_scale;
+ float3 *mP = attr_mP->data_float3() + step * numverts;
+
+ for (int i = 0; i < numverts; i++) {
+ mP[i] = P[i] + get_float3(b_vector_attribute.data[i].vector()) * relative_time;
+ }
+ }
+}
+
+static void attr_create_generic(Scene *scene,
+ Mesh *mesh,
+ BL::Mesh &b_mesh,
+ const bool subdivision,
+ const bool need_motion,
+ const float motion_scale)
{
if (subdivision) {
/* TODO: Handle subdivision correctly. */
return;
}
AttributeSet &attributes = mesh->attributes;
+ static const ustring u_velocity("velocity");
for (BL::Attribute &b_attribute : b_mesh.attributes) {
const ustring name{b_attribute.name().c_str()};
+
+ if (need_motion && name == u_velocity) {
+ attr_create_motion(mesh, b_attribute, motion_scale);
+ }
+
if (!mesh->need_attribute(scene, name)) {
continue;
}
@@ -859,8 +900,10 @@ static void create_mesh(Scene *scene,
Mesh *mesh,
BL::Mesh &b_mesh,
const array<Node *> &used_shaders,
- bool subdivision = false,
- bool subdivide_uvs = true)
+ const bool need_motion,
+ const float motion_scale,
+ const bool subdivision = false,
+ const bool subdivide_uvs = true)
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
@@ -974,7 +1017,7 @@ static void create_mesh(Scene *scene,
attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision);
attr_create_random_per_island(scene, mesh, b_mesh, subdivision);
- attr_create_generic(scene, mesh, b_mesh, subdivision);
+ attr_create_generic(scene, mesh, b_mesh, subdivision, need_motion, motion_scale);
if (subdivision) {
attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
@@ -1002,6 +1045,8 @@ static void create_subd_mesh(Scene *scene,
BObjectInfo &b_ob_info,
BL::Mesh &b_mesh,
const array<Node *> &used_shaders,
+ const bool need_motion,
+ const float motion_scale,
float dicing_rate,
int max_subdivisions)
{
@@ -1010,7 +1055,7 @@ static void create_subd_mesh(Scene *scene,
BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
- create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
+ create_mesh(scene, mesh, b_mesh, used_shaders, need_motion, motion_scale, true, subdivide_uvs);
/* export creases */
size_t num_creases = 0;
@@ -1074,96 +1119,6 @@ static bool mesh_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
return true;
}
-static void sync_mesh_cached_velocities(BObjectInfo &b_ob_info, Scene *scene, Mesh *mesh)
-{
- if (!mesh_need_motion_attribute(b_ob_info, scene)) {
- return;
- }
-
- BL::Object b_ob = b_ob_info.real_object;
- BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, true, nullptr);
-
- if (!b_mesh_cache) {
- return;
- }
-
- if (!MeshSequenceCacheModifier_read_velocity_get(&b_mesh_cache.ptr)) {
- return;
- }
-
- const size_t numverts = mesh->get_verts().size();
-
- if (b_mesh_cache.vertex_velocities.length() != numverts) {
- return;
- }
-
- /* Find or add attribute */
- float3 *P = &mesh->get_verts()[0];
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- }
-
- /* Only export previous and next frame, we don't have any in between data. */
- float motion_times[2] = {-1.0f, 1.0f};
- for (int step = 0; step < 2; step++) {
- const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
- float3 *mP = attr_mP->data_float3() + step * numverts;
-
- BL::MeshSequenceCacheModifier::vertex_velocities_iterator vvi;
- int i = 0;
-
- for (b_mesh_cache.vertex_velocities.begin(vvi); vvi != b_mesh_cache.vertex_velocities.end();
- ++vvi, ++i) {
- mP[i] = P[i] + get_float3(vvi->velocity()) * relative_time;
- }
- }
-}
-
-static void sync_mesh_fluid_motion(BObjectInfo &b_ob_info, Scene *scene, Mesh *mesh)
-{
- if (!b_ob_info.is_real_object_data()) {
- return;
- }
- if (!mesh_need_motion_attribute(b_ob_info, scene)) {
- return;
- }
-
- BL::Object b_ob = b_ob_info.real_object;
- BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
-
- if (!b_fluid_domain)
- return;
-
- /* If the mesh has modifiers following the fluid domain we can't export motion. */
- if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size())
- return;
-
- /* Find or add attribute */
- float3 *P = &mesh->get_verts()[0];
- Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- if (!attr_mP) {
- attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
- }
-
- /* Only export previous and next frame, we don't have any in between data. */
- float motion_times[2] = {-1.0f, 1.0f};
- for (int step = 0; step < 2; step++) {
- float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
- float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size();
-
- BL::FluidDomainSettings::mesh_vertices_iterator svi;
- int i = 0;
-
- for (b_fluid_domain.mesh_vertices.begin(svi); svi != b_fluid_domain.mesh_vertices.end();
- ++svi, ++i) {
- mP[i] = P[i] + get_float3(svi->velocity()) * relative_time;
- }
- }
-}
-
void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
@@ -1187,6 +1142,13 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
b_data, b_ob_info, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
if (b_mesh) {
+ /* Motion blur attribute is relative to seconds, we need it relative to frames. */
+ const bool need_motion = mesh_need_motion_attribute(b_ob_info, scene);
+ const float motion_scale = (need_motion) ?
+ scene->motion_shutter_time() /
+ (b_scene.render().fps() / b_scene.render().fps_base()) :
+ 0.0f;
+
/* Sync mesh itself. */
if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE)
create_subd_mesh(scene,
@@ -1194,21 +1156,23 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
b_ob_info,
b_mesh,
new_mesh.get_used_shaders(),
+ need_motion,
+ motion_scale,
dicing_rate,
max_subdivisions);
else
- create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false);
+ create_mesh(scene,
+ &new_mesh,
+ b_mesh,
+ new_mesh.get_used_shaders(),
+ need_motion,
+ motion_scale,
+ false);
free_object_to_mesh(b_data, b_ob_info, b_mesh);
}
}
- /* cached velocities (e.g. from alembic archive) */
- sync_mesh_cached_velocities(b_ob_info, scene, &new_mesh);
-
- /* mesh fluid motion mantaflow */
- sync_mesh_fluid_motion(b_ob_info, scene, &new_mesh);
-
/* update original sockets */
mesh->clear_non_sockets();
@@ -1242,19 +1206,6 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
Mesh *mesh,
int motion_step)
{
- /* Fluid motion blur already exported. */
- BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob_info.real_object);
- if (b_fluid_domain) {
- return;
- }
-
- /* Cached motion blur already exported. */
- BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(
- b_ob_info.real_object, true, nullptr);
- if (mesh_cache) {
- return;
- }
-
/* Skip if no vertices were exported. */
size_t numverts = mesh->get_verts().size();
if (numverts == 0) {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 2243baca0b2..22d6edeb099 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -604,7 +604,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
* only available in preview renders since currently do not have a good cache policy, the
* data being loaded at once for all the frames. */
if (experimental && b_v3d) {
- b_mesh_cache = object_mesh_cache_find(b_ob, false, &has_subdivision_modifier);
+ b_mesh_cache = object_mesh_cache_find(b_ob, &has_subdivision_modifier);
use_procedural = b_mesh_cache && b_mesh_cache.cache_file().use_render_procedural();
}
@@ -719,6 +719,14 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
}
}
+ /* Check which geometry already has motion blur so it can be skipped. */
+ geometry_motion_attribute_synced.clear();
+ for (Geometry *geom : scene->geometry) {
+ if (geom->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
+ geometry_motion_attribute_synced.insert(geom);
+ }
+ }
+
/* note iteration over motion_times set happens in sorted order */
foreach (float relative_time, motion_times) {
/* center time is already handled. */
@@ -749,6 +757,8 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
sync_objects(b_depsgraph, b_v3d, relative_time);
}
+ geometry_motion_attribute_synced.clear();
+
/* we need to set the python thread state again because this
* function assumes it is being executed from python and will
* try to save the thread state */
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 76e8f23864c..d25c0ce1bc3 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -236,6 +236,7 @@ class BlenderSync {
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
set<Geometry *> geometry_synced;
set<Geometry *> geometry_motion_synced;
+ set<Geometry *> geometry_motion_attribute_synced;
set<float> motion_times;
void *world_map;
bool world_recalc;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index e69531ea707..04008d77d89 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -573,22 +573,6 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_
return use_deform_motion;
}
-static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
-{
- for (BL::Modifier &b_mod : b_ob.modifiers) {
- if (b_mod.is_a(&RNA_FluidModifier)) {
- BL::FluidModifier b_mmd(b_mod);
-
- if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
- b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
- return b_mmd.domain_settings();
- }
- }
- }
-
- return BL::FluidDomainSettings(PointerRNA_NULL);
-}
-
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
{
for (BL::Modifier &b_mod : b_ob.modifiers) {
@@ -606,7 +590,6 @@ static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b
}
static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob,
- bool check_velocity,
bool *has_subdivision_modifier)
{
for (int i = b_ob.modifiers.length() - 1; i >= 0; --i) {
@@ -614,13 +597,6 @@ static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b
if (b_mod.type() == BL::Modifier::type_MESH_SEQUENCE_CACHE) {
BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(b_mod);
-
- if (check_velocity) {
- if (!MeshSequenceCacheModifier_has_velocity_get(&mesh_cache.ptr)) {
- return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
- }
- }
-
return mesh_cache;
}
@@ -629,9 +605,7 @@ static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b
continue;
}
- /* Only skip the subsurf modifier if we are not checking for the mesh sequence cache modifier
- * for motion blur. */
- if (b_mod.type() == BL::Modifier::type_SUBSURF && !check_velocity) {
+ if (b_mod.type() == BL::Modifier::type_SUBSURF) {
if (has_subdivision_modifier) {
*has_subdivision_modifier = true;
}
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 5fda30224c6..7476474258b 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -66,6 +66,11 @@ bool BKE_id_attribute_remove(struct ID *id,
struct CustomDataLayer *layer,
struct ReportList *reports);
+struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id,
+ const char *name,
+ const int type,
+ const AttributeDomain domain);
+
AttributeDomain BKE_id_attribute_domain(struct ID *id, struct CustomDataLayer *layer);
int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer);
bool BKE_id_attribute_required(struct ID *id, struct CustomDataLayer *layer);
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c
index e9444cf88a6..ee8ef5e97f7 100644
--- a/source/blender/blenkernel/intern/attribute.c
+++ b/source/blender/blenkernel/intern/attribute.c
@@ -51,7 +51,7 @@ typedef struct DomainInfo {
int length;
} DomainInfo;
-static void get_domains(ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
+static void get_domains(const ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
{
memset(info, 0, sizeof(DomainInfo) * ATTR_DOMAIN_NUM);
@@ -223,6 +223,29 @@ bool BKE_id_attribute_remove(ID *id, CustomDataLayer *layer, ReportList *reports
return true;
}
+CustomDataLayer *BKE_id_attribute_find(const ID *id,
+ const char *name,
+ const int type,
+ const AttributeDomain domain)
+{
+ DomainInfo info[ATTR_DOMAIN_NUM];
+ get_domains(id, info);
+
+ CustomData *customdata = info[domain].customdata;
+ if (customdata == NULL) {
+ return NULL;
+ }
+
+ for (int i = 0; i < customdata->totlayer; i++) {
+ CustomDataLayer *layer = &customdata->layers[i];
+ if (layer->type == type && STREQ(layer->name, name)) {
+ return layer;
+ }
+ }
+
+ return NULL;
+}
+
int BKE_id_attributes_length(ID *id, const CustomDataMask mask)
{
DomainInfo info[ATTR_DOMAIN_NUM];
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 5a5e1208ff0..f13ed1f2bf7 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -39,6 +39,7 @@
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
+#include "BKE_attribute.h"
#include "BKE_effect.h"
#include "BKE_fluid.h"
#include "BKE_global.h"
@@ -529,8 +530,7 @@ static bool BKE_fluid_modifier_init(
copy_v3_v3_int(fds->res_max, res);
/* Set time, frame length = 0.1 is at 25fps. */
- float fps = scene->r.frs_sec / scene->r.frs_sec_base;
- fds->frame_length = DT_DEFAULT * (25.0f / fps) * fds->time_scale;
+ fds->frame_length = DT_DEFAULT * (25.0f / FPS) * fds->time_scale;
/* Initially dt is equal to frame length (dt can change with adaptive-time stepping though). */
fds->dt = fds->frame_length;
fds->time_per_frame = 0;
@@ -3256,7 +3256,10 @@ static void update_effectors(
BKE_effectors_free(effectors);
}
-static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob)
+static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
+ Scene *scene,
+ Mesh *orgmesh,
+ Object *ob)
{
Mesh *me;
MVert *mverts;
@@ -3303,22 +3306,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
/* Normals are per vertex, so these must match. */
BLI_assert(num_verts == num_normals);
- /* If needed, vertex velocities will be read too. */
- bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS;
- FluidDomainVertexVelocity *velarray = NULL;
- float time_mult = 25.0f * DT_DEFAULT;
-
- if (use_speedvectors) {
- if (fds->mesh_velocities) {
- MEM_freeN(fds->mesh_velocities);
- }
-
- fds->mesh_velocities = MEM_calloc_arrayN(
- num_verts, sizeof(FluidDomainVertexVelocity), "fluid_mesh_vertvelocities");
- fds->totvert = num_verts;
- velarray = fds->mesh_velocities;
- }
-
me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces);
if (!me) {
return NULL;
@@ -3350,6 +3337,18 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
/* Normals. */
normals = MEM_callocN(sizeof(short[3]) * num_normals, "Fluidmesh_tmp_normals");
+ /* Velocities. */
+ /* If needed, vertex velocities will be read too. */
+ bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS;
+ float(*velarray)[3] = NULL;
+ float time_mult = fds->dx / (DT_DEFAULT * (25.0f / FPS));
+
+ if (use_speedvectors) {
+ CustomDataLayer *velocity_layer = BKE_id_attribute_new(
+ &me->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, NULL);
+ velarray = velocity_layer->data;
+ }
+
/* Loop for vertices and normals. */
for (i = 0, no_s = normals; i < num_verts && i < num_normals; i++, mverts++, no_s += 3) {
@@ -3389,18 +3388,18 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
# endif
if (use_speedvectors) {
- velarray[i].vel[0] = manta_liquid_get_vertvel_x_at(fds->fluid, i) * (fds->dx / time_mult);
- velarray[i].vel[1] = manta_liquid_get_vertvel_y_at(fds->fluid, i) * (fds->dx / time_mult);
- velarray[i].vel[2] = manta_liquid_get_vertvel_z_at(fds->fluid, i) * (fds->dx / time_mult);
+ velarray[i][0] = manta_liquid_get_vertvel_x_at(fds->fluid, i) * time_mult;
+ velarray[i][1] = manta_liquid_get_vertvel_y_at(fds->fluid, i) * time_mult;
+ velarray[i][2] = manta_liquid_get_vertvel_z_at(fds->fluid, i) * time_mult;
# ifdef DEBUG_PRINT
/* Debugging: Print velocities of vertices. */
- printf("velarray[%d].vel[0]: %f, velarray[%d].vel[1]: %f, velarray[%d].vel[2]: %f\n",
+ printf("velarray[%d][0]: %f, velarray[%d][1]: %f, velarray[%d][2]: %f\n",
i,
- velarray[i].vel[0],
+ velarray[i][0],
i,
- velarray[i].vel[1],
+ velarray[i][1],
i,
- velarray[i].vel[2]);
+ velarray[i][2]);
# endif
}
}
@@ -3670,8 +3669,7 @@ static void manta_guiding(
Depsgraph *depsgraph, Scene *scene, Object *ob, FluidModifierData *fmd, int frame)
{
FluidDomainSettings *fds = fmd->domain;
- float fps = scene->r.frs_sec / scene->r.frs_sec_base;
- float dt = DT_DEFAULT * (25.0f / fps) * fds->time_scale;
+ float dt = DT_DEFAULT * (25.0f / FPS) * fds->time_scale;
BLI_mutex_lock(&object_update_lock);
@@ -3842,8 +3840,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
copy_v3_v3_int(o_shift, fds->shift);
/* Ensure that time parameters are initialized correctly before every step. */
- float fps = scene->r.frs_sec / scene->r.frs_sec_base;
- fds->frame_length = DT_DEFAULT * (25.0f / fps) * fds->time_scale;
+ fds->frame_length = DT_DEFAULT * (25.0f / FPS) * fds->time_scale;
fds->dt = fds->frame_length;
fds->time_per_frame = 0;
@@ -4216,7 +4213,7 @@ struct Mesh *BKE_fluid_modifier_do(
if (needs_viewport_update) {
/* Return generated geometry depending on domain type. */
if (fmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) {
- result = create_liquid_geometry(fmd->domain, me, ob);
+ result = create_liquid_geometry(fmd->domain, scene, me, ob);
}
if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
result = create_smoke_geometry(fmd->domain, me, ob);
@@ -4773,8 +4770,6 @@ static void BKE_fluid_modifier_freeDomain(FluidModifierData *fmd)
fmd->domain->point_cache[0] = NULL;
}
- MEM_SAFE_FREE(fmd->domain->mesh_velocities);
-
if (fmd->domain->coba) {
MEM_freeN(fmd->domain->coba);
}
@@ -5010,16 +5005,12 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->viscosity_exponent = fds->viscosity_exponent;
/* mesh options */
- if (fds->mesh_velocities) {
- tfds->mesh_velocities = MEM_dupallocN(fds->mesh_velocities);
- }
tfds->mesh_concave_upper = fds->mesh_concave_upper;
tfds->mesh_concave_lower = fds->mesh_concave_lower;
tfds->mesh_particle_radius = fds->mesh_particle_radius;
tfds->mesh_smoothen_pos = fds->mesh_smoothen_pos;
tfds->mesh_smoothen_neg = fds->mesh_smoothen_neg;
tfds->mesh_scale = fds->mesh_scale;
- tfds->totvert = fds->totvert;
tfds->mesh_generator = fds->mesh_generator;
/* secondary particle options */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index b328a31cda5..b55b02c7bf2 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1473,7 +1473,6 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
fmd->domain->tex_velocity_y = NULL;
fmd->domain->tex_velocity_z = NULL;
fmd->domain->tex_wt = NULL;
- fmd->domain->mesh_velocities = NULL;
BLO_read_data_address(reader, &fmd->domain->coba);
BLO_read_data_address(reader, &fmd->domain->effector_weights);
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index cb7a8ad592a..0e89c15ca1e 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1092,8 +1092,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (md->type == eModifierType_MeshSequenceCache) {
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
mcmd->velocity_scale = 1.0f;
- mcmd->vertex_velocities = NULL;
- mcmd->num_vertices = 0;
}
}
}
diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h
index 0a3a43bb21f..0b5e927f02f 100644
--- a/source/blender/io/alembic/ABC_alembic.h
+++ b/source/blender/io/alembic/ABC_alembic.h
@@ -117,7 +117,9 @@ struct Mesh *ABC_read_mesh(struct CacheReader *reader,
struct Mesh *existing_mesh,
const float time,
const char **err_str,
- int read_flags);
+ const int read_flags,
+ const char *velocity_name,
+ const float velocity_scale);
bool ABC_mesh_topology_changed(struct CacheReader *reader,
struct Object *ob,
@@ -133,16 +135,6 @@ struct CacheReader *CacheReader_open_alembic_object(struct CacheArchiveHandle *h
struct Object *object,
const char *object_path);
-bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name);
-
-/* r_vertex_velocities should point to a preallocated array of num_vertices floats */
-int ABC_read_velocity_cache(struct CacheReader *reader,
- const char *velocity_name,
- float time,
- float velocity_scale,
- int num_vertices,
- float *r_vertex_velocities);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 131b60b90fb..8f410978211 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -25,6 +25,7 @@
#include "BLI_assert.h"
#include "BLI_math_vector.h"
+#include "BKE_attribute.h"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
@@ -108,9 +109,6 @@ void ABCGenericMeshWriter::create_alembic_objects(const HierarchyContext *contex
OBoolProperty type(typeContainer, "meshtype");
type.set(subsurf_modifier_ == nullptr);
}
-
- Scene *scene_eval = DEG_get_evaluated_scene(args_.depsgraph);
- liquid_sim_modifier_ = get_liquid_sim_modifier(scene_eval, context->object);
}
Alembic::Abc::OObject ABCGenericMeshWriter::get_alembic_object() const
@@ -144,21 +142,6 @@ bool ABCGenericMeshWriter::export_as_subdivision_surface(Object *ob_eval) const
return false;
}
-ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object *ob)
-{
- ModifierData *md = BKE_modifiers_findby_type(ob, eModifierType_Fluidsim);
-
- if (md && (BKE_modifier_is_enabled(scene, md, eModifierMode_Render))) {
- FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
-
- if (fsmd->fss && fsmd->fss->type == OB_FLUIDSIM_DOMAIN) {
- return md;
- }
- }
-
- return nullptr;
-}
-
bool ABCGenericMeshWriter::is_supported(const HierarchyContext *context) const
{
if (args_.export_params->visible_objects_only) {
@@ -284,8 +267,7 @@ void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
write_generated_coordinates(abc_poly_mesh_schema_.getArbGeomParams(), m_custom_data_config);
}
- if (liquid_sim_modifier_ != nullptr) {
- get_velocities(mesh, velocities);
+ if (get_velocities(mesh, velocities)) {
mesh_sample.setVelocities(V3fArraySample(velocities));
}
@@ -368,11 +350,6 @@ void ABCGenericMeshWriter::write_face_sets(Object *object, struct Mesh *mesh, Sc
void ABCGenericMeshWriter::write_arb_geo_params(struct Mesh *me)
{
- if (liquid_sim_modifier_ != nullptr) {
- /* We don't need anything more for liquid meshes. */
- return;
- }
-
if (frame_has_been_written_ || !args_.export_params->vcolors) {
return;
}
@@ -387,27 +364,28 @@ void ABCGenericMeshWriter::write_arb_geo_params(struct Mesh *me)
write_custom_data(arb_geom_params, m_custom_data_config, &me->ldata, CD_MLOOPCOL);
}
-void ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
+bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
{
+ /* Export velocity attribute output by fluid sim, sequence cache modifier
+ * and geometry nodes. */
+ CustomDataLayer *velocity_layer = BKE_id_attribute_find(
+ &mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT);
+
+ if (velocity_layer == nullptr) {
+ return false;
+ }
+
const int totverts = mesh->totvert;
+ const float(*mesh_velocities)[3] = reinterpret_cast<float(*)[3]>(velocity_layer->data);
vels.clear();
vels.resize(totverts);
- FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(liquid_sim_modifier_);
- FluidsimSettings *fss = fmd->fss;
-
- if (fss->meshVelocities) {
- float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
-
- for (int i = 0; i < totverts; i++) {
- copy_yup_from_zup(vels[i].getValue(), mesh_vels);
- mesh_vels += 3;
- }
- }
- else {
- std::fill(vels.begin(), vels.end(), Imath::V3f(0.0f));
+ for (int i = 0; i < totverts; i++) {
+ copy_yup_from_zup(vels[i].getValue(), mesh_velocities[i]);
}
+
+ return true;
}
void ABCGenericMeshWriter::get_geo_groups(Object *object,
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.h b/source/blender/io/alembic/exporter/abc_writer_mesh.h
index 0e1792b9dab..fb8a01a3bbf 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.h
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.h
@@ -45,7 +45,6 @@ class ABCGenericMeshWriter : public ABCAbstractWriter {
* exported object. */
bool is_subd_;
ModifierData *subsurf_modifier_;
- ModifierData *liquid_sim_modifier_;
CDStreamConfig m_custom_data_config;
@@ -70,10 +69,8 @@ class ABCGenericMeshWriter : public ABCAbstractWriter {
void write_subd(HierarchyContext &context, Mesh *mesh);
template<typename Schema> void write_face_sets(Object *object, Mesh *mesh, Schema &schema);
- ModifierData *get_liquid_sim_modifier(Scene *scene_eval, Object *ob_eval);
-
void write_arb_geo_params(Mesh *me);
- void get_velocities(Mesh *mesh, std::vector<Imath::V3f> &vels);
+ bool get_velocities(Mesh *mesh, std::vector<Imath::V3f> &vels);
void get_geo_groups(Object *object,
Mesh *mesh,
std::map<std::string, std::vector<int32_t>> &geo_groups);
diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h
index e9736555ead..4fba6a2f0f7 100644
--- a/source/blender/io/alembic/intern/abc_customdata.h
+++ b/source/blender/io/alembic/intern/abc_customdata.h
@@ -122,6 +122,12 @@ void read_custom_data(const std::string &iobject_full_name,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss);
+void read_velocity(const Alembic::Abc::ICompoundProperty &prop,
+ const Alembic::Abc::PropertyHeader *prop_header,
+ const Alembic::Abc::ISampleSelector &selector,
+ const CDStreamConfig &config,
+ const char *velocity_name,
+ const float velocity_scale);
typedef enum {
ABC_UV_SCOPE_NONE,
ABC_UV_SCOPE_LOOP,
diff --git a/source/blender/io/alembic/intern/abc_reader_curves.cc b/source/blender/io/alembic/intern/abc_reader_curves.cc
index 27ee35d1b39..688ba23333a 100644
--- a/source/blender/io/alembic/intern/abc_reader_curves.cc
+++ b/source/blender/io/alembic/intern/abc_reader_curves.cc
@@ -283,6 +283,8 @@ void AbcCurveReader::read_curve_sample(Curve *cu,
Mesh *AbcCurveReader::read_mesh(Mesh *existing_mesh,
const ISampleSelector &sample_sel,
int /*read_flag*/,
+ const char * /*velocity_name*/,
+ const float /*velocity_scale*/,
const char **err_str)
{
ICurvesSchema::Sample sample;
diff --git a/source/blender/io/alembic/intern/abc_reader_curves.h b/source/blender/io/alembic/intern/abc_reader_curves.h
index 075ed5ca6a1..11b23c8a8cf 100644
--- a/source/blender/io/alembic/intern/abc_reader_curves.h
+++ b/source/blender/io/alembic/intern/abc_reader_curves.h
@@ -45,7 +45,9 @@ class AbcCurveReader : public AbcObjectReader {
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
struct Mesh *read_mesh(struct Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str);
void read_curve_sample(Curve *cu,
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index 77edd4908bd..dbccc8f2851 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_customdata_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -36,6 +37,7 @@
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
+#include "BKE_attribute.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -43,8 +45,10 @@
#include "BKE_object.h"
using Alembic::Abc::Int32ArraySamplePtr;
+using Alembic::Abc::IV3fArrayProperty;
using Alembic::Abc::P3fArraySamplePtr;
using Alembic::Abc::PropertyHeader;
+using Alembic::Abc::V3fArraySamplePtr;
using Alembic::AbcGeom::IC3fGeomParam;
using Alembic::AbcGeom::IC4fGeomParam;
@@ -420,6 +424,52 @@ static void get_weight_and_index(CDStreamConfig &config,
config.ceil_index = i1;
}
+static V3fArraySamplePtr get_velocity_prop(const ICompoundProperty &schema,
+ const ISampleSelector &selector,
+ const std::string &name)
+{
+ for (size_t i = 0; i < schema.getNumProperties(); i++) {
+ const PropertyHeader &header = schema.getPropertyHeader(i);
+
+ if (header.isCompound()) {
+ const ICompoundProperty &prop = ICompoundProperty(schema, header.getName());
+
+ if (has_property(prop, name)) {
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0);
+ if (velocity_prop) {
+ return velocity_prop.getValue(selector);
+ }
+ }
+ }
+ else if (header.isArray()) {
+ if (header.getName() == name) {
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0);
+ return velocity_prop.getValue(selector);
+ }
+ }
+ }
+
+ return V3fArraySamplePtr();
+}
+
+static void read_velocity(const V3fArraySamplePtr &velocities,
+ const CDStreamConfig &config,
+ const float velocity_scale)
+{
+ CustomDataLayer *velocity_layer = BKE_id_attribute_new(
+ &config.mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, NULL);
+ float(*velocity)[3] = (float(*)[3])velocity_layer->data;
+
+ const int num_velocity_vectors = static_cast<int>(velocities->size());
+ BLI_assert(num_velocity_vectors == config.mesh->totvert);
+
+ for (int i = 0; i < num_velocity_vectors; i++) {
+ const Imath::V3f &vel_in = (*velocities)[i];
+ copy_zup_from_yup(velocity[i], vel_in.getValue());
+ mul_v3_fl(velocity[i], velocity_scale);
+ }
+}
+
static void read_mesh_sample(const std::string &iobject_full_name,
ImportSettings *settings,
const IPolyMeshSchema &schema,
@@ -458,6 +508,13 @@ static void read_mesh_sample(const std::string &iobject_full_name,
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
read_custom_data(iobject_full_name, schema.getArbGeomParams(), config, selector);
}
+
+ if (!settings->velocity_name.empty() && settings->velocity_scale != 0.0f) {
+ V3fArraySamplePtr velocities = get_velocity_prop(schema, selector, settings->velocity_name);
+ if (velocities) {
+ read_velocity(velocities, config, settings->velocity_scale);
+ }
+ }
}
CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation)
@@ -563,7 +620,7 @@ void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
m_object->data = mesh;
- Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, nullptr);
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
if (read_mesh != mesh) {
/* XXX FIXME: after 2.80; mesh->flag isn't copied by #BKE_mesh_nomain_to_mesh(). */
/* read_mesh can be freed by BKE_mesh_nomain_to_mesh(), so get the flag before that happens. */
@@ -630,7 +687,9 @@ bool AbcMeshReader::topology_changed(Mesh *existing_mesh, const ISampleSelector
Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
const ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str)
{
IPolyMeshSchema::Sample sample;
@@ -673,6 +732,8 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
/* Only read point data when streaming meshes, unless we need to create new ones. */
ImportSettings settings;
settings.read_flag |= read_flag;
+ settings.velocity_name = velocity_name;
+ settings.velocity_scale = velocity_scale;
if (topology_changed(existing_mesh, sample_sel)) {
new_mesh = BKE_mesh_new_nomain_from_template(
@@ -829,6 +890,13 @@ static void read_subd_sample(const std::string &iobject_full_name,
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
read_custom_data(iobject_full_name, schema.getArbGeomParams(), config, selector);
}
+
+ if (!settings->velocity_name.empty() && settings->velocity_scale != 0.0f) {
+ V3fArraySamplePtr velocities = get_velocity_prop(schema, selector, settings->velocity_name);
+ if (velocities) {
+ read_velocity(velocities, config, settings->velocity_scale);
+ }
+ }
}
/* ************************************************************************** */
@@ -876,7 +944,7 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
m_object->data = mesh;
- Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, nullptr);
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
if (read_mesh != mesh) {
BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_EVERYTHING, true);
}
@@ -935,7 +1003,9 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
const ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str)
{
ISubDSchema::Sample sample;
@@ -962,6 +1032,8 @@ Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
ImportSettings settings;
settings.read_flag |= read_flag;
+ settings.velocity_name = velocity_name;
+ settings.velocity_scale = velocity_scale;
if (existing_mesh->totvert != positions->size()) {
new_mesh = BKE_mesh_new_nomain_from_template(
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.h b/source/blender/io/alembic/intern/abc_reader_mesh.h
index 3329b723b77..d9f89cc8085 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.h
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.h
@@ -42,7 +42,9 @@ class AbcMeshReader : public AbcObjectReader {
struct Mesh *read_mesh(struct Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str) override;
bool topology_changed(Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &sample_sel) override;
@@ -73,7 +75,9 @@ class AbcSubDReader : public AbcObjectReader {
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
struct Mesh *read_mesh(struct Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str);
};
diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc
index 9a5ffd04bd1..a6d46c4b42a 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.cc
+++ b/source/blender/io/alembic/intern/abc_reader_object.cc
@@ -167,6 +167,8 @@ Imath::M44d get_matrix(const IXformSchema &schema, const float time)
struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
int UNUSED(read_flag),
+ const char *UNUSED(velocity_name),
+ const float UNUSED(velocity_scale),
const char **UNUSED(err_str))
{
return existing_mesh;
diff --git a/source/blender/io/alembic/intern/abc_reader_object.h b/source/blender/io/alembic/intern/abc_reader_object.h
index 89590b26b61..6e97f841a88 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.h
+++ b/source/blender/io/alembic/intern/abc_reader_object.h
@@ -50,6 +50,10 @@ struct ImportSettings {
/* From MeshSeqCacheModifierData.read_flag */
int read_flag;
+ /* From CacheFile and MeshSeqCacheModifierData */
+ std::string velocity_name;
+ float velocity_scale;
+
bool validate_meshes;
bool always_add_cache_reader;
@@ -65,6 +69,8 @@ struct ImportSettings {
sequence_len(1),
sequence_offset(0),
read_flag(0),
+ velocity_name(""),
+ velocity_scale(1.0f),
validate_meshes(false),
always_add_cache_reader(false),
cache_file(NULL)
@@ -143,7 +149,9 @@ class AbcObjectReader {
virtual struct Mesh *read_mesh(struct Mesh *mesh,
const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale,
const char **err_str);
virtual bool topology_changed(Mesh *existing_mesh,
const Alembic::Abc::ISampleSelector &sample_sel);
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index deb945b767c..63565b902f3 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -786,7 +786,9 @@ Mesh *ABC_read_mesh(CacheReader *reader,
Mesh *existing_mesh,
const float time,
const char **err_str,
- int read_flag)
+ const int read_flag,
+ const char *velocity_name,
+ const float velocity_scale)
{
AbcObjectReader *abc_reader = get_abc_reader(reader, ob, err_str);
if (abc_reader == nullptr) {
@@ -794,7 +796,8 @@ Mesh *ABC_read_mesh(CacheReader *reader,
}
ISampleSelector sample_sel = sample_selector_for_time(time);
- return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
+ return abc_reader->read_mesh(
+ existing_mesh, sample_sel, read_flag, velocity_name, velocity_scale, err_str);
}
bool ABC_mesh_topology_changed(
@@ -860,136 +863,3 @@ CacheReader *CacheReader_open_alembic_object(CacheArchiveHandle *handle,
return reinterpret_cast<CacheReader *>(abc_reader);
}
-
-/* ************************************************************************** */
-
-static const PropertyHeader *get_property_header(const IPolyMeshSchema &schema, const char *name)
-{
- const PropertyHeader *prop_header = schema.getPropertyHeader(name);
-
- if (prop_header) {
- return prop_header;
- }
-
- ICompoundProperty prop = schema.getArbGeomParams();
-
- if (!has_property(prop, name)) {
- return nullptr;
- }
-
- return prop.getPropertyHeader(name);
-}
-
-bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name)
-{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
-
- if (!abc_reader) {
- return false;
- }
-
- IObject iobject = abc_reader->iobject();
-
- if (!iobject.valid()) {
- return false;
- }
-
- const ObjectHeader &header = iobject.getHeader();
-
- if (!IPolyMesh::matches(header)) {
- return false;
- }
-
- IPolyMesh mesh(iobject, kWrapExisting);
- IPolyMeshSchema schema = mesh.getSchema();
-
- const PropertyHeader *prop_header = get_property_header(schema, name);
-
- if (!prop_header) {
- return false;
- }
-
- return IV3fArrayProperty::matches(prop_header->getMetaData());
-}
-
-static V3fArraySamplePtr get_velocity_prop(const IPolyMeshSchema &schema,
- const ISampleSelector &iss,
- const std::string &name)
-{
- const PropertyHeader *prop_header = schema.getPropertyHeader(name);
-
- if (prop_header) {
- const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0);
- return velocity_prop.getValue(iss);
- }
-
- ICompoundProperty prop = schema.getArbGeomParams();
-
- if (!has_property(prop, name)) {
- return V3fArraySamplePtr();
- }
-
- const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0);
-
- if (velocity_prop) {
- return velocity_prop.getValue(iss);
- }
-
- return V3fArraySamplePtr();
-}
-
-int ABC_read_velocity_cache(CacheReader *reader,
- const char *velocity_name,
- const float time,
- float velocity_scale,
- int num_vertices,
- float *r_vertex_velocities)
-{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
-
- if (!abc_reader) {
- return -1;
- }
-
- IObject iobject = abc_reader->iobject();
-
- if (!iobject.valid()) {
- return -1;
- }
-
- const ObjectHeader &header = iobject.getHeader();
-
- if (!IPolyMesh::matches(header)) {
- return -1;
- }
-
- IPolyMesh mesh(iobject, kWrapExisting);
- IPolyMeshSchema schema = mesh.getSchema();
- ISampleSelector sample_sel(time);
- const IPolyMeshSchema::Sample sample = schema.getValue(sample_sel);
-
- V3fArraySamplePtr velocities = get_velocity_prop(schema, sample_sel, velocity_name);
-
- if (!velocities) {
- return -1;
- }
-
- float vel[3];
-
- int num_velocity_vectors = static_cast<int>(velocities->size());
-
- if (num_velocity_vectors != num_vertices) {
- return -1;
- }
-
- for (size_t i = 0; i < velocities->size(); ++i) {
- const Imath::V3f &vel_in = (*velocities)[i];
- copy_zup_from_yup(vel, vel_in.getValue());
-
- mul_v3_fl(vel, velocity_scale);
-
- copy_v3_v3(r_vertex_velocities + i * 3, vel);
- }
-
- return num_vertices;
-}
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index 54316e56867..61b14155dd0 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -26,6 +26,7 @@
#include "BLI_assert.h"
#include "BLI_math_vector.h"
+#include "BKE_attribute.h"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
@@ -219,7 +220,7 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
if (usd_export_context_.export_params.export_normals) {
write_normals(mesh, usd_mesh);
}
- write_surface_velocity(context.object, mesh, usd_mesh);
+ write_surface_velocity(mesh, usd_mesh);
/* TODO(Sybren): figure out what happens when the face groups change. */
if (frame_has_been_written_) {
@@ -409,42 +410,25 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
usd_mesh.SetNormalsInterpolation(pxr::UsdGeomTokens->faceVarying);
}
-void USDGenericMeshWriter::write_surface_velocity(Object *object,
- const Mesh *mesh,
- pxr::UsdGeomMesh usd_mesh)
+void USDGenericMeshWriter::write_surface_velocity(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh)
{
- /* Only velocities from the fluid simulation are exported. This is the most important case,
- * though, as the baked mesh changes topology all the time, and thus computing the velocities
- * at import time in a post-processing step is hard. */
- ModifierData *md = BKE_modifiers_findby_type(object, eModifierType_Fluidsim);
- if (md == nullptr) {
- return;
- }
+ /* Export velocity attribute output by fluid sim, sequence cache modifier
+ * and geometry nodes. */
+ CustomDataLayer *velocity_layer = BKE_id_attribute_find(
+ &mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT);
- /* Check that the fluid sim modifier is enabled and has useful data. */
- const bool use_render = (DEG_get_mode(usd_export_context_.depsgraph) == DAG_EVAL_RENDER);
- const ModifierMode required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
- const Scene *scene = DEG_get_evaluated_scene(usd_export_context_.depsgraph);
- if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
- return;
- }
- FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
- if (!fsmd->fss || fsmd->fss->type != OB_FLUIDSIM_DOMAIN) {
- return;
- }
- FluidsimSettings *fss = fsmd->fss;
- if (!fss->meshVelocities) {
+ if (velocity_layer == nullptr) {
return;
}
+ const float(*velocities)[3] = reinterpret_cast<float(*)[3]>(velocity_layer->data);
+
/* Export per-vertex velocity vectors. */
pxr::VtVec3fArray usd_velocities;
usd_velocities.reserve(mesh->totvert);
- FluidVertexVelocity *mesh_velocities = fss->meshVelocities;
- for (int vertex_idx = 0, totvert = mesh->totvert; vertex_idx < totvert;
- ++vertex_idx, ++mesh_velocities) {
- usd_velocities.push_back(pxr::GfVec3f(mesh_velocities->vel));
+ for (int vertex_idx = 0, totvert = mesh->totvert; vertex_idx < totvert; ++vertex_idx) {
+ usd_velocities.push_back(pxr::GfVec3f(velocities[vertex_idx]));
}
pxr::UsdTimeCode timecode = get_export_time_code();
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.h b/source/blender/io/usd/intern/usd_writer_mesh.h
index 6345f2d4240..d60a6c4a59b 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.h
+++ b/source/blender/io/usd/intern/usd_writer_mesh.h
@@ -49,7 +49,7 @@ class USDGenericMeshWriter : public USDAbstractWriter {
const MaterialFaceGroups &usd_face_groups);
void write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh);
void write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh);
- void write_surface_velocity(Object *object, const Mesh *mesh, pxr::UsdGeomMesh usd_mesh);
+ void write_surface_velocity(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh);
};
class USDMeshWriter : public USDGenericMeshWriter {
diff --git a/source/blender/makesdna/DNA_fluid_defaults.h b/source/blender/makesdna/DNA_fluid_defaults.h
index 95f5b8b66b0..4135c4d40a8 100644
--- a/source/blender/makesdna/DNA_fluid_defaults.h
+++ b/source/blender/makesdna/DNA_fluid_defaults.h
@@ -50,7 +50,6 @@
.tex_flags = NULL, \
.tex_range_field = NULL, \
.guide_parent = NULL, \
- .mesh_velocities = NULL, \
.effector_weights = NULL, /* #BKE_effector_add_weights. */ \
.p0 = {0.0f, 0.0f, 0.0f}, \
.p1 = {0.0f, 0.0f, 0.0f}, \
@@ -122,7 +121,6 @@
.mesh_smoothen_pos = 1, \
.mesh_smoothen_neg = 1, \
.mesh_scale = 2, \
- .totvert = 0, \
.mesh_generator = FLUID_DOMAIN_MESH_IMPROVED, \
.particle_type = 0, \
.particle_scale = 1, \
diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h
index 835af3c6ff8..0cbef540306 100644
--- a/source/blender/makesdna/DNA_fluid_types.h
+++ b/source/blender/makesdna/DNA_fluid_types.h
@@ -480,10 +480,6 @@ enum {
SM_HRES_FULLSAMPLE = 2,
};
-typedef struct FluidDomainVertexVelocity {
- float vel[3];
-} FluidDomainVertexVelocity;
-
typedef struct FluidDomainSettings {
/* -- Runtime-only fields (from here on). -- */
@@ -509,8 +505,6 @@ typedef struct FluidDomainSettings {
struct GPUTexture *tex_flags;
struct GPUTexture *tex_range_field;
struct Object *guide_parent;
- /** Vertex velocities of simulated fluid mesh. */
- struct FluidDomainVertexVelocity *mesh_velocities;
struct EffectorWeights *effector_weights;
/* Domain object data. */
@@ -607,9 +601,8 @@ typedef struct FluidDomainSettings {
int mesh_smoothen_pos;
int mesh_smoothen_neg;
int mesh_scale;
- int totvert;
short mesh_generator;
- char _pad6[6]; /* Unused. */
+ char _pad6[2]; /* Unused. */
/* Secondary particle options. */
int particle_type;
diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index 1b3dbd148df..5b2694f420b 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -419,10 +419,6 @@
.velocity_scale = 1.0f, \
.reader = NULL, \
.reader_object_path = "", \
- .vertex_velocities = NULL, \
- .num_vertices = 0, \
- .velocity_delta = 0.0f, \
- .last_lookup_time = 0.0f, \
}
#define _DNA_DEFAULT_MirrorModifierData \
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 8520786a030..31daa778b03 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2144,10 +2144,6 @@ enum {
MOD_NORMALEDIT_MIX_MUL = 3,
};
-typedef struct MeshCacheVertexVelocity {
- float vel[3];
-} MeshCacheVertexVelocity;
-
typedef struct MeshSeqCacheModifierData {
ModifierData modifier;
@@ -2163,25 +2159,6 @@ typedef struct MeshSeqCacheModifierData {
/* Runtime. */
struct CacheReader *reader;
char reader_object_path[1024];
-
- /* Vertex velocities read from the cache. The velocities are not automatically read during
- * modifier execution, and therefore have to manually be read when needed. This is only used
- * through the RNA for now. */
- struct MeshCacheVertexVelocity *vertex_velocities;
-
- /* The number of vertices of the Alembic mesh, set when the modifier is executed. */
- int num_vertices;
-
- /* 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. */
- float velocity_delta;
-
- /* Caches the scene time (in seconds) used to lookup data in the Alembic archive when the
- * modifier was last executed. Used to access Alembic samples through the RNA. */
- float last_lookup_time;
-
- int _pad1;
- void *_pad2;
} MeshSeqCacheModifierData;
/* MeshSeqCacheModifierData.read_flag */
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 10e899b7ee3..90e77406f23 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -1242,22 +1242,6 @@ static void rna_Fluid_flowtype_set(struct PointerRNA *ptr, int value)
#else
-static void rna_def_fluid_mesh_vertices(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- srna = RNA_def_struct(brna, "FluidDomainVertexVelocity", NULL);
- RNA_def_struct_ui_text(srna, "Fluid Mesh Velocity", "Velocity of a simulated fluid mesh");
- RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
-
- prop = RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_sdna(prop, NULL, "vel");
- RNA_def_property_ui_text(prop, "Velocity", "");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-}
-
static void rna_def_fluid_domain_settings(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2019,14 +2003,6 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mesh generator", "Which particle level set generator to use");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_update");
- prop = RNA_def_property(srna, "mesh_vertices", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "mesh_velocities", "totvert");
- RNA_def_property_struct_type(prop, "FluidDomainVertexVelocity");
- RNA_def_property_ui_text(
- prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation");
-
- rna_def_fluid_mesh_vertices(brna);
-
prop = RNA_def_property(srna, "use_mesh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_USE_MESH);
RNA_def_property_ui_text(prop, "Use Mesh", "Enable fluid mesh (using amplification)");
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index fb4fd4528d6..c99dfea524f 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1601,51 +1601,6 @@ static bool rna_Modifier_show_expanded_get(PointerRNA *ptr)
return md->ui_expand_flag & UI_PANEL_DATA_EXPAND_ROOT;
}
-static int rna_MeshSequenceCacheModifier_has_velocity_get(PointerRNA *ptr)
-{
-# ifdef WITH_ALEMBIC
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
- return ABC_has_vec3_array_property_named(mcmd->reader, mcmd->cache_file->velocity_name);
-# else
- return false;
- UNUSED_VARS(ptr);
-# endif
-}
-
-static int rna_MeshSequenceCacheModifier_read_velocity_get(PointerRNA *ptr)
-{
-# ifdef WITH_ALEMBIC
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
-
- if (mcmd->num_vertices == 0) {
- return 0;
- }
-
- if (mcmd->vertex_velocities) {
- MEM_freeN(mcmd->vertex_velocities);
- }
-
- mcmd->vertex_velocities = MEM_mallocN(sizeof(MeshCacheVertexVelocity) * mcmd->num_vertices,
- "Mesh Cache Velocities");
-
- int num_read = ABC_read_velocity_cache(mcmd->reader,
- mcmd->cache_file->velocity_name,
- mcmd->last_lookup_time,
- mcmd->velocity_scale * mcmd->velocity_delta,
- mcmd->num_vertices,
- (float *)mcmd->vertex_velocities);
-
- if (num_read == -1 || num_read != mcmd->num_vertices) {
- return false;
- }
-
- return true;
-# else
- return false;
- UNUSED_VARS(ptr);
-# endif
-}
-
static bool rna_NodesModifier_node_group_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
bNodeTree *ntree = value.data;
@@ -6118,22 +6073,6 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
-static void rna_def_mesh_cache_velocities(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- srna = RNA_def_struct(brna, "MeshCacheVertexVelocity", NULL);
- RNA_def_struct_ui_text(srna, "Mesh Cache Velocity", "Velocity attribute of an Alembic mesh");
- RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
-
- prop = RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_sdna(prop, NULL, "vel");
- RNA_def_property_ui_text(prop, "Velocity", "");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-}
-
static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
{
StructRNA *srna;
@@ -6190,26 +6129,6 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
"Multiplier used to control the magnitude of the velocity vectors for time effects");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- /* -------------------------- Velocity Vectors -------------------------- */
-
- prop = RNA_def_property(srna, "vertex_velocities", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "vertex_velocities", "num_vertices");
- RNA_def_property_struct_type(prop, "MeshCacheVertexVelocity");
- RNA_def_property_ui_text(
- prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation");
-
- rna_def_mesh_cache_velocities(brna);
-
- prop = RNA_def_property(srna, "has_velocity", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_ui_text(prop, "Has Velocity Cache", "");
- RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_has_velocity_get", NULL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "read_velocity", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_ui_text(prop, "Read Velocity Cache", "");
- RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_read_velocity_get", NULL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
RNA_define_lib_overridable(false);
}
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 259c1cb2417..bcaf294ec8b 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -105,10 +105,6 @@ static void freeData(ModifierData *md)
mcmd->reader_object_path[0] = '\0';
BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
-
- if (mcmd->vertex_velocities) {
- MEM_freeN(mcmd->vertex_velocities);
- }
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -233,11 +229,26 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *result = NULL;
switch (cache_file->type) {
- case CACHEFILE_TYPE_ALEMBIC:
+ case CACHEFILE_TYPE_ALEMBIC: {
# ifdef WITH_ALEMBIC
- result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
+ /* 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. */
+ float velocity_scale = mcmd->velocity_scale;
+ if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_FRAME) {
+ velocity_scale *= FPS;
+ }
+
+ result = ABC_read_mesh(mcmd->reader,
+ ctx->object,
+ mesh,
+ time,
+ &err_str,
+ mcmd->read_flag,
+ mcmd->cache_file->velocity_name,
+ velocity_scale);
# endif
break;
+ }
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
result = USD_read_mesh(
@@ -248,17 +259,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
break;
}
- mcmd->velocity_delta = 1.0f;
- if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) {
- mcmd->velocity_delta /= FPS;
- }
-
- mcmd->last_lookup_time = time;
-
- if (result != NULL) {
- mcmd->num_vertices = result->totvert;
- }
-
if (err_str) {
BKE_modifier_set_error(ctx->object, md, "%s", err_str);
}