ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / render / mesh_subdivision.cpp
index 95cc6f1..46c8240 100644 (file)
@@ -31,87 +31,92 @@ CCL_NAMESPACE_BEGIN
 
 CCL_NAMESPACE_END
 
-#include <opensubdiv/far/topologyRefinerFactory.h>
-#include <opensubdiv/far/primvarRefiner.h>
-#include <opensubdiv/far/patchTableFactory.h>
-#include <opensubdiv/far/patchMap.h>
+#  include <opensubdiv/far/topologyRefinerFactory.h>
+#  include <opensubdiv/far/primvarRefiner.h>
+#  include <opensubdiv/far/patchTableFactory.h>
+#  include <opensubdiv/far/patchMap.h>
 
 /* specializations of TopologyRefinerFactory for ccl::Mesh */
 
 namespace OpenSubdiv {
 namespace OPENSUBDIV_VERSION {
 namespace Far {
-       template<>
-       bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner& refiner, ccl::Mesh const& mesh)
-       {
-               setNumBaseVertices(refiner, mesh.verts.size());
-               setNumBaseFaces(refiner, mesh.subd_faces.size());
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
+                                                                ccl::Mesh const &mesh)
+{
+  setNumBaseVertices(refiner, mesh.verts.size());
+  setNumBaseFaces(refiner, mesh.subd_faces.size());
 
-               const ccl::Mesh::SubdFace* face = mesh.subd_faces.data();
+  const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
 
-               for(int i = 0; i < mesh.subd_faces.size(); i++, face++) {
-                       setNumBaseFaceVertices(refiner, i, face->num_corners);
-               }
+  for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
+    setNumBaseFaceVertices(refiner, i, face->num_corners);
+  }
 
-               return true;
-       }
+  return true;
+}
 
-       template<>
-       bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner& refiner, ccl::Mesh const& mesh)
-       {
-               const ccl::Mesh::SubdFace* face = mesh.subd_faces.data();
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
+                                                                ccl::Mesh const &mesh)
+{
+  const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
 
-               for(int i = 0; i < mesh.subd_faces.size(); i++, face++) {
-                       IndexArray face_verts = getBaseFaceVertices(refiner, i);
+  for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
+    IndexArray face_verts = getBaseFaceVertices(refiner, i);
 
-                       int* corner = &mesh.subd_face_corners[face->start_corner];
+    int *corner = &mesh.subd_face_corners[face->start_corner];
 
-                       for(int j = 0; j < face->num_corners; j++, corner++) {
-                               face_verts[j] = *corner;
-                       }
-               }
+    for (int j = 0; j < face->num_corners; j++, corner++) {
+      face_verts[j] = *corner;
+    }
+  }
 
-               return true;
-       }
+  return true;
+}
 
-       template<>
-       bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner& refiner, ccl::Mesh const& mesh)
-       {
-               const ccl::Mesh::SubdEdgeCrease* crease = mesh.subd_creases.data();
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
+                                                            ccl::Mesh const &mesh)
+{
+  const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data();
 
-               for(int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
-                       Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
+  for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
+    Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
 
-                       if(edge != INDEX_INVALID) {
-                               setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
-                       }
-               }
+    if (edge != INDEX_INVALID) {
+      setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
+    }
+  }
 
-               for(int i = 0; i < mesh.verts.size(); i++) {
-                       ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
+  for (int i = 0; i < mesh.verts.size(); i++) {
+    ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
 
-                       if(vert_edges.size() == 2) {
-                               float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
-                               sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
+    if (vert_edges.size() == 2) {
+      float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
+      sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
 
-                               setBaseVertexSharpness(refiner, i, sharpness);
-                       }
-               }
+      setBaseVertexSharpness(refiner, i, sharpness);
+    }
+  }
 
-               return true;
-       }
+  return true;
+}
 
-       template<>
-       bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner& /*refiner*/, ccl::Mesh const& /*mesh*/)
-       {
-               return true;
-       }
+template<>
+bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & /*refiner*/,
+                                                                  ccl::Mesh const & /*mesh*/)
+{
+  return true;
+}
 
-       template<>
-       void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
-               char const * /*msg*/, ccl::Mesh const& /*mesh*/)
-       {
-       }
+template<>
+void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
+                                                              char const * /*msg*/,
+                                                              ccl::Mesh const & /*mesh*/)
+{
+}
 } /* namespace Far */
 } /* namespace OPENSUBDIV_VERSION */
 } /* namespace OpenSubdiv */
@@ -122,226 +127,242 @@ using namespace OpenSubdiv;
 
 /* struct that implements OpenSubdiv's vertex interface */
 
-template<typename T>
-struct OsdValue {
-       T value;
+template<typename T> struct OsdValue {
+  T value;
 
-       OsdValue() {}
+  OsdValue()
+  {
+  }
 
-       void Clear(void* = 0) {
-               memset(&value, 0, sizeof(T));
-       }
+  void Clear(void * = 0)
+  {
+    memset(&value, 0, sizeof(T));
+  }
 
-       void AddWithWeight(OsdValue<T> const& src, float weight) {
-               value += src.value * weight;
-       }
+  void AddWithWeight(OsdValue<T> const &src, float weight)
+  {
+    value += src.value * weight;
+  }
 };
 
-template<>
-void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const& src, float weight)
+template<> void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const &src, float weight)
 {
-       for(int i = 0; i < 4; i++) {
-               value[i] += (uchar)(src.value[i] * weight);
-       }
+  for (int i = 0; i < 4; i++) {
+    value[i] += (uchar)(src.value[i] * weight);
+  }
 }
 
 /* class for holding OpenSubdiv data used during tessellation */
 
 class OsdData {
-       Mesh* mesh;
-       vector<OsdValue<float3> > verts;
-       Far::TopologyRefiner* refiner;
-       Far::PatchTable* patch_table;
-       Far::PatchMap* patch_map;
-
-public:
-       OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL) {}
-
-       ~OsdData()
-       {
-               delete refiner;
-               delete patch_table;
-               delete patch_map;
-       }
-
-       void build_from_mesh(Mesh* mesh_)
-       {
-               mesh = mesh_;
-
-               /* type and options */
-               Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
-
-               Sdc::Options options;
-               options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
-
-               /* create refiner */
-               refiner = Far::TopologyRefinerFactory<Mesh>::Create(*mesh,
-                               Far::TopologyRefinerFactory<Mesh>::Options(type, options));
-
-               /* adaptive refinement */
-               int max_isolation = calculate_max_isolation();
-               refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
-
-               /* create patch table */
-               Far::PatchTableFactory::Options patch_options;
-               patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
-
-               patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
-
-               /* interpolate verts */
-               int num_refiner_verts = refiner->GetNumVerticesTotal();
-               int num_local_points = patch_table->GetNumLocalPoints();
-
-               verts.resize(num_refiner_verts + num_local_points);
-               for(int i = 0; i < mesh->verts.size(); i++) {
-                       verts[i].value = mesh->verts[i];
-               }
-
-               OsdValue<float3>* src = verts.data();
-               for(int i = 0; i < refiner->GetMaxLevel(); i++) {
-                       OsdValue<float3>* dest = src + refiner->GetLevel(i).GetNumVertices();
-                       Far::PrimvarRefiner(*refiner).Interpolate(i+1, src, dest);
-                       src = dest;
-               }
-
-               if(num_local_points) {
-                       patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
-               }
-
-               /* create patch map */
-               patch_map = new Far::PatchMap(*patch_table);
-       }
-
-       void subdivide_attribute(Attribute& attr)
-       {
-               Far::PrimvarRefiner primvar_refiner(*refiner);
-
-               if(attr.element == ATTR_ELEMENT_VERTEX) {
-                       int num_refiner_verts = refiner->GetNumVerticesTotal();
-                       int num_local_points = patch_table->GetNumLocalPoints();
-
-                       attr.resize(num_refiner_verts + num_local_points);
-                       attr.flags |= ATTR_FINAL_SIZE;
-
-                       char* src = attr.buffer.data();
-
-                       for(int i = 0; i < refiner->GetMaxLevel(); i++) {
-                               char* dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
-
-                               if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
-                                       primvar_refiner.Interpolate(i+1, (OsdValue<float>*)src, (OsdValue<float>*&)dest);
-                               }
-                               else if(attr.same_storage(attr.type, TypeFloat2)) {
-                                       primvar_refiner.Interpolate(i+1, (OsdValue<float2>*)src, (OsdValue<float2>*&)dest);
-                               }
-                               else {
-                                       primvar_refiner.Interpolate(i+1, (OsdValue<float4>*)src, (OsdValue<float4>*&)dest);
-                               }
-
-                               src = dest;
-                       }
-
-                       if(num_local_points) {
-                               if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
-                                       patch_table->ComputeLocalPointValues((OsdValue<float>*)&attr.buffer[0],
-                                                                                    (OsdValue<float>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
-                               }
-                               else if(attr.same_storage(attr.type, TypeFloat2)) {
-                                       patch_table->ComputeLocalPointValues((OsdValue<float2>*)&attr.buffer[0],
-                                                                                                                (OsdValue<float2>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
-                               }
-                               else {
-                                       patch_table->ComputeLocalPointValues((OsdValue<float4>*)&attr.buffer[0],
-                                                                                    (OsdValue<float4>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
-                               }
-                       }
-               }
-               else if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
-                       // TODO(mai): fvar interpolation
-               }
-       }
-
-       int calculate_max_isolation()
-       {
-               /* loop over all edges to find longest in screen space */
-               const Far::TopologyLevel& level = refiner->GetLevel(0);
-               Transform objecttoworld = mesh->subd_params->objecttoworld;
-               Camera* cam = mesh->subd_params->camera;
-
-               float longest_edge = 0.0f;
-
-               for(size_t i = 0; i < level.GetNumEdges(); i++) {
-                       Far::ConstIndexArray verts = level.GetEdgeVertices(i);
-
-                       float3 a = mesh->verts[verts[0]];
-                       float3 b = mesh->verts[verts[1]];
-
-                       float edge_len;
-
-                       if(cam) {
-                               a = transform_point(&objecttoworld, a);
-                               b = transform_point(&objecttoworld, b);
-
-                               edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
-                       }
-                       else {
-                               edge_len = len(a - b);
-                       }
-
-                       longest_edge = max(longest_edge, edge_len);
-               }
-
-               /* calculate isolation level */
-               int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
-
-               return min(isolation, 10);
-       }
-
-       friend struct OsdPatch;
-       friend class Mesh;
+  Mesh *mesh;
+  vector<OsdValue<float3>> verts;
+  Far::TopologyRefiner *refiner;
+  Far::PatchTable *patch_table;
+  Far::PatchMap *patch_map;
+
+ public:
+  OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL)
+  {
+  }
+
+  ~OsdData()
+  {
+    delete refiner;
+    delete patch_table;
+    delete patch_map;
+  }
+
+  void build_from_mesh(Mesh *mesh_)
+  {
+    mesh = mesh_;
+
+    /* type and options */
+    Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
+
+    Sdc::Options options;
+    options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
+
+    /* create refiner */
+    refiner = Far::TopologyRefinerFactory<Mesh>::Create(
+        *mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options));
+
+    /* adaptive refinement */
+    int max_isolation = calculate_max_isolation();
+    refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
+
+    /* create patch table */
+    Far::PatchTableFactory::Options patch_options;
+    patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
+
+    patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
+
+    /* interpolate verts */
+    int num_refiner_verts = refiner->GetNumVerticesTotal();
+    int num_local_points = patch_table->GetNumLocalPoints();
+
+    verts.resize(num_refiner_verts + num_local_points);
+    for (int i = 0; i < mesh->verts.size(); i++) {
+      verts[i].value = mesh->verts[i];
+    }
+
+    OsdValue<float3> *src = verts.data();
+    for (int i = 0; i < refiner->GetMaxLevel(); i++) {
+      OsdValue<float3> *dest = src + refiner->GetLevel(i).GetNumVertices();
+      Far::PrimvarRefiner(*refiner).Interpolate(i + 1, src, dest);
+      src = dest;
+    }
+
+    if (num_local_points) {
+      patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
+    }
+
+    /* create patch map */
+    patch_map = new Far::PatchMap(*patch_table);
+  }
+
+  void subdivide_attribute(Attribute &attr)
+  {
+    Far::PrimvarRefiner primvar_refiner(*refiner);
+
+    if (attr.element == ATTR_ELEMENT_VERTEX) {
+      int num_refiner_verts = refiner->GetNumVerticesTotal();
+      int num_local_points = patch_table->GetNumLocalPoints();
+
+      attr.resize(num_refiner_verts + num_local_points);
+      attr.flags |= ATTR_FINAL_SIZE;
+
+      char *src = attr.buffer.data();
+
+      for (int i = 0; i < refiner->GetMaxLevel(); i++) {
+        char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
+
+        if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+          primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest);
+        }
+        else if (attr.same_storage(attr.type, TypeFloat2)) {
+          primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest);
+        }
+        else {
+          primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest);
+        }
+
+        src = dest;
+      }
+
+      if (num_local_points) {
+        if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
+          patch_table->ComputeLocalPointValues(
+              (OsdValue<float> *)&attr.buffer[0],
+              (OsdValue<float> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+        }
+        else if (attr.same_storage(attr.type, TypeFloat2)) {
+          patch_table->ComputeLocalPointValues(
+              (OsdValue<float2> *)&attr.buffer[0],
+              (OsdValue<float2> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+        }
+        else {
+          patch_table->ComputeLocalPointValues(
+              (OsdValue<float4> *)&attr.buffer[0],
+              (OsdValue<float4> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
+        }
+      }
+    }
+    else if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+      // TODO(mai): fvar interpolation
+    }
+  }
+
+  int calculate_max_isolation()
+  {
+    /* loop over all edges to find longest in screen space */
+    const Far::TopologyLevel &level = refiner->GetLevel(0);
+    Transform objecttoworld = mesh->subd_params->objecttoworld;
+    Camera *cam = mesh->subd_params->camera;
+
+    float longest_edge = 0.0f;
+
+    for (size_t i = 0; i < level.GetNumEdges(); i++) {
+      Far::ConstIndexArray verts = level.GetEdgeVertices(i);
+
+      float3 a = mesh->verts[verts[0]];
+      float3 b = mesh->verts[verts[1]];
+
+      float edge_len;
+
+      if (cam) {
+        a = transform_point(&objecttoworld, a);
+        b = transform_point(&objecttoworld, b);
+
+        edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
+      }
+      else {
+        edge_len = len(a - b);
+      }
+
+      longest_edge = max(longest_edge, edge_len);
+    }
+
+    /* calculate isolation level */
+    int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
+
+    return min(isolation, 10);
+  }
+
+  friend struct OsdPatch;
+  friend class Mesh;
 };
 
 /* ccl::Patch implementation that uses OpenSubdiv for eval */
 
 struct OsdPatch : Patch {
-       OsdData* osd_data;
-
-       OsdPatch(OsdData* data) : osd_data(data) {}
-
-       void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
-       {
-               const Far::PatchTable::PatchHandle* handle = osd_data->patch_map->FindPatch(patch_index, u, v);
-               assert(handle);
-
-               float p_weights[20], du_weights[20], dv_weights[20];
-               osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
-
-               Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
-
-               float3 du, dv;
-               if(P) *P = make_float3(0.0f, 0.0f, 0.0f);
-               du = make_float3(0.0f, 0.0f, 0.0f);
-               dv = make_float3(0.0f, 0.0f, 0.0f);
-
-               for(int i = 0; i < cv.size(); i++) {
-                       float3 p = osd_data->verts[cv[i]].value;
-
-                       if(P) *P += p * p_weights[i];
-                       du += p * du_weights[i];
-                       dv += p * dv_weights[i];
-               }
-
-               if(dPdu) *dPdu = du;
-               if(dPdv) *dPdv = dv;
-               if(N) {
-                       *N = cross(du, dv);
-
-                       float t = len(*N);
-                       *N = (t != 0.0f) ? *N/t : make_float3(0.0f, 0.0f, 1.0f);
-               }
-       }
-
-       BoundBox bound() { return BoundBox::empty; }
+  OsdData *osd_data;
+
+  OsdPatch(OsdData *data) : osd_data(data)
+  {
+  }
+
+  void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
+  {
+    const Far::PatchTable::PatchHandle *handle = osd_data->patch_map->FindPatch(patch_index, u, v);
+    assert(handle);
+
+    float p_weights[20], du_weights[20], dv_weights[20];
+    osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
+
+    Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
+
+    float3 du, dv;
+    if (P)
+      *P = make_float3(0.0f, 0.0f, 0.0f);
+    du = make_float3(0.0f, 0.0f, 0.0f);
+    dv = make_float3(0.0f, 0.0f, 0.0f);
+
+    for (int i = 0; i < cv.size(); i++) {
+      float3 p = osd_data->verts[cv[i]].value;
+
+      if (P)
+        *P += p * p_weights[i];
+      du += p * du_weights[i];
+      dv += p * dv_weights[i];
+    }
+
+    if (dPdu)
+      *dPdu = du;
+    if (dPdv)
+      *dPdv = dv;
+    if (N) {
+      *N = cross(du, dv);
+
+      float t = len(*N);
+      *N = (t != 0.0f) ? *N / t : make_float3(0.0f, 0.0f, 1.0f);
+    }
+  }
+
+  BoundBox bound()
+  {
+    return BoundBox::empty;
+  }
 };
 
 #endif
@@ -349,273 +370,280 @@ struct OsdPatch : Patch {
 void Mesh::tessellate(DiagSplit *split)
 {
 #ifdef WITH_OPENSUBDIV
-       OsdData osd_data;
-       bool need_packed_patch_table = false;
-
-       if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
-               if(subd_faces.size()) {
-                       osd_data.build_from_mesh(this);
-               }
-       }
-       else
+  OsdData osd_data;
+  bool need_packed_patch_table = false;
+
+  if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+    if (subd_faces.size()) {
+      osd_data.build_from_mesh(this);
+    }
+  }
+  else
 #endif
-       {
-               /* force linear subdivision if OpenSubdiv is unavailable to avoid
-                * falling into catmull-clark code paths by accident
-                */
-               subdivision_type = SUBDIVISION_LINEAR;
+  {
+    /* force linear subdivision if OpenSubdiv is unavailable to avoid
+     * falling into catmull-clark code paths by accident
+     */
+    subdivision_type = SUBDIVISION_LINEAR;
 
-               /* force disable attribute subdivision for same reason as above */
-               foreach(Attribute& attr, subd_attributes.attributes) {
-                       attr.flags &= ~ATTR_SUBDIVIDED;
-               }
-       }
+    /* force disable attribute subdivision for same reason as above */
+    foreach (Attribute &attr, subd_attributes.attributes) {
+      attr.flags &= ~ATTR_SUBDIVIDED;
+    }
+  }
 
-       int num_faces = subd_faces.size();
+  int num_faces = subd_faces.size();
 
-       Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
-       float3* vN = attr_vN->data_float3();
+  Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
+  float3 *vN = attr_vN->data_float3();
 
-       for(int f = 0; f < num_faces; f++) {
-               SubdFace& face = subd_faces[f];
+  for (int f = 0; f < num_faces; f++) {
+    SubdFace &face = subd_faces[f];
 
-               if(face.is_quad()) {
-                       /* quad */
-                       QuadDice::SubPatch subpatch;
+    if (face.is_quad()) {
+      /* quad */
+      QuadDice::SubPatch subpatch;
 
-                       LinearQuadPatch quad_patch;
+      LinearQuadPatch quad_patch;
 #ifdef WITH_OPENSUBDIV
-                       OsdPatch osd_patch(&osd_data);
+      OsdPatch osd_patch(&osd_data);
 
-                       if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
-                               osd_patch.patch_index = face.ptex_offset;
+      if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+        osd_patch.patch_index = face.ptex_offset;
 
-                               subpatch.patch = &osd_patch;
-                       }
-                       else
+        subpatch.patch = &osd_patch;
+      }
+      else
 #endif
-                       {
-                               float3 *hull = quad_patch.hull;
-                               float3 *normals = quad_patch.normals;
-
-                               quad_patch.patch_index = face.ptex_offset;
-
-                               for(int i = 0; i < 4; i++) {
-                                       hull[i] = verts[subd_face_corners[face.start_corner+i]];
-                               }
-
-                               if(face.smooth) {
-                                       for(int i = 0; i < 4; i++) {
-                                               normals[i] = vN[subd_face_corners[face.start_corner+i]];
-                                       }
-                               }
-                               else {
-                                       float3 N = face.normal(this);
-                                       for(int i = 0; i < 4; i++) {
-                                               normals[i] = N;
-                                       }
-                               }
-
-                               swap(hull[2], hull[3]);
-                               swap(normals[2], normals[3]);
-
-                               subpatch.patch = &quad_patch;
-                       }
-
-                       subpatch.patch->shader = face.shader;
-
-                       /* Quad faces need to be split at least once to line up with split ngons, we do this
-                        * here in this manner because if we do it later edge factors may end up slightly off.
-                        */
-                       subpatch.P00 = make_float2(0.0f, 0.0f);
-                       subpatch.P10 = make_float2(0.5f, 0.0f);
-                       subpatch.P01 = make_float2(0.0f, 0.5f);
-                       subpatch.P11 = make_float2(0.5f, 0.5f);
-                       split->split_quad(subpatch.patch, &subpatch);
-
-                       subpatch.P00 = make_float2(0.5f, 0.0f);
-                       subpatch.P10 = make_float2(1.0f, 0.0f);
-                       subpatch.P01 = make_float2(0.5f, 0.5f);
-                       subpatch.P11 = make_float2(1.0f, 0.5f);
-                       split->split_quad(subpatch.patch, &subpatch);
-
-                       subpatch.P00 = make_float2(0.0f, 0.5f);
-                       subpatch.P10 = make_float2(0.5f, 0.5f);
-                       subpatch.P01 = make_float2(0.0f, 1.0f);
-                       subpatch.P11 = make_float2(0.5f, 1.0f);
-                       split->split_quad(subpatch.patch, &subpatch);
-
-                       subpatch.P00 = make_float2(0.5f, 0.5f);
-                       subpatch.P10 = make_float2(1.0f, 0.5f);
-                       subpatch.P01 = make_float2(0.5f, 1.0f);
-                       subpatch.P11 = make_float2(1.0f, 1.0f);
-                       split->split_quad(subpatch.patch, &subpatch);
-               }
-               else {
-                       /* ngon */
+      {
+        float3 *hull = quad_patch.hull;
+        float3 *normals = quad_patch.normals;
+
+        quad_patch.patch_index = face.ptex_offset;
+
+        for (int i = 0; i < 4; i++) {
+          hull[i] = verts[subd_face_corners[face.start_corner + i]];
+        }
+
+        if (face.smooth) {
+          for (int i = 0; i < 4; i++) {
+            normals[i] = vN[subd_face_corners[face.start_corner + i]];
+          }
+        }
+        else {
+          float3 N = face.normal(this);
+          for (int i = 0; i < 4; i++) {
+            normals[i] = N;
+          }
+        }
+
+        swap(hull[2], hull[3]);
+        swap(normals[2], normals[3]);
+
+        subpatch.patch = &quad_patch;
+      }
+
+      subpatch.patch->shader = face.shader;
+
+      /* Quad faces need to be split at least once to line up with split ngons, we do this
+       * here in this manner because if we do it later edge factors may end up slightly off.
+       */
+      subpatch.P00 = make_float2(0.0f, 0.0f);
+      subpatch.P10 = make_float2(0.5f, 0.0f);
+      subpatch.P01 = make_float2(0.0f, 0.5f);
+      subpatch.P11 = make_float2(0.5f, 0.5f);
+      split->split_quad(subpatch.patch, &subpatch);
+
+      subpatch.P00 = make_float2(0.5f, 0.0f);
+      subpatch.P10 = make_float2(1.0f, 0.0f);
+      subpatch.P01 = make_float2(0.5f, 0.5f);
+      subpatch.P11 = make_float2(1.0f, 0.5f);
+      split->split_quad(subpatch.patch, &subpatch);
+
+      subpatch.P00 = make_float2(0.0f, 0.5f);
+      subpatch.P10 = make_float2(0.5f, 0.5f);
+      subpatch.P01 = make_float2(0.0f, 1.0f);
+      subpatch.P11 = make_float2(0.5f, 1.0f);
+      split->split_quad(subpatch.patch, &subpatch);
+
+      subpatch.P00 = make_float2(0.5f, 0.5f);
+      subpatch.P10 = make_float2(1.0f, 0.5f);
+      subpatch.P01 = make_float2(0.5f, 1.0f);
+      subpatch.P11 = make_float2(1.0f, 1.0f);
+      split->split_quad(subpatch.patch, &subpatch);
+    }
+    else {
+      /* ngon */
 #ifdef WITH_OPENSUBDIV
-                       if(subdivision_type == SUBDIVISION_CATMULL_CLARK) {
-                               OsdPatch patch(&osd_data);
+      if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
+        OsdPatch patch(&osd_data);
 
-                               patch.shader = face.shader;
+        patch.shader = face.shader;
 
-                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                       patch.patch_index = face.ptex_offset + corner;
+        for (int corner = 0; corner < face.num_corners; corner++) {
+          patch.patch_index = face.ptex_offset + corner;
 
-                                       split->split_quad(&patch);
-                               }
-                       }
-                       else
+          split->split_quad(&patch);
+        }
+      }
+      else
 #endif
-                       {
-                               float3 center_vert = make_float3(0.0f, 0.0f, 0.0f);
-                               float3 center_normal = make_float3(0.0f, 0.0f, 0.0f);
-
-                               float inv_num_corners = 1.0f/float(face.num_corners);
-                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                       center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
-                                       center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
-                               }
-
-                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                       LinearQuadPatch patch;
-                                       float3 *hull = patch.hull;
-                                       float3 *normals = patch.normals;
-
-                                       patch.patch_index = face.ptex_offset + corner;
-
-                                       patch.shader = face.shader;
-
-                                       hull[0] = verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
-                                       hull[1] = verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
-                                       hull[2] = verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
-                                       hull[3] = center_vert;
-
-                                       hull[1] = (hull[1] + hull[0]) * 0.5;
-                                       hull[2] = (hull[2] + hull[0]) * 0.5;
-
-                                       if(face.smooth) {
-                                               normals[0] = vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
-                                               normals[1] = vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
-                                               normals[2] = vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
-                                               normals[3] = center_normal;
-
-                                               normals[1] = (normals[1] + normals[0]) * 0.5;
-                                               normals[2] = (normals[2] + normals[0]) * 0.5;
-                                       }
-                                       else {
-                                               float3 N = face.normal(this);
-                                               for(int i = 0; i < 4; i++) {
-                                                       normals[i] = N;
-                                               }
-                                       }
-
-                                       split->split_quad(&patch);
-                               }
-                       }
-               }
-       }
-
-       /* interpolate center points for attributes */
-       foreach(Attribute& attr, subd_attributes.attributes) {
+      {
+        float3 center_vert = make_float3(0.0f, 0.0f, 0.0f);
+        float3 center_normal = make_float3(0.0f, 0.0f, 0.0f);
+
+        float inv_num_corners = 1.0f / float(face.num_corners);
+        for (int corner = 0; corner < face.num_corners; corner++) {
+          center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
+          center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
+        }
+
+        for (int corner = 0; corner < face.num_corners; corner++) {
+          LinearQuadPatch patch;
+          float3 *hull = patch.hull;
+          float3 *normals = patch.normals;
+
+          patch.patch_index = face.ptex_offset + corner;
+
+          patch.shader = face.shader;
+
+          hull[0] =
+              verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
+          hull[1] =
+              verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
+          hull[2] =
+              verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
+          hull[3] = center_vert;
+
+          hull[1] = (hull[1] + hull[0]) * 0.5;
+          hull[2] = (hull[2] + hull[0]) * 0.5;
+
+          if (face.smooth) {
+            normals[0] =
+                vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
+            normals[1] =
+                vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
+            normals[2] =
+                vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
+            normals[3] = center_normal;
+
+            normals[1] = (normals[1] + normals[0]) * 0.5;
+            normals[2] = (normals[2] + normals[0]) * 0.5;
+          }
+          else {
+            float3 N = face.normal(this);
+            for (int i = 0; i < 4; i++) {
+              normals[i] = N;
+            }
+          }
+
+          split->split_quad(&patch);
+        }
+      }
+    }
+  }
+
+  /* interpolate center points for attributes */
+  foreach (Attribute &attr, subd_attributes.attributes) {
 #ifdef WITH_OPENSUBDIV
-               if(subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
-                       if(attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
-                               /* keep subdivision for corner attributes disabled for now */
-                               attr.flags &= ~ATTR_SUBDIVIDED;
-                       }
-                       else if(subd_faces.size()) {
-                               osd_data.subdivide_attribute(attr);
-
-                               need_packed_patch_table = true;
-                               continue;
-                       }
-               }
+    if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
+      if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
+        /* keep subdivision for corner attributes disabled for now */
+        attr.flags &= ~ATTR_SUBDIVIDED;
+      }
+      else if (subd_faces.size()) {
+        osd_data.subdivide_attribute(attr);
+
+        need_packed_patch_table = true;
+        continue;
+      }
+    }
 #endif
 
-               char* data = attr.data();
-               size_t stride = attr.data_sizeof();
-               int ngons = 0;
-
-               switch(attr.element) {
-                       case ATTR_ELEMENT_VERTEX: {
-                               for(int f = 0; f < num_faces; f++) {
-                                       SubdFace& face = subd_faces[f];
-
-                                       if(!face.is_quad()) {
-                                               char* center = data + (verts.size() - num_subd_verts + ngons) * stride;
-                                               attr.zero_data(center);
-
-                                               float inv_num_corners = 1.0f / float(face.num_corners);
-
-                                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                                       attr.add_with_weight(center,
-                                                                            data + subd_face_corners[face.start_corner + corner] * stride,
-                                                                            inv_num_corners);
-                                               }
-
-                                               ngons++;
-                                       }
-                               }
-                       } break;
-                       case ATTR_ELEMENT_VERTEX_MOTION: {
-                               // TODO(mai): implement
-                       } break;
-                       case ATTR_ELEMENT_CORNER: {
-                               for(int f = 0; f < num_faces; f++) {
-                                       SubdFace& face = subd_faces[f];
-
-                                       if(!face.is_quad()) {
-                                               char* center = data + (subd_face_corners.size() + ngons) * stride;
-                                               attr.zero_data(center);
-
-                                               float inv_num_corners = 1.0f / float(face.num_corners);
-
-                                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                                       attr.add_with_weight(center,
-                                                                            data + (face.start_corner + corner) * stride,
-                                                                            inv_num_corners);
-                                               }
-
-                                               ngons++;
-                                       }
-                               }
-                       } break;
-                       case ATTR_ELEMENT_CORNER_BYTE: {
-                               for(int f = 0; f < num_faces; f++) {
-                                       SubdFace& face = subd_faces[f];
-
-                                       if(!face.is_quad()) {
-                                               uchar* center = (uchar*)data + (subd_face_corners.size() + ngons) * stride;
-
-                                               float inv_num_corners = 1.0f / float(face.num_corners);
-                                               float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-                                               for(int corner = 0; corner < face.num_corners; corner++) {
-                                                       for(int i = 0; i < 4; i++) {
-                                                               val[i] += float(*(data + (face.start_corner + corner) * stride + i)) * inv_num_corners;
-                                                       }
-                                               }
-
-                                               for(int i = 0; i < 4; i++) {
-                                                       center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
-                                               }
-
-                                               ngons++;
-                                       }
-                               }
-                       } break;
-                       default: break;
-               }
-       }
+    char *data = attr.data();
+    size_t stride = attr.data_sizeof();
+    int ngons = 0;
+
+    switch (attr.element) {
+      case ATTR_ELEMENT_VERTEX: {
+        for (int f = 0; f < num_faces; f++) {
+          SubdFace &face = subd_faces[f];
+
+          if (!face.is_quad()) {
+            char *center = data + (verts.size() - num_subd_verts + ngons) * stride;
+            attr.zero_data(center);
+
+            float inv_num_corners = 1.0f / float(face.num_corners);
+
+            for (int corner = 0; corner < face.num_corners; corner++) {
+              attr.add_with_weight(center,
+                                   data + subd_face_corners[face.start_corner + corner] * stride,
+                                   inv_num_corners);
+            }
+
+            ngons++;
+          }
+        }
+      } break;
+      case ATTR_ELEMENT_VERTEX_MOTION: {
+        // TODO(mai): implement
+      } break;
+      case ATTR_ELEMENT_CORNER: {
+        for (int f = 0; f < num_faces; f++) {
+          SubdFace &face = subd_faces[f];
+
+          if (!face.is_quad()) {
+            char *center = data + (subd_face_corners.size() + ngons) * stride;
+            attr.zero_data(center);
+
+            float inv_num_corners = 1.0f / float(face.num_corners);
+
+            for (int corner = 0; corner < face.num_corners; corner++) {
+              attr.add_with_weight(
+                  center, data + (face.start_corner + corner) * stride, inv_num_corners);
+            }
+
+            ngons++;
+          }
+        }
+      } break;
+      case ATTR_ELEMENT_CORNER_BYTE: {
+        for (int f = 0; f < num_faces; f++) {
+          SubdFace &face = subd_faces[f];
+
+          if (!face.is_quad()) {
+            uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride;
+
+            float inv_num_corners = 1.0f / float(face.num_corners);
+            float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+            for (int corner = 0; corner < face.num_corners; corner++) {
+              for (int i = 0; i < 4; i++) {
+                val[i] += float(*(data + (face.start_corner + corner) * stride + i)) *
+                          inv_num_corners;
+              }
+            }
+
+            for (int i = 0; i < 4; i++) {
+              center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
+            }
+
+            ngons++;
+          }
+        }
+      } break;
+      default:
+        break;
+    }
+  }
 
 #ifdef WITH_OPENSUBDIV
-       /* pack patch tables */
-       if(need_packed_patch_table) {
-               delete patch_table;
-               patch_table = new PackedPatchTable;
-               patch_table->pack(osd_data.patch_table);
-       }
+  /* pack patch tables */
+  if (need_packed_patch_table) {
+    delete patch_table;
+    patch_table = new PackedPatchTable;
+    patch_table->pack(osd_data.patch_table);
+  }
 #endif
 }