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 /source/blender/io/alembic
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
Diffstat (limited to 'source/blender/io/alembic')
-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
11 files changed, 130 insertions, 197 deletions
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;
-}