[Bf-blender-cvs] [bb6dd4a6c31] opensubdiv_compare: OpenSubdiv: Use explicit storage for edge sharpness

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


Commit: bb6dd4a6c31403ed759fd9dbbbf9717c9a66cb54
Author: Sergey Sharybin
Date:   Tue May 19 12:38:52 2020 +0200
Branches: opensubdiv_compare
https://developer.blender.org/rBbb6dd4a6c31403ed759fd9dbbbf9717c9a66cb54

OpenSubdiv: Use explicit storage for edge sharpness

Similar to previous change in vertex sharpness, explicitly store value
provided by the converter.

Allows to avoid rather fragile check for boundary edges.

Also allows to avoid need in constructing edge map. This lowers memory
footprint of the comparison process and avoids memory allocations
during the comparison (which is an extra benefit from the performance
point of view).

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

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

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

diff --git a/intern/opensubdiv/internal/topology/mesh_topology.cc b/intern/opensubdiv/internal/topology/mesh_topology.cc
index f8832d61cd0..e4469a83f75 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology.cc
+++ b/intern/opensubdiv/internal/topology/mesh_topology.cc
@@ -23,7 +23,7 @@
 namespace blender {
 namespace opensubdiv {
 
-MeshTopology::MeshTopology()
+MeshTopology::MeshTopology() : num_vertices_(0), num_edges_(0)
 {
 }
 
@@ -31,21 +31,102 @@ MeshTopology::~MeshTopology()
 {
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Vertices.
+
 void MeshTopology::setNumVertices(int num_vertices)
 {
-  vertices.resize(num_vertices);
+  num_vertices_ = num_vertices;
 }
+
 int MeshTopology::getNumVertices() const
 {
-  return vertices.size();
+  return num_vertices_;
 }
 
 void MeshTopology::setVertexSharpness(int vertex_index, float sharpness)
 {
   assert(vertex_index >= 0);
-  assert(vertex_index < vertices.size());
+  assert(vertex_index < getNumVertices());
+
+  ensureVertexTagsSize(vertex_index + 1);
+
+  vertex_tags_[vertex_index].sharpness = sharpness;
+}
+
+float MeshTopology::getVertexSharpness(int vertex_index) const
+{
+  assert(vertex_index >= 0);
+  assert(vertex_index < getNumVertices());
 
-  vertices[vertex_index].sharpness = sharpness;
+  if (vertex_index >= vertex_tags_.size()) {
+    // Sharpness for the vertex was never provided.
+    return 0.0f;
+  }
+
+  return vertex_tags_[vertex_index].sharpness;
+}
+
+void MeshTopology::ensureVertexTagsSize(int num_vertices)
+{
+  if (vertex_tags_.size() < num_vertices) {
+    vertex_tags_.resize(num_vertices);
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Edges.
+
+void MeshTopology::setNumEdges(int num_edges)
+{
+  num_edges_ = num_edges;
+}
+
+int MeshTopology::getNumEdges() const
+{
+  return num_edges_;
+}
+
+void MeshTopology::setEdgeSharpness(int edge_index, float sharpness)
+{
+  assert(edge_index >= 0);
+
+  ensureNumEdgesAtLeast(edge_index + 1);
+
+  if (sharpness < 1e-6f) {
+    return;
+  }
+
+  ensureEdgeTagsSize(edge_index + 1);
+
+  edge_tags_[edge_index].sharpness = sharpness;
+}
+
+float MeshTopology::getEdgeSharpness(int edge_index) const
+{
+  assert(edge_index >= 0);
+
+  if (edge_index >= edge_tags_.size()) {
+    // NOTE: It's possible that full topology is not known and that there was
+    // never sharpness assigned to any of the edges.
+    return 0.0f;
+  }
+
+  return edge_tags_[edge_index].sharpness;
+}
+
+void MeshTopology::ensureNumEdgesAtLeast(int num_edges)
+{
+  if (getNumEdges() < num_edges) {
+    setNumEdges(num_edges);
+  }
+}
+
+void MeshTopology::ensureEdgeTagsSize(int num_edges)
+{
+  if (edge_tags_.size() < num_edges) {
+    edge_tags_.resize(num_edges);
+  }
 }
 
 }  // namespace opensubdiv
diff --git a/intern/opensubdiv/internal/topology/mesh_topology.h b/intern/opensubdiv/internal/topology/mesh_topology.h
index 9893c70dac8..183f5eb45d4 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology.h
+++ b/intern/opensubdiv/internal/topology/mesh_topology.h
@@ -27,7 +27,12 @@ struct OpenSubdiv_Converter;
 namespace blender {
 namespace opensubdiv {
 
-class VertexTopology {
+class VertexTopologyTag {
+ public:
+  float sharpness = 0.0f;
+};
+
+class EdgeTopologyTag {
  public:
   float sharpness = 0.0f;
 };
@@ -45,12 +50,44 @@ class MeshTopology {
   MeshTopology &operator=(const MeshTopology &other) = default;
   MeshTopology &operator=(MeshTopology &&other) = default;
 
+  //////////////////////////////////////////////////////////////////////////////
+  // Vertices.
+
   void setNumVertices(int num_vertices);
   int getNumVertices() const;
 
   void setVertexSharpness(int vertex_index, float sharpness);
+  float getVertexSharpness(int vertex_index) const;
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Edges.
+
+  void setNumEdges(int num_edges);
+
+  // NOTE: Unless full topology was specified will return number of edges based
+  // on last edge index for which topology tag was specified.
+  int getNumEdges() const;
+
+  void setEdgeSharpness(int edge_index, float sharpness);
+  float getEdgeSharpness(int edge_index) const;
+
+ protected:
+  // Unless full topology was specified the number of edges is not know ahead
+  // of a time.
+  void ensureNumEdgesAtLeast(int num_edges);
+
+  // Geometry tags are stored sparsly.
+  //
+  // These functions ensures that the storage can be addressed by an index which
+  // corresponds to the given size.
+  void ensureVertexTagsSize(int num_vertices);
+  void ensureEdgeTagsSize(int num_edges);
+
+  int num_vertices_;
+  vector<VertexTopologyTag> vertex_tags_;
 
-  vector<VertexTopology> vertices;
+  int num_edges_;
+  vector<EdgeTopologyTag> edge_tags_;
 
   MEM_CXX_CLASS_ALLOC_FUNCS("MeshTopology");
 };
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
index c9c72f18349..a0e0269936c 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
@@ -77,6 +77,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
 
   // Edges and edge-faces.
   const int num_edges = converter->getNumEdges(converter);
+  base_mesh_topology->setNumEdges(num_edges);
   setNumBaseEdges(refiner, num_edges);
   for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
     const int num_edge_faces = converter->getNumEdgeFaces(converter, edge_index);
@@ -161,9 +162,12 @@ 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;
       }
+
       if (full_topology_specified) {
         setBaseEdgeSharpness(refiner, edge_index, sharpness);
       }
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
index d51d0eb7f54..06612a9e6a1 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
@@ -18,7 +18,6 @@
 
 #include "internal/topology/topology_refiner_impl.h"
 
-#include "internal/base/edge_map.h"
 #include "internal/base/type.h"
 #include "internal/base/type_convert.h"
 #include "internal/topology/mesh_topology.h"
@@ -233,102 +232,37 @@ bool checkGeometryMatches(const TopologyRefinerImpl *topology_refiner_impl,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// Compare attributes which affects on topology
+// Compare attributes which affects on topology.
 
-inline bool checkSingleEdgeSharpnessMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
-                                          int base_level_edge_index,
-                                          const OpenSubdiv_Converter *converter,
-                                          int converter_edge_index)
+// TODO(sergey): Make this function usable by factory as well.
+float getEffectiveEdgeSharpness(const OpenSubdiv_Converter *converter, const int edge_index)
 {
-  // NOTE: Boundary and non-manifold edges are internally forced to an infinite
-  // sharpness. So we can not reliably compare those.
-  //
-  // TODO(sergey): Watch for NON_MANIFOLD_SHARP option.
-  if (base_level.IsEdgeBoundary(base_level_edge_index) ||
-      base_level.IsEdgeNonManifold(base_level_edge_index)) {
-    return true;
-  }
-  const float sharpness = base_level.GetEdgeSharpness(base_level_edge_index);
-  const float converter_sharpness = converter->getEdgeSharpness(converter, converter_edge_index);
-  if (sharpness != converter_sharpness) {
-    return false;
+  if (converter->getEdgeSharpness != nullptr) {
+    return converter->getEdgeSharpness(converter, edge_index);
   }
-  return true;
-}
 
-inline bool checkSingleEdgeTagMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
-                                    int base_level_edge_index,
-                                    const OpenSubdiv_Converter *converter,
-                                    int converter_edge_index)
-{
-  return checkSingleEdgeSharpnessMatch(
-      base_level, base_level_edge_index, converter, converter_edge_index);
+  return 0.0f;
 }
 
-// Compares edge tags between topology refiner and converter in a case when
-// converter specifies a full topology.
-// This is simplest loop, since we know that order of edges matches.
-bool checkEdgeTagsMatchFullTopology(const TopologyRefinerImpl *topology_refiner_impl,
-                                    const OpenSubdiv_Converter *converter)
+bool checkEdgeTagsMatch(const TopologyRefinerImpl *topology_refiner_impl,
+                        const OpenSubdiv_Converter *converter)
 {
-  using OpenSubdiv::Far::ConstIndexArray;
-  using OpenSubdiv::Far::TopologyLevel;
-  const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner_impl);
-  const int num_edges = base_level.GetNumEdges();
-  for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
-    if (!checkSingleEdgeTagMatch(base_level, edge_index, converter, edge_index)) {
-      return false;
-    }
-  }
-  return true;
-}
+  const MeshTopology &base_mesh_topology = topology_refiner_impl->base_mesh_topology;
 
-// Compares tags of edges in the case when orientation of edges is left up to
-// OpenSubdiv. In this case we do need to take care of mapping edges from the
-// converter to current topology refiner, since the order is not guaranteed.
-bool checkEdgeTagsMatchAutoOrient(const TopologyRefinerImpl *topology_refiner_impl,
-                                  const OpenSubdiv_Converter *converter)
-{
-  using OpenSubdiv::Far::ConstIndexArray;
-  using OpenSubdiv::Far::TopologyLevel;
-  const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner_impl);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list