[Bf-blender-cvs] [b49f0f990b5] cycles_procedural_api: first pass at reading arbitrary attributes
Kévin Dietrich
noreply at git.blender.org
Sat Oct 3 04:18:21 CEST 2020
Commit: b49f0f990b51aefbf752fa998e61cfebaf801ca9
Author: Kévin Dietrich
Date: Sun Sep 27 20:52:19 2020 +0200
Branches: cycles_procedural_api
https://developer.blender.org/rBb49f0f990b51aefbf752fa998e61cfebaf801ca9
first pass at reading arbitrary attributes
For now, we only read vertex colors.
===================================================================
M intern/cycles/render/alembic.cpp
M intern/cycles/render/alembic.h
===================================================================
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp
index 70e0053cdd8..58fbad0cf31 100644
--- a/intern/cycles/render/alembic.cpp
+++ b/intern/cycles/render/alembic.cpp
@@ -166,11 +166,27 @@ void AlembicObject::load_all_data(IPolyMeshSchema &schema)
frame_data.clear();
// TODO : store other properties and have a better structure to store these arrays
+ auto geometry_ = object->get_geometry();
+
+ AttributeRequestSet requested_attributes;
+
+ foreach (Node *node, geometry_->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+
+ foreach (const AttributeRequest &attr, shader->attributes.requests) {
+ if (attr.name != "") {
+ requested_attributes.add(attr.name);
+ }
+ }
+ }
+
for (size_t i = 0; i < schema.getNumSamples(); ++i) {
frame_data.emplace_back();
AlembicObject::DataCache &data_cache = frame_data.back();
- auto sample = schema.getValue(ISampleSelector(static_cast<index_t>(i)));
+ ISampleSelector iss = ISampleSelector(static_cast<index_t>(i));
+
+ auto sample = schema.getValue(iss);
auto positions = sample.getPositions();
@@ -211,11 +227,75 @@ void AlembicObject::load_all_data(IPolyMeshSchema &schema)
index_offset += face_counts_array[i];
}
}
+
+ foreach (const AttributeRequest &attr, requested_attributes.requests) {
+ read_attribute(schema.getArbGeomParams(), iss, attr.name, data_cache);
+ }
}
data_loaded = true;
}
+void AlembicObject::read_attribute(const ICompoundProperty &arb_geom_params, const ISampleSelector &iss, const ustring &attr_name, DataCache &data_cache)
+{
+ for (size_t i = 0; i < arb_geom_params.getNumProperties(); ++i) {
+ const PropertyHeader &prop = arb_geom_params.getPropertyHeader(i);
+
+ if (prop.getName() != attr_name) {
+ continue;
+ }
+
+ if (IV2fProperty::matches(prop.getMetaData()) && Alembic::AbcGeom::isUV(prop)) {
+ // TODO : UV indices
+// const IV2fGeomParam ¶m = IV2fGeomParam(arb_geom_params, prop.getName());
+
+// IV2fGeomParam::Sample sample;
+// param.getIndexed(sample, iss);
+
+// if (param.getScope() == kFacevaryingScope) {
+// V2fArraySamplePtr values = sample.getVals();
+// UInt32ArraySamplePtr indices = sample.getIndices();
+
+// AttributeData &attribute = data_cache.attributes.emplace_back();
+// attribute.name = attr_name;
+// attribute.std = ATTR_STD_UV;
+// }
+ }
+ else if (IC3fProperty::matches(prop.getMetaData())) {
+ const IC3fGeomParam ¶m = IC3fGeomParam(arb_geom_params, prop.getName());
+
+ IC3fGeomParam::Sample sample;
+ param.getIndexed(sample, iss);
+
+ C3fArraySamplePtr values = sample.getVals();
+
+ AttributeData &attribute = data_cache.attributes.emplace_back();
+ attribute.name = attr_name;
+
+ if (param.getScope() == kVaryingScope) {
+ attribute.std = ATTR_STD_VERTEX_COLOR;
+ attribute.data.resize(data_cache.triangles.size() * 3 * sizeof(uchar4));
+
+ uchar4 *data_uchar4 = reinterpret_cast<uchar4 *>(attribute.data.data());
+
+ int offset = 0;
+ for (const int3 &tri : data_cache.triangles) {
+ auto v = (*values)[tri.x];
+ data_uchar4[offset + 0] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ v = (*values)[tri.y];
+ data_uchar4[offset + 1] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ v = (*values)[tri.z];
+ data_uchar4[offset + 2] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ offset += 3;
+ }
+ }
+ }
+ }
+}
+
NODE_DEFINE(AlembicProcedural)
{
NodeType *type = NodeType::add("alembic", create);
@@ -432,6 +512,11 @@ void AlembicProcedural::read_mesh(Scene *scene,
attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
}
+ for (const AlembicObject::AttributeData &attribute : data.attributes) {
+ auto attr = mesh->attributes.add(attribute.std, attribute.name);
+ memcpy(attr->data_uchar4(), attribute.data.data(), attribute.data.size());
+ }
+
if (mesh->is_modified()) {
// TODO : check for modification of subdivision data (is a separate object in Alembic)
bool need_rebuild = mesh->triangles_is_modified();
diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h
index 52cd2dc59cf..14e98765b29 100644
--- a/intern/cycles/render/alembic.h
+++ b/intern/cycles/render/alembic.h
@@ -17,6 +17,7 @@
#pragma once
#include "graph/node.h"
+#include "render/attribute.h"
#include "render/procedural.h"
#include "util/util_transform.h"
#include "util/util_vector.h"
@@ -53,10 +54,19 @@ class AlembicObject : public Node {
// TODO : this is only for Meshes at the moment
// TODO : handle attributes as well
+
+ struct AttributeData {
+ AttributeStandard std;
+ ustring name;
+ array<char> data;
+ };
+
struct DataCache {
bool dirty = false;
array<float3> vertices{};
array<int3> triangles{};
+
+ vector<AttributeData> attributes{};
};
DataCache &get_frame_data(int index);
@@ -72,6 +82,8 @@ class AlembicObject : public Node {
bool data_loaded = false;
vector<DataCache> frame_data;
+
+ void read_attribute(const ICompoundProperty &arb_geom_params, const ISampleSelector &iss, const ustring &attr_name, DataCache &data_cache);
};
class AlembicProcedural : public Procedural {
More information about the Bf-blender-cvs
mailing list