[Bf-blender-cvs] [006d4e85a23] cycles_procedural_api: add support for reading face sets
Kévin Dietrich
noreply at git.blender.org
Sun Dec 6 06:26:26 CET 2020
Commit: 006d4e85a2362372d1ab0d4720b536c263f7f91d
Author: Kévin Dietrich
Date: Wed Dec 2 16:54:48 2020 +0100
Branches: cycles_procedural_api
https://developer.blender.org/rB006d4e85a2362372d1ab0d4720b536c263f7f91d
add support for reading face sets
===================================================================
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 031031647e0..86658fc14b2 100644
--- a/intern/cycles/render/alembic.cpp
+++ b/intern/cycles/render/alembic.cpp
@@ -359,7 +359,7 @@ static void add_positions(const P3fArraySamplePtr positions, double time, Cached
cached_data.vertices.add_data(vertices, time);
}
-static void add_triangles(const Int32ArraySamplePtr face_counts, const Int32ArraySamplePtr face_indices, double time, CachedData &cached_data)
+static void add_triangles(const Int32ArraySamplePtr face_counts, const Int32ArraySamplePtr face_indices, double time, CachedData &cached_data, const array<int> &polygon_to_shader)
{
if (!face_counts || !face_indices) {
return;
@@ -374,18 +374,27 @@ static void add_triangles(const Int32ArraySamplePtr face_counts, const Int32Arra
num_triangles += face_counts_array[i] - 2;
}
+ array<int> shader;
array<int3> triangles;
array<int3> triangles_loops;
+ shader.reserve(num_triangles);
triangles.reserve(num_triangles);
triangles_loops.reserve(num_triangles);
int index_offset = 0;
for (size_t i = 0; i < num_faces; i++) {
+ int current_shader = 0;
+
+ if (!polygon_to_shader.empty()) {
+ current_shader = polygon_to_shader[i];
+ }
+
for (int j = 0; j < face_counts_array[i] - 2; j++) {
int v0 = face_indices_array[index_offset];
int v1 = face_indices_array[index_offset + j + 1];
int v2 = face_indices_array[index_offset + j + 2];
+ shader.push_back_reserved(current_shader);
triangles.push_back_reserved(make_int3(v0, v1, v2));
triangles_loops.push_back_reserved(
make_int3(index_offset, index_offset + j + 1, index_offset + j + 2));
@@ -396,6 +405,7 @@ static void add_triangles(const Int32ArraySamplePtr face_counts, const Int32Arra
cached_data.triangles.add_data(triangles, time);
cached_data.triangles_loops.add_data(triangles_loops, time);
+ cached_data.shader.add_data(shader, time);
}
NODE_DEFINE(AlembicObject)
@@ -430,7 +440,65 @@ bool AlembicObject::has_data_loaded() const
return data_loaded;
}
-void AlembicObject::load_all_data(const IPolyMeshSchema &schema, Progress &progress)
+void AlembicObject::read_face_sets(IPolyMeshSchema &schema, array<int> &polygon_to_shader)
+{
+ assert(geometry);
+
+ /* TODO(@kevindietrich) at the moment this is only supported for meshes whose topology remains constant (with possible vertex animation) */
+ if (schema.getTopologyVariance() == kHeterogenousTopology) {
+ return;
+ }
+
+ std::vector<std::string> face_sets;
+ schema.getFaceSetNames(face_sets);
+
+ if (face_sets.empty()) {
+ return;
+ }
+
+ auto face_counts = schema.getFaceCountsProperty().getValue();
+
+ polygon_to_shader.resize(face_counts->size());
+
+ foreach (const std::string &face_set_name, face_sets) {
+ int shader_index = 0;
+
+ foreach (Node *node, geometry->get_used_shaders()) {
+ if (node->name == face_set_name) {
+ break;
+ }
+
+ ++shader_index;
+ }
+
+ if (shader_index >= geometry->get_used_shaders().size()) {
+ continue;
+ }
+
+ const IFaceSet face_set = schema.getFaceSet(face_set_name);
+
+ if (!face_set.valid()) {
+ continue;
+ }
+
+ const IFaceSetSchema face_schem = face_set.getSchema();
+ const IFaceSetSchema::Sample face_sample = face_schem.getValue(ISampleSelector(index_t(0)));
+ const Int32ArraySamplePtr group_faces = face_sample.getFaces();
+ const size_t num_group_faces = group_faces->size();
+
+ for (size_t l = 0; l < num_group_faces; l++) {
+ size_t pos = (*group_faces)[l];
+
+ if (pos >= polygon_to_shader.size()) {
+ continue;
+ }
+
+ polygon_to_shader[pos] = shader_index;
+ }
+ }
+}
+
+void AlembicObject::load_all_data(IPolyMeshSchema &schema, Progress &progress)
{
cached_data.clear();
@@ -440,6 +508,11 @@ void AlembicObject::load_all_data(const IPolyMeshSchema &schema, Progress &progr
cached_data.triangles.set_time_sampling(*schema.getTimeSampling());
cached_data.triangles_loops.set_time_sampling(*schema.getTimeSampling());
+ /* start by reading the face sets (per face shader), as we directly split polygons to triangles */
+ array<int> polygon_to_shader;
+ read_face_sets(schema, polygon_to_shader);
+
+ /* read topology */
for (size_t i = 0; i < schema.getNumSamples(); ++i) {
if (progress.get_cancel()) {
return;
@@ -452,7 +525,7 @@ void AlembicObject::load_all_data(const IPolyMeshSchema &schema, Progress &progr
add_positions(sample.getPositions(), time, cached_data);
- add_triangles(sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data);
+ add_triangles(sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
foreach (const AttributeRequest &attr, requested_attributes.requests) {
read_attribute(schema.getArbGeomParams(), iss, attr.name);
@@ -901,27 +974,28 @@ void AlembicProcedural::read_mesh(Scene *scene,
array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time);
if (triangle_data) {
- // TODO : shader association
array<int> triangles;
array<bool> smooth;
- array<int> shader;
triangles.reserve(triangle_data->size() * 3);
smooth.reserve(triangle_data->size());
- shader.reserve(triangle_data->size());
for (size_t i = 0; i < triangle_data->size(); ++i) {
int3 tri = (*triangle_data)[i];
triangles.push_back_reserved(tri.x);
triangles.push_back_reserved(tri.y);
triangles.push_back_reserved(tri.z);
- shader.push_back_reserved(0);
smooth.push_back_reserved(1);
}
mesh->set_triangles(triangles);
mesh->set_smooth(smooth);
- mesh->set_shader(shader);
+ }
+
+ array<int> *shader = cached_data.shader.data_for_time(frame_time);
+ if (shader) {
+ array<int> new_shader = *shader;
+ mesh->set_shader(new_shader);
}
for (auto &attribute : cached_data.attributes) {
diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h
index 98ad757b62c..f043c7753bd 100644
--- a/intern/cycles/render/alembic.h
+++ b/intern/cycles/render/alembic.h
@@ -100,6 +100,7 @@ struct CachedData {
DataStore<array<float3>> vertices;
DataStore<array<int3>> triangles{};
DataStore<array<int3>> triangles_loops{};
+ DataStore<array<int>> shader{};
/* hair data */
DataStore<array<float3>> curve_keys;
@@ -196,7 +197,7 @@ class AlembicObject : public Node {
void set_object(Object *object);
Object *get_object();
- void load_all_data(const Alembic::AbcGeom::IPolyMeshSchema &schema, Progress &progress);
+ void load_all_data(Alembic::AbcGeom::IPolyMeshSchema &schema, Progress &progress);
void load_all_data(const Alembic::AbcGeom::ICurvesSchema &schema, Progress &progress);
bool has_data_loaded() const;
@@ -228,6 +229,8 @@ class AlembicObject : public Node {
const Alembic::AbcGeom::ISampleSelector &iss,
const ustring &attr_name);
+ void read_face_sets(Alembic::AbcGeom::IPolyMeshSchema &schema, array<int> &polygon_to_shader);
+
void setup_transform_cache();
AttributeRequestSet get_requested_attributes();
More information about the Bf-blender-cvs
mailing list