[Bf-blender-cvs] [0182d72aa4a] cycles_procedural_api: fix reading normals

Kévin Dietrich noreply at git.blender.org
Sun Dec 6 06:26:27 CET 2020


Commit: 0182d72aa4a86ab35e1710f8514d3a7d24463fce
Author: Kévin Dietrich
Date:   Thu Dec 3 12:13:59 2020 +0100
Branches: cycles_procedural_api
https://developer.blender.org/rB0182d72aa4a86ab35e1710f8514d3a7d24463fce

fix reading normals

===================================================================

M	intern/cycles/render/alembic.cpp

===================================================================

diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp
index a7eb1b39048..9492792e1a1 100644
--- a/intern/cycles/render/alembic.cpp
+++ b/intern/cycles/render/alembic.cpp
@@ -264,85 +264,86 @@ static void read_default_uvs(const IV2fGeomParam &uvs, CachedData &cached_data)
   }
 }
 
-static void read_default_normals(const IN3fGeomParam &normals, CachedData &cached_data)
+static void add_normals(const Int32ArraySamplePtr face_indices,
+                                 const IN3fGeomParam &normals,
+                                 double time,
+                                 CachedData &cached_data)
 {
-  CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()));
 
-  for (index_t i = 0; i < static_cast<index_t>(normals.getNumSamples()); ++i) {
-    const ISampleSelector iss = ISampleSelector(static_cast<index_t>(i));
-    const IN3fGeomParam::Sample sample = normals.getExpandedValue(iss);
+  switch (normals.getScope()) {
+    case kFacevaryingScope: {
+      const ISampleSelector iss = ISampleSelector(time);
+      const IN3fGeomParam::Sample sample = normals.getExpandedValue(iss);
 
-    if (!sample.valid()) {
-      return;
-    }
+      if (!sample.valid()) {
+        return;
+      }
 
-    const double time = normals.getTimeSampling()->getSampleTime(static_cast<index_t>(i));
+      CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()));
+      attr.std = ATTR_STD_VERTEX_NORMAL;
 
-    switch (normals.getScope()) {
-      case kFacevaryingScope: {
-        attr.std = ATTR_STD_VERTEX_NORMAL;
+      const array<float3> *vertices = cached_data.vertices.data_for_time(time);
 
-        const array<float3> *vertices = cached_data.vertices.data_for_time(time);
-        const array<int3> *triangles = cached_data.triangles.data_for_time(time);
+      if (!vertices) {
+        return;
+      }
 
-        if (!vertices || !triangles) {
-          continue;
-        }
+      array<char> data;
+      data.resize(vertices->size() * sizeof(float3));
 
-        array<char> data;
-        data.resize(vertices->size() * sizeof(float3));
+      float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
 
-        float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
+      const int *face_indices_array = face_indices->get();
+      const N3fArraySamplePtr values = sample.getVals();
 
-        for (size_t i = 0; i < vertices->size(); ++i) {
-          data_float3[i] = make_float3(0.0f);
-        }
+      for (size_t i = 0; i < face_indices->size(); ++i) {
+        int point_index = face_indices_array[i];
+        /* polygon winding order in Alembic follows the RenderMan convention, which is the
+         * reverse of Cycle, so the normal has to flipped
+         * this code also assumes that the vertices of each polygon corresponding to the same
+         * point have the same normal (that we do not have split normals, which is not
+         * supported in Cycles anyway) */
+        data_float3[point_index] = -make_float3_from_yup(values->get()[i]);
+      }
 
-        const Imath::V3f *values = sample.getVals()->get();
+      attr.data.add_data(data, time);
+      break;
+    }
+    case kVaryingScope:
+    case kVertexScope: {
+      const ISampleSelector iss = ISampleSelector(time);
+      const IN3fGeomParam::Sample sample = normals.getExpandedValue(iss);
 
-        for (const int3 &tri : *triangles) {
-          const Imath::V3f &v0 = values[tri.x];
-          const Imath::V3f &v1 = values[tri.y];
-          const Imath::V3f &v2 = values[tri.z];
+      if (!sample.valid()) {
+        return;
+      }
 
-          data_float3[tri.x] += make_float3_from_yup(v0);
-          data_float3[tri.y] += make_float3_from_yup(v1);
-          data_float3[tri.z] += make_float3_from_yup(v2);
-        }
+      CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()));
+      attr.std = ATTR_STD_VERTEX_NORMAL;
 
-        attr.data.add_data(data, time);
+      const array<float3> *vertices = cached_data.vertices.data_for_time(time);
 
-        break;
+      if (!vertices) {
+        return;
       }
-      case kVaryingScope:
-      case kVertexScope: {
-        attr.std = ATTR_STD_VERTEX_NORMAL;
 
-        const array<float3> *vertices = cached_data.vertices.data_for_time(time);
+      array<char> data;
+      data.resize(vertices->size() * sizeof(float3));
 
-        if (!vertices) {
-          continue;
-        }
-
-        array<char> data;
-        data.resize(vertices->size() * sizeof(float3));
+      float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
 
-        float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
+      const Imath::V3f *values = sample.getVals()->get();
 
-        const Imath::V3f *values = sample.getVals()->get();
-
-        for (size_t i = 0; i < vertices->size(); ++i) {
-          data_float3[i] = make_float3_from_yup(values[i]);
-        }
+      for (size_t i = 0; i < vertices->size(); ++i) {
+        data_float3[i] = make_float3_from_yup(values[i]);
+      }
 
-        attr.data.add_data(data, time);
+      attr.data.add_data(data, time);
 
-        break;
-      }
-      default: {
-        // not supported
-        break;
-      }
+      break;
+    }
+    default: {
+      break;
     }
   }
 }
@@ -523,6 +524,8 @@ void AlembicObject::load_all_data(IPolyMeshSchema &schema, Progress &progress)
   array<int> polygon_to_shader;
   read_face_sets(schema, polygon_to_shader);
 
+  const IN3fGeomParam &normals = schema.getNormalsParam();
+
   /* read topology */
   for (size_t i = 0; i < schema.getNumSamples(); ++i) {
     if (progress.get_cancel()) {
@@ -539,6 +542,10 @@ void AlembicObject::load_all_data(IPolyMeshSchema &schema, Progress &progress)
     add_triangles(
         sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
 
+    if (normals.valid()) {
+      add_normals(sample.getFaceIndices(), normals, time, cached_data);
+    }
+
     foreach (const AttributeRequest &attr, requested_attributes.requests) {
       read_attribute(schema.getArbGeomParams(), iss, attr.name);
     }
@@ -558,16 +565,6 @@ void AlembicObject::load_all_data(IPolyMeshSchema &schema, Progress &progress)
     return;
   }
 
-  //  const IN3fGeomParam &normals = schema.getNormalsParam();
-
-  //  if (normals.valid()) {
-  //    read_default_normals(normals, cached_data);
-  //  }
-
-  if (progress.get_cancel()) {
-    return;
-  }
-
   setup_transform_cache();
 
   data_loaded = true;
@@ -1043,10 +1040,6 @@ void AlembicProcedural::read_mesh(Scene *scene,
     memcpy(attr->data(), attr_data->data(), attr_data->size());
   }
 
-  // TODO(@kevindietrich): proper normals support
-  mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
-  mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
-
   /* we don't yet support arbitrary attributes, for now add vertex
    * coordinates as generated coordinates if requested */
   if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) {



More information about the Bf-blender-cvs mailing list