Commit: 275bccc27c5885be271c60192d760834e58358a8
Author: Sergey Sharybin
Date:   Tue May 19 16:19:40 2020 +0200
Branches: opensubdiv_compare
https://developer.blender.org/rB275bccc27c5885be271c60192d760834e58358a8

OpenSubdiv: Keep explicit storage of base mesh faces

Allows to perform comparison by doing linear comparison of indices.

Before cyclic match was used to deal with possibly changed winding from
OpenSubdiv side.

Speeds up comparison (and hence improves FPS), makes code more reliable
nut uses more memory.

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

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
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 483595dbfe1..ae7c1e069b6 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() : num_vertices_(0), num_edges_(0)
+MeshTopology::MeshTopology() : num_vertices_(0), num_edges_(0), num_faces_(0)
 {
 }
 
@@ -168,5 +168,45 @@ void MeshTopology::ensureEdgeTagsSize(int num_edges)
   }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Faces.
+
+void MeshTopology::setNumFaces(int num_faces)
+{
+  num_faces_ = num_faces;
+
+  faces_.resize(num_faces);
+}
+
+int MeshTopology::getNumFaces() const
+{
+  return num_faces_;
+}
+
+FaceTopology &MeshTopology::getFace(int face_index)
+{
+  const MeshTopology *const_this = this;
+  return const_cast<FaceTopology &>(const_this->getFace(face_index));
+}
+const FaceTopology &MeshTopology::getFace(int face_index) const
+{
+  assert(face_index >= 0);
+  assert(face_index < getNumFaces());
+
+  return faces_[face_index];
+}
+
+void MeshTopology::setNumFaceVertices(int face_index, int num_face_vertices)
+{
+  FaceTopology &face = getFace(face_index);
+  face.setNumVertices(num_face_vertices);
+}
+
+void MeshTopology::setFaceVertexIndices(int face_index, int 
*face_vertex_indices)
+{
+  FaceTopology &face = getFace(face_index);
+  face.setVertexIndices(face_vertex_indices);
+}
+
 }  // namespace opensubdiv
 }  // namespace blender
diff --git a/intern/opensubdiv/internal/topology/mesh_topology.h 
b/intern/opensubdiv/internal/topology/mesh_topology.h
index 6edbc59b230..196d79c87df 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology.h
+++ b/intern/opensubdiv/internal/topology/mesh_topology.h
@@ -19,6 +19,8 @@
 #ifndef OPENSUBDIV_MESH_TOPOLOGY_H_
 #define OPENSUBDIV_MESH_TOPOLOGY_H_
 
+#include <cstring>
+
 #include "internal/base/memory.h"
 #include "internal/base/type.h"
 
@@ -43,6 +45,37 @@ class EdgeTopology {
   int v2 = -1;
 };
 
+class FaceTopology {
+ public:
+  void setNumVertices(int num_vertices)
+  {
+    vertex_indices.resize(num_vertices, -1);
+  }
+
+  void setVertexIndices(int *face_vertex_indices)
+  {
+    memcpy(vertex_indices.data(), face_vertex_indices, sizeof(int) * 
vertex_indices.size());
+  }
+
+  bool isValid() const
+  {
+    for (int vertex_index : vertex_indices) {
+      if (vertex_index < 0) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  int getNumVertices() const
+  {
+    return vertex_indices.size();
+  }
+
+  vector<int> vertex_indices;
+};
+
 class EdgeTopologyTag {
  public:
   float sharpness = 0.0f;
@@ -87,6 +120,19 @@ class MeshTopology {
   void setEdgeSharpness(int edge_index, float sharpness);
   float getEdgeSharpness(int edge_index) const;
 
+  
//////////////////////////////////////////////////////////////////////////////
+  // Faces.
+
+  void setNumFaces(int num_faces);
+
+  int getNumFaces() const;
+
+  FaceTopology &getFace(int face_index);
+  const FaceTopology &getFace(int face_index) const;
+
+  void setNumFaceVertices(int face_index, int num_face_vertices);
+  void setFaceVertexIndices(int face_index, int *face_vertex_indices);
+
   
//////////////////////////////////////////////////////////////////////////////
   // Comparison.
 
@@ -113,6 +159,9 @@ class MeshTopology {
   vector<EdgeTopology> edges_;
   vector<EdgeTopologyTag> edge_tags_;
 
+  int num_faces_;
+  vector<FaceTopology> faces_;
+
   MEM_CXX_CLASS_ALLOC_FUNCS("MeshTopology");
 };
 
diff --git a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc 
b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
index c8ae0638bed..a2561568c71 100644
--- a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
+++ b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc
@@ -19,8 +19,11 @@
 #include "internal/topology/mesh_topology.h"
 
 #include <cassert>
+#include <cstring>
 #include <opensubdiv/sdc/crease.h>
 
+#include "internal/base/type.h"
+
 #include "opensubdiv_converter_capi.h"
 
 namespace blender {
@@ -42,7 +45,7 @@ int getEffectiveNumEdges(const OpenSubdiv_Converter 
*converter)
   return converter->getNumEdges(converter);
 }
 
-bool isEqualEdgeGeometry(const MeshTopology &mesh_topology, const 
OpenSubdiv_Converter *converter)
+bool isEqualGeometryEdge(const MeshTopology &mesh_topology, const 
OpenSubdiv_Converter *converter)
 {
   const int num_requested_edges = getEffectiveNumEdges(converter);
   if (num_requested_edges != mesh_topology.getNumEdges()) {
@@ -63,11 +66,43 @@ bool isEqualEdgeGeometry(const MeshTopology &mesh_topology, 
const OpenSubdiv_Con
   return true;
 }
 
+// Faces.
+
+bool isEqualGeometryFace(const MeshTopology &mesh_topology, const 
OpenSubdiv_Converter *converter)
+{
+  const int num_requested_faces = converter->getNumFaces(converter);
+  if (num_requested_faces != mesh_topology.getNumFaces()) {
+    return false;
+  }
+
+  vector<int> vertices_of_face;
+  for (int face_index = 0; face_index < num_requested_faces; ++face_index) {
+    const FaceTopology &current_face = mesh_topology.getFace(face_index);
+
+    int num_face_vertices = converter->getNumFaceVertices(converter, 
face_index);
+    if (current_face.getNumVertices() != num_face_vertices) {
+      return false;
+    }
+
+    vertices_of_face.resize(num_face_vertices);
+    converter->getFaceVertices(converter, face_index, vertices_of_face.data());
+
+    if (current_face.vertex_indices != vertices_of_face) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 // Geometry comparison entry point.
 
 bool isEqualGeometry(const MeshTopology &mesh_topology, const 
OpenSubdiv_Converter *converter)
 {
-  if (!isEqualEdgeGeometry(mesh_topology, converter)) {
+  if (!isEqualGeometryEdge(mesh_topology, converter)) {
+    return false;
+  }
+  if (!isEqualGeometryFace(mesh_topology, converter)) {
     return false;
   }
 
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc 
b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
index 239a8447f47..c01cf158668 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
@@ -52,6 +52,7 @@ template<>
 inline bool 
TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
     TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
 {
+  using blender::opensubdiv::FaceTopology;
   using blender::opensubdiv::MeshTopology;
 
   const OpenSubdiv_Converter *converter = cb_data.converter;
@@ -81,9 +82,11 @@ inline bool 
TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
 
   // Faces and face-vertices.
   const int num_faces = converter->getNumFaces(converter);
+  base_mesh_topology->setNumFaces(num_faces);
   setNumBaseFaces(refiner, num_faces);
   for (int face_index = 0; face_index < num_faces; ++face_index) {
     const int num_face_vertices = converter->getNumFaceVertices(converter, 
face_index);
+    base_mesh_topology->setNumFaceVertices(face_index, num_face_vertices);
     setNumBaseFaceVertices(refiner, face_index, num_face_vertices);
   }
 
@@ -147,6 +150,8 @@ inline bool 
TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology
   for (int face_index = 0; face_index < num_faces; ++face_index) {
     IndexArray dst_face_verts = getBaseFaceVertices(refiner, face_index);
     converter->getFaceVertices(converter, face_index, &dst_face_verts[0]);
+
+    base_mesh_topology->setFaceVertexIndices(face_index, &dst_face_verts[0]);
   }
 
   // If converter does not provide full topology, we are done.
diff --git 
a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc 
b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
index 3506d93b7aa..41727d5664a 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc
@@ -85,150 +85,6 @@ bool checkPreliminaryMatches(const TopologyRefinerImpl 
*topology_refiner_impl,
          checkGeometryCountersMatches(topology_refiner_impl, converter);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// Geometry comparison.
-
-// A thin wrapper around index like array which does cyclic access. This means,
-// it basically does indices[requested_index % num_indices].
-//
-// NOTE: This array does not own the memory.
-//
-// TODO(sergey): Consider moving this to a more reusable place.
-class CyclicArray {
- public:
-  typedef int value_type;
-  typedef int size_type;
-  static constexpr size_type npos = -1;
-
-  explicit CyclicArray(const std::vector<int> &data) : data_(data.data()), 
size_(data.size())
-  {
-  }
-
-  explicit CyclicArray(const OpenSubdiv::Far::ConstIndexArray &data)
-      : data_(&data[0]), size_(data.size())
-  {
-  }
-
-  inline value_type operator[](int index) const
-  {
-    assert(index >= 0);
-    // TODO(sergey): Check whether doing check for element index exceeding 
total
-    // number of indices prior to modulo helps performance.
-    return data_[index % size()];
-  }
-
-  inline size_type size() const
-  {
-    return size_;
-  }
-
-  // Find index of first occurrence of a given value.
-  inline size_type find(const value_type value) const
-  {
-    const int num_indices = size();
-    for (size_type i = 0; i < num_indices; ++i) {
-      if (value == (*this)[i]) {
-        return i;
-      }
-    }
-    return npos;
-  }
-
- protected:
-  const value_type *data_;
-  const size_type size_;
-};
-
-bool compareCyclicForward(const CyclicArray &array_a,
-                          const int start_a,
-                          const CyclicArray &array_b,
-                          const int start_b)
-{
-  const int num_elements = array_a.size();
-  for (int i = 0; i < num_elements; ++i) {
-    if (array_a[start_a + i] != array_b[start_b + i]) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool compareCyclicBackward(const CyclicArray &array_a,
-                           const int start_a,
-                           const CyclicArra

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to