[Bf-blender-cvs] [b597fa56d3c] opensubdiv_compare: OpenSubdiv: Only store edges topology for non-smooth edges

Sergey Sharybin noreply at git.blender.org
Tue May 26 12:58:52 CEST 2020


Commit: b597fa56d3c58624a57d5aff2befc8b7c08c0e08
Author: Sergey Sharybin
Date:   Tue May 26 12:42:13 2020 +0200
Branches: opensubdiv_compare
https://developer.blender.org/rBb597fa56d3c58624a57d5aff2befc8b7c08c0e08

OpenSubdiv: Only store edges topology for non-smooth edges

This change makes it so vertices of edge are only stored when edge
has non-zero crease. This allows to lower memory footprint of 1.5M
faces from 78 MiB to 54 MiB in the case all creases are zero.

Meshes with crease are more hard to predict due to array-based
storage, so it all depends on index of edge with crease. Worst case
(all edges are creased) still stays at 78 MiB.

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

M	intern/opensubdiv/internal/topology/mesh_topology.cc
M	intern/opensubdiv/internal/topology/mesh_topology.h
M	intern/opensubdiv/internal/topology/mesh_topology_compare.cc
M	intern/opensubdiv/internal/topology/topology_refiner_factory.cc

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

diff --git a/intern/opensubdiv/internal/topology/mesh_topology.cc b/intern/opensubdiv/internal/topology/mesh_topology.cc
index 3d8535ee2f1..9197a5c1b54 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology.cc
+++ b/intern/opensubdiv/internal/topology/mesh_topology.cc
@@ -80,8 +80,6 @@ void MeshTopology::ensureVertexTagsSize(int num_vertices)
 void MeshTopology::setNumEdges(int num_edges)
 {
   num_edges_ = num_edges;
-
-  edges_.resize(num_edges_);
 }
 
 int MeshTopology::getNumEdges() const
@@ -112,6 +110,12 @@ void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
   assert(edge_index >= 0);
   assert(edge_index < getNumEdges());
 
+  if (edge_index >= edges_.size()) {
+    *v1 = -1;
+    *v1 = -1;
+    return;
+  }
+
   const Edge &edge = edges_[edge_index];
   *v1 = edge.v1;
   *v2 = edge.v2;
@@ -122,6 +126,10 @@ bool MeshTopology::isEdgeEqual(int edge_index, int expected_v1, int expected_v2)
   assert(edge_index >= 0);
   assert(edge_index < getNumEdges());
 
+  if (edge_index >= edges_.size()) {
+    return false;
+  }
+
   const Edge &edge = edges_[edge_index];
   return edge.v1 == expected_v1 && edge.v2 == expected_v2;
 }
@@ -155,8 +163,8 @@ float MeshTopology::getEdgeSharpness(int edge_index) const
 
 void MeshTopology::ensureNumEdgesAtLeast(int num_edges)
 {
-  if (getNumEdges() < num_edges) {
-    setNumEdges(num_edges);
+  if (edges_.size() < num_edges) {
+    edges_.resize(num_edges);
   }
 }
 
diff --git a/intern/opensubdiv/internal/topology/mesh_topology.h b/intern/opensubdiv/internal/topology/mesh_topology.h
index ddabc322a6e..861614482ef 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology.h
+++ b/intern/opensubdiv/internal/topology/mesh_topology.h
@@ -125,8 +125,8 @@ class MeshTopology {
   bool isEqualToConverter(const OpenSubdiv_Converter *converter) const;
 
  protected:
-  // Unless full topology was specified the number of edges is not know ahead
-  // of a time.
+  // Edges are allowed to be stored sparsly, to save memory used by
+  // non-semi-sharp edges.
   void ensureNumEdgesAtLeast(int num_edges);
 
   // Geometry tags are stored sparsly.
diff --git a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
index fe30c3f43a5..fd291e72cab 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
+++ b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
@@ -71,16 +71,14 @@ bool isEqualGeometryEdge(const MeshTopology &mesh_topology, const OpenSubdiv_Con
     return false;
   }
 
-  for (int edge_index = 0; edge_index < num_requested_edges; ++edge_index) {
-    int requested_edge_vertices[2];
-    converter->getEdgeVertices(converter, edge_index, requested_edge_vertices);
-
-    if (!mesh_topology.isEdgeEqual(
-            edge_index, requested_edge_vertices[0], requested_edge_vertices[1])) {
-      printf("edge mismatch\n");
-      return false;
-    }
-  }
+  // NOTE: Ignoring the sharpness we don't really care of the content of the
+  // edges, they should be in the consistent state with faces and face-vertices.
+  // If that's not the case the mesh is invalid and comparison can not happen
+  // reliably.
+  //
+  // For sharpness it is important to know that edges are connecting same pair
+  // of vertices. But since sharpness is stored sparesly the connectivity will
+  // be checked when comparing edge sharpness.
 
   return true;
 }
@@ -183,6 +181,17 @@ bool isEqualEdgeTags(const MeshTopology &mesh_topology, const OpenSubdiv_Convert
     if (current_sharpness != requested_sharpness) {
       return false;
     }
+
+    if (current_sharpness < 1e-6f) {
+      continue;
+    }
+
+    int requested_edge_vertices[2];
+    converter->getEdgeVertices(converter, edge_index, requested_edge_vertices);
+    if (!mesh_topology.isEdgeEqual(
+            edge_index, requested_edge_vertices[0], requested_edge_vertices[1])) {
+      return false;
+    }
   }
 
   return true;
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
index e0c5e18e504..9688bc9eb0f 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
@@ -130,21 +130,6 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology
 
   const bool full_topology_specified = converter->specifiesFullTopology(converter);
 
-  // Vertices of an edge.
-  //
-  // NOTE: Only specify for base mesh topology on our side.
-  // They will be provided to the topology refiner only if the full topology is
-  // specified.
-  if (converter->getNumEdges != nullptr) {
-    const int num_edges = converter->getNumEdges(converter);
-    for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
-      int edge_vertices[2];
-      converter->getEdgeVertices(converter, edge_index, edge_vertices);
-
-      base_mesh_topology->setEdgeVertexIndices(edge_index, edge_vertices[0], edge_vertices[1]);
-    }
-  }
-
   // Vertices of face.
   const int num_faces = converter->getNumFaces(converter);
   for (int face_index = 0; face_index < num_faces; ++face_index) {
@@ -186,12 +171,8 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology
   const int num_edges = converter->getNumEdges(converter);
   for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
     // Vertices this edge connects.
-    int v1, v2;
-    base_mesh_topology->getEdgeVertexIndices(edge_index, &v1, &v2);
-
     IndexArray dst_edge_vertices = getBaseEdgeVertices(refiner, edge_index);
-    dst_edge_vertices[0] = v1;
-    dst_edge_vertices[1] = v2;
+    converter->getEdgeVertices(converter, edge_index, &dst_edge_vertices[0]);
 
     // Faces adjacent to this edge.
     IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge_index);
@@ -224,20 +205,21 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
     const int num_edges = converter->getNumEdges(converter);
     for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
       const float sharpness = converter->getEdgeSharpness(converter, edge_index);
-      base_mesh_topology->setEdgeSharpness(edge_index, sharpness);
-
       if (sharpness < 1e-6f) {
         continue;
       }
 
+      int edge_vertices[2];
+      converter->getEdgeVertices(converter, edge_index, edge_vertices);
+      base_mesh_topology->setEdgeVertexIndices(edge_index, edge_vertices[0], edge_vertices[1]);
+      base_mesh_topology->setEdgeSharpness(edge_index, sharpness);
+
       if (full_topology_specified) {
         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]);
         if (base_edge_index == OpenSubdiv::Far::INDEX_INVALID) {
           printf("OpenSubdiv Error: failed to find reconstructed edge\n");



More information about the Bf-blender-cvs mailing list