Fix T63030: Edge crease is not applied for boundary edges
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 28 Mar 2019 10:48:22 +0000 (11:48 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 28 Mar 2019 10:49:08 +0000 (11:49 +0100)
Caused by missing vertex sharpness comparison in the topology
comparator.

intern/opensubdiv/internal/opensubdiv_topology_refiner.cc

index b31146a644ed63092ec5c381777bc5e658a69660..c77ddc49df7a7349f038f5dd60a6695addd6de6a 100644 (file)
@@ -548,6 +548,61 @@ bool checkEdgeTagsMatch(
   }
 }
 
+bool checkvertexSharpnessMatch(
+    const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
+    const OpenSubdiv_Converter* converter) {
+  using OpenSubdiv::Far::ConstIndexArray;
+  using OpenSubdiv::Far::TopologyLevel;
+  using OpenSubdiv::Sdc::Crease;
+  const TopologyLevel& base_level = topology_refiner->GetLevel(0);
+  // Create mapping for quick lookup of edge index from its verticies indices.
+  //
+  // TODO(sergey): Consider caching it in some sort of wrapper around topology
+  // refiner.
+  const int num_edges = base_level.GetNumEdges();
+  EdgeTagMap<int> edge_map;
+  for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
+    int edge_vertices[2];
+    converter->getEdgeVertices(converter, edge_index, edge_vertices);
+    edge_map.insert(edge_vertices[0], edge_vertices[1], edge_index);
+  }
+  const int num_vertices = base_level.GetNumVertices();
+  for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
+    const float current_sharpness = base_level.GetVertexSharpness(vertex_index);
+    if (converter->isInfiniteSharpVertex(converter, vertex_index)) {
+      if (current_sharpness != Crease::SHARPNESS_INFINITE) {
+        return false;
+      }
+    } else {
+      ConstIndexArray vertex_edges = base_level.GetVertexEdges(vertex_index);
+      float sharpness = converter->getVertexSharpness(converter, vertex_index);
+      if (vertex_edges.size() == 2) {
+        const int edge0 = vertex_edges[0], edge1 = vertex_edges[1];
+        // Construct keys for lookup.
+        ConstIndexArray edge0_vertices = base_level.GetEdgeVertices(edge0);
+        ConstIndexArray edge1_vertices = base_level.GetEdgeVertices(edge1);
+        EdgeKey edge0_key(edge0_vertices[0], edge0_vertices[1]);
+        EdgeKey edge1_key(edge1_vertices[0], edge1_vertices[1]);
+        // Lookup edge indices in the converter.
+        const int edge0_converter_index = edge_map[edge0_key];
+        const int edge1_converter_index = edge_map[edge1_key];
+        // Lookup sharpness.
+        const float sharpness0 = converter->getEdgeSharpness(
+            converter, edge0_converter_index);
+        const float sharpness1 = converter->getEdgeSharpness(
+            converter, edge1_converter_index);
+        // TODO(sergey): Find a better mixing between edge and vertex sharpness.
+        sharpness += min(sharpness0, sharpness1);
+        sharpness = min(sharpness, 10.0f);
+      }
+      if (sharpness != current_sharpness) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 bool checkSingleUVLayerMatch(
     const OpenSubdiv::Far::TopologyLevel& base_level,
     const OpenSubdiv_Converter* converter,
@@ -578,7 +633,7 @@ bool checkUVLayersMatch(
   using OpenSubdiv::Far::TopologyLevel;
   const int num_layers = converter->getNumUVLayers(converter);
   const TopologyLevel& base_level = topology_refiner->GetLevel(0);
-  // Number of UF layers should match.
+  // Number of UV layers should match.
   if (base_level.GetNumFVarChannels() != num_layers) {
     return false;
   }
@@ -594,6 +649,7 @@ bool checkTopologyAttributesMatch(
     const OpenSubdiv::Far::TopologyRefiner* topology_refiner,
     const OpenSubdiv_Converter* converter) {
   return checkEdgeTagsMatch(topology_refiner, converter) &&
+         checkvertexSharpnessMatch(topology_refiner, converter) &&
          checkUVLayersMatch(topology_refiner, converter);
 }