[Bf-blender-cvs] [bdd0701c433] opensubdiv_compare: OpenSubdiv: Refactor, move comparison to own file

Sergey Sharybin noreply at git.blender.org
Mon May 25 15:46:21 CEST 2020


Commit: bdd0701c433b9312a4d5b07d6dce67d2c597f318
Author: Sergey Sharybin
Date:   Tue May 19 12:02:54 2020 +0200
Branches: opensubdiv_compare
https://developer.blender.org/rBbdd0701c433b9312a4d5b07d6dce67d2c597f318

OpenSubdiv: Refactor, move comparison to own file

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

M	intern/opensubdiv/CMakeLists.txt
M	intern/opensubdiv/internal/topology/topology_refiner_capi.cc
M	intern/opensubdiv/internal/topology/topology_refiner_impl.h
A	intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc

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

diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index 70c5453d3bd..98bb723ebd9 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -83,6 +83,7 @@ if(WITH_OPENSUBDIV)
     internal/topology/topology_refiner_capi.cc
     internal/topology/topology_refiner_factory.cc
     internal/topology/topology_refiner_impl.cc
+    internal/topology/topology_refiner_impl_compare.cc
     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 8c3f8f1f896..b30d509be20 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
@@ -19,12 +19,8 @@
 #include "opensubdiv_topology_refiner_capi.h"
 
 #include "MEM_guardedalloc.h"
-#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"
 
 using blender::opensubdiv::vector;
 
@@ -259,389 +255,8 @@ void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refin
   OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefiner);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// Comparison with converter.
-
-namespace blender {
-namespace opensubdiv {
-namespace {
-
-///////////////////////////////////////////////////////////
-// Quick preliminary checks.
-
-bool checkSchemeTypeMatches(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                            const OpenSubdiv_Converter *converter)
-{
-  const OpenSubdiv::Sdc::SchemeType converter_scheme_type =
-      blender::opensubdiv::getSchemeTypeFromCAPI(converter->getSchemeType(converter));
-  return (converter_scheme_type == getOSDTopologyRefiner(topology_refiner)->GetSchemeType());
-}
-
-bool checkOptionsMatches(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                         const OpenSubdiv_Converter *converter)
-{
-  typedef OpenSubdiv::Sdc::Options Options;
-  const Options options = getOSDTopologyRefiner(topology_refiner)->GetSchemeOptions();
-  const Options::FVarLinearInterpolation fvar_interpolation = options.GetFVarLinearInterpolation();
-  const Options::FVarLinearInterpolation converter_fvar_interpolation =
-      blender::opensubdiv::getFVarLinearInterpolationFromCAPI(
-          converter->getFVarLinearInterpolation(converter));
-  if (fvar_interpolation != converter_fvar_interpolation) {
-    return false;
-  }
-  return true;
-}
-
-bool checkGeometryCountersMatches(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                                  const OpenSubdiv_Converter *converter)
-{
-  using OpenSubdiv::Far::TopologyLevel;
-  const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
-  return ((converter->getNumVertices(converter) == base_level.GetNumVertices()) &&
-          (converter->getNumEdges(converter) == base_level.GetNumEdges()) &&
-          (converter->getNumFaces(converter) == base_level.GetNumFaces()));
-}
-
-bool checkPreliminaryMatches(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                             const OpenSubdiv_Converter *converter)
-{
-  return checkSchemeTypeMatches(topology_refiner, converter) &&
-         checkOptionsMatches(topology_refiner, converter) &&
-         checkGeometryCountersMatches(topology_refiner, 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 CyclicArray &array_b,
-                           const int start_b)
-{
-  const int num_elements = array_a.size();
-  // TODO(sergey): Some optimization might be possible with memcmp trickery.
-  for (int i = 0; i < num_elements; ++i) {
-    if (array_a[start_a + (num_elements - i - 1)] != array_b[start_b + (num_elements - i - 1)]) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// Utility function dedicated for checking whether whether vertices indices
-// used by two faces match.
-// The tricky part here is that we can't trust 1:1 array match here, since it's
-// possible that OpenSubdiv oriented edges of a face to make it compatible with
-// an internal representation of non-manifold meshes.
-//
-// TODO(sergey): Check whether this is needed, ot whether OpenSubdiv is only
-// creating edges in a proper orientation without modifying indices of face
-// vertices.
-bool checkVerticesOfFacesMatch(const CyclicArray &indices_a, const CyclicArray &indices_b)
-{
-  if (indices_a.size() != indices_b.size()) {
-    return false;
-  }
-  // "Align" the arrays so we know first matched element.
-  const int start_b = indices_b.find(indices_a[0]);
-  if (start_b == indices_b.npos) {
-    return false;
-  }
-  // Check match in both directions, for the case OpenSubdiv did orient face in
-  // a way which made normals more consistent internally.
-  if (compareCyclicForward(indices_a, 0, indices_b, start_b)) {
-    return true;
-  }
-  if (compareCyclicBackward(indices_a, 0, indices_b, start_b)) {
-    return true;
-  }
-  return false;
-}
-
-bool checkGeometryFacesMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                             const OpenSubdiv_Converter *converter)
-{
-  using OpenSubdiv::Far::ConstIndexArray;
-  using OpenSubdiv::Far::TopologyLevel;
-  const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
-  const int num_faces = base_level.GetNumFaces();
-  // TODO(sergey): Consider using data structure which keeps handful of
-  // elements on stack before doing heep allocation.
-  vector<int> conv_face_vertices;
-  for (int face_index = 0; face_index < num_faces; ++face_index) {
-    const ConstIndexArray &face_vertices = base_level.GetFaceVertices(face_index);
-    const int num_face_vertices = face_vertices.size();
-    if (num_face_vertices != converter->getNumFaceVertices(converter, face_index)) {
-      return false;
-    }
-    conv_face_vertices.resize(num_face_vertices);
-    converter->getFaceVertices(converter, face_index, &conv_face_vertices[0]);
-    if (!checkVerticesOfFacesMatch(CyclicArray(conv_face_vertices), CyclicArray(face_vertices))) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool checkGeometryMatches(const OpenSubdiv_TopologyRefiner *topology_refiner,
-                          const OpenSubdiv_Converter *converter)
-{
-  // NOTE: Since OpenSubdiv's topology refiner doesn't contain loose edges, we
-  // are only checking for faces to be matched. Changes in edges we don't care
-  // here too much (they'll be checked for creases changes later).
-  return checkGeometryFacesMatch(topology_refiner, converter);
-}
-
-///////////////////////////////////////////////////////////
-// 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)
-{
-  // 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;
-  }
-  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);
-}
-
-// Compares edge tags between topology refiner and converter in a case when
-//

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list