[Bf-blender-cvs] [f795f57fcb7] opensubdiv_compare: OpenSubdiv: Compare sharpness based on converter

Sergey Sharybin noreply at git.blender.org
Tue May 26 11:13:27 CEST 2020


Commit: f795f57fcb74c66c643953f14ad84b26fb3d3aea
Author: Sergey Sharybin
Date:   Tue May 19 11:43:58 2020 +0200
Branches: opensubdiv_compare
https://developer.blender.org/rBf795f57fcb74c66c643953f14ad84b26fb3d3aea

OpenSubdiv: Compare sharpness based on converter

This change starts the transition of topology refiner comparison
to compare actual values given by the converter, which will not be
affected by the refinement or face winding synchronization steps.

Currently is only implemented for vertex sharpness, but will be
extended further as followup development.

Fixes T71908: Subdiv: Incorrect topology comparison, leading to poor performance

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

M	intern/opensubdiv/internal/topology/topology_refiner_capi.cc
M	intern/opensubdiv/internal/topology/topology_refiner_factory.cc
M	intern/opensubdiv/internal/topology/topology_refiner_impl.h

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

diff --git a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
index 58c0ffbb7cf..8c3f8f1f896 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
@@ -22,6 +22,7 @@
 #include "internal/base/edge_map.h"
 #include "internal/base/type.h"
 #include "internal/base/type_convert.h"
+#include "internal/topology/mesh_topology.h"
 #include "internal/topology/topology_refiner_impl.h"
 #include "opensubdiv_converter_capi.h"
 
@@ -553,55 +554,32 @@ bool checkEdgeTagsMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
   }
 }
 
-bool checkvertexSharpnessMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                               const OpenSubdiv_Converter *converter)
+float getEffectiveVertexSharpness(const OpenSubdiv_Converter *converter, const int vertex_index)
 {
-  using OpenSubdiv::Far::ConstIndexArray;
-  using OpenSubdiv::Far::TopologyLevel;
-  using OpenSubdiv::Sdc::Crease;
-  const TopologyLevel &base_level = getOSDTopologyRefiner(topology_refiner)->GetLevel(0);
-  // Create mapping for quick lookup of edge index from its vertices 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);
+  if (converter->isInfiniteSharpVertex != nullptr &&
+      converter->isInfiniteSharpVertex(converter, vertex_index)) {
+    return OpenSubdiv::Sdc::Crease::SHARPNESS_INFINITE;
+  }
+
+  if (converter->getVertexSharpness != nullptr) {
+    return converter->getVertexSharpness(converter, vertex_index);
   }
-  const int num_vertices = base_level.GetNumVertices();
+
+  return 0.0f;
+}
+
+bool checkVertexSharpnessMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
+                               const OpenSubdiv_Converter *converter)
+{
+  const MeshTopology &base_mesh_topology = topology_refiner->impl->base_mesh_topology;
+
+  const int num_vertices = base_mesh_topology.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;
-      }
+    const float current_sharpness = base_mesh_topology.vertices[vertex_index].sharpness;
+    const float requested_sharpness = getEffectiveVertexSharpness(converter, vertex_index);
+
+    if (current_sharpness != requested_sharpness) {
+      return false;
     }
   }
   return true;
@@ -652,7 +630,7 @@ bool checkTopologyAttributesMatch(const OpenSubdiv_TopologyRefiner *topology_ref
                                   const OpenSubdiv_Converter *converter)
 {
   return checkEdgeTagsMatch(topology_refiner, converter) &&
-         checkvertexSharpnessMatch(topology_refiner, converter) &&
+         checkVertexSharpnessMatch(topology_refiner, converter) &&
          checkUVLayersMatch(topology_refiner, converter);
 }
 
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
index 1a51fce6e24..c9c72f18349 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
@@ -29,6 +29,8 @@
 
 #include "internal/base/type.h"
 #include "internal/base/type_convert.h"
+#include "internal/topology/mesh_topology.h"
+
 #include "opensubdiv_converter_capi.h"
 
 using blender::opensubdiv::min;
@@ -37,6 +39,7 @@ using blender::opensubdiv::vector;
 
 struct TopologyRefinerData {
   const OpenSubdiv_Converter *converter;
+  blender::opensubdiv::MeshTopology *base_mesh_topology;
 };
 
 typedef OpenSubdiv::Far::TopologyRefinerFactory<TopologyRefinerData> TopologyRefinerFactoryType;
@@ -49,7 +52,11 @@ template<>
 inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
     TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
 {
+  using blender::opensubdiv::MeshTopology;
+
   const OpenSubdiv_Converter *converter = cb_data.converter;
+  MeshTopology *base_mesh_topology = cb_data.base_mesh_topology;
+
   // Faces and face-vertices.
   const int num_faces = converter->getNumFaces(converter);
   setNumBaseFaces(refiner, num_faces);
@@ -57,13 +64,17 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
     const int num_face_vertices = converter->getNumFaceVertices(converter, face_index);
     setNumBaseFaceVertices(refiner, face_index, num_face_vertices);
   }
+
   // Vertices.
   const int num_vertices = converter->getNumVertices(converter);
+  base_mesh_topology->setNumVertices(num_vertices);
   setNumBaseVertices(refiner, num_vertices);
+
   // If converter does not provide full topology, we are done.
   if (!converter->specifiesFullTopology(converter)) {
     return true;
   }
+
   // Edges and edge-faces.
   const int num_edges = converter->getNumEdges(converter);
   setNumBaseEdges(refiner, num_edges);
@@ -71,6 +82,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
     const int num_edge_faces = converter->getNumEdgeFaces(converter, edge_index);
     setNumBaseEdgeFaces(refiner, edge_index, num_edge_faces);
   }
+
   // Vertex-faces and vertex-edges.
   for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
     const int num_vert_edges = converter->getNumVertexEdges(converter, vertex_index);
@@ -78,6 +90,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
     setNumBaseVertexEdges(refiner, vertex_index, num_vert_edges);
     setNumBaseVertexFaces(refiner, vertex_index, num_vert_faces);
   }
+
   return true;
 }
 
@@ -137,8 +150,12 @@ template<>
 inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
     TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
 {
+  using blender::opensubdiv::MeshTopology;
   using OpenSubdiv::Sdc::Crease;
+
   const OpenSubdiv_Converter *converter = cb_data.converter;
+  MeshTopology *base_mesh_topology = cb_data.base_mesh_topology;
+
   const bool full_topology_specified = converter->specifiesFullTopology(converter);
   if (full_topology_specified || converter->getEdgeVertices != NULL) {
     const int num_edges = converter->getNumEdges(converter);
@@ -151,6 +168,8 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
         setBaseEdgeSharpness(refiner, edge_index, sharpness);
       }
       else {
+        // TODO(sergey): Should be a faster way to find reconstructed edge to
+        // specify sharpness for (assuming, findBaseEdge has linear complexity).
         int edge_vertices[2];
         converter->getEdgeVertices(converter, edge_index, edge_vertices);
         const int base_edge_index = findBaseEdge(refiner, edge_vertices[0], edge_vertices[1]);
@@ -162,6 +181,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
       }
     }
   }
+
   // OpenSubdiv expects non-manifold vertices to be sharp but at the time it
   // handles correct cases when vertex is a corner of plane. Currently mark
   // vertices which are adjacent to a loose edge as sharp, but this decision
@@ -170,6 +190,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
   for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
     ConstIndexArray vertex_edges = getBaseVertexEdges(refiner, vertex_index);
     if (converter->isInfiniteSharpVertex(converter, vertex_index)) {
+      base_mesh_topology->setVertexSharpness(vertex_index, Crease::SHARPNESS_INFINITE);
       setBaseVertexSharpness(refiner, vertex_index, Crease::SHARPNESS_INFINITE);
       continue;
     }
@@ -178,6 +199,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
     float sharpness = 0.0f;
     if (converter->getVertexSharpness != NULL) {
       sharpness = converter->getVertexSharpness(converter, vertex_index);
+      base_mesh_topology->setVertexSharpness(vertex_index, sharpness);
     }
 
     // If it's vertex where 2 non-manifold edges meet adjust vertex sharpness to
@@ -291,8 +313,11 @@ TopologyRefinerImpl *TopologyRefinerImpl::createFromConverter(
 {
   using OpenSubdiv::Far::TopologyRefiner;
 
+  blender::opensubdiv::MeshTopology base_mesh_topology;
+
   TopologyRefinerData cb_data;
   cb_data.converter = converter;
+  cb_data.base_mesh_topology = &base_mesh_topology;
 
   // Create OpenSubdiv descriptor for the topology r

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list