From 6a8193e505a33c1a09c9afd01630c7a56a6019f2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 19 May 2020 14:30:58 +0200 Subject: OpenSubdiv: Refactor, move mesh topology comparison to own file Makes it easier to follow and extend. --- intern/opensubdiv/CMakeLists.txt | 1 + .../opensubdiv/internal/topology/mesh_topology.h | 7 ++ .../internal/topology/mesh_topology_compare.cc | 111 +++++++++++++++++++++ .../internal/topology/topology_refiner_impl.h | 8 +- .../topology/topology_refiner_impl_compare.cc | 69 +------------ 5 files changed, 129 insertions(+), 67 deletions(-) create mode 100644 intern/opensubdiv/internal/topology/mesh_topology_compare.cc (limited to 'intern') diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index 98bb723ebd9..efa8fccd8b6 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -79,6 +79,7 @@ if(WITH_OPENSUBDIV) # Topology. internal/topology/mesh_topology.cc + internal/topology/mesh_topology_compare.cc internal/topology/mesh_topology.h internal/topology/topology_refiner_capi.cc internal/topology/topology_refiner_factory.cc diff --git a/intern/opensubdiv/internal/topology/mesh_topology.h b/intern/opensubdiv/internal/topology/mesh_topology.h index 183f5eb45d4..375d8a9379f 100644 --- a/intern/opensubdiv/internal/topology/mesh_topology.h +++ b/intern/opensubdiv/internal/topology/mesh_topology.h @@ -71,6 +71,13 @@ class MeshTopology { void setEdgeSharpness(int edge_index, float sharpness); float getEdgeSharpness(int edge_index) const; + ////////////////////////////////////////////////////////////////////////////// + // Comparison. + + // Check whether this topology refiner defines same topology as the given + // converter. + bool isEqualToConverter(const OpenSubdiv_Converter *converter) const; + protected: // Unless full topology was specified the number of edges is not know ahead // of a time. diff --git a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc new file mode 100644 index 00000000000..fd10a53dbe3 --- /dev/null +++ b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc @@ -0,0 +1,111 @@ +// Copyright 2020 Blender Foundation. All rights reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// Author: Sergey Sharybin + +#include "internal/topology/mesh_topology.h" + +#include +#include + +#include "opensubdiv_converter_capi.h" + +namespace blender { +namespace opensubdiv { + +namespace { + +//////////////////////////////////////////////////////////////////////////////// +// Geometry tags. + +// Vertices. + +// TODO(sergey): Make this function usable by factory as well. +float getEffectiveVertexSharpness(const OpenSubdiv_Converter *converter, const int vertex_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); + } + + return 0.0f; +} + +bool isEqualVertexTags(const MeshTopology &mesh_topology, const OpenSubdiv_Converter *converter) +{ + const int num_vertices = mesh_topology.getNumVertices(); + for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { + const float current_sharpness = mesh_topology.getVertexSharpness(vertex_index); + const float requested_sharpness = getEffectiveVertexSharpness(converter, vertex_index); + + if (current_sharpness != requested_sharpness) { + return false; + } + } + + return true; +} + +// Edges. + +// TODO(sergey): Make this function usable by factory as well. +float getEffectiveEdgeSharpness(const OpenSubdiv_Converter *converter, const int edge_index) +{ + if (converter->getEdgeSharpness != nullptr) { + return converter->getEdgeSharpness(converter, edge_index); + } + + return 0.0f; +} + +bool isEqualEdgeTags(const MeshTopology &mesh_topology, const OpenSubdiv_Converter *converter) +{ + const int num_edges = mesh_topology.getNumEdges(); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + const float current_sharpness = mesh_topology.getEdgeSharpness(edge_index); + const float requested_sharpness = getEffectiveEdgeSharpness(converter, edge_index); + + if (current_sharpness != requested_sharpness) { + return false; + } + } + + return true; +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// Entry point. + +bool MeshTopology::isEqualToConverter(const OpenSubdiv_Converter *converter) const +{ + if (!isEqualVertexTags(*this, converter)) { + return false; + } + if (!isEqualEdgeTags(*this, converter)) { + return false; + } + + return true; +} + +} // namespace opensubdiv +} // namespace blender diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl.h b/intern/opensubdiv/internal/topology/topology_refiner_impl.h index 261369c3161..a9750166b35 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_impl.h +++ b/intern/opensubdiv/internal/topology/topology_refiner_impl.h @@ -36,15 +36,17 @@ namespace opensubdiv { class TopologyRefinerImpl { public: - // NOTE: Will return nullptr if topology refiner can not be created (for example, when topology - // is detected to be corrupted or invalid). + // NOTE: Will return nullptr if topology refiner can not be created (for + // example, when topology is detected to be corrupted or invalid). static TopologyRefinerImpl *createFromConverter( OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings &settings); TopologyRefinerImpl(); ~TopologyRefinerImpl(); - // Check whether this topology refiner defines same topology as the given converter. + // Check whether this topology refiner defines same topology as the given + // converter. + // Covers options, geometry, and geometry tags. bool isEqualToConverter(const OpenSubdiv_Converter *converter) const; OpenSubdiv::Far::TopologyRefiner *topology_refiner; diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc index 06612a9e6a1..42f7b27adab 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc @@ -22,6 +22,7 @@ #include "internal/base/type_convert.h" #include "internal/topology/mesh_topology.h" #include "internal/topology/topology_refiner_impl.h" + #include "opensubdiv_converter_capi.h" namespace blender { @@ -234,67 +235,6 @@ bool checkGeometryMatches(const TopologyRefinerImpl *topology_refiner_impl, //////////////////////////////////////////////////////////////////////////////// // Compare attributes which affects on topology. -// TODO(sergey): Make this function usable by factory as well. -float getEffectiveEdgeSharpness(const OpenSubdiv_Converter *converter, const int edge_index) -{ - if (converter->getEdgeSharpness != nullptr) { - return converter->getEdgeSharpness(converter, edge_index); - } - - return 0.0f; -} - -bool checkEdgeTagsMatch(const TopologyRefinerImpl *topology_refiner_impl, - const OpenSubdiv_Converter *converter) -{ - const MeshTopology &base_mesh_topology = topology_refiner_impl->base_mesh_topology; - - const int num_edges = base_mesh_topology.getNumEdges(); - for (int edge_index = 0; edge_index < num_edges; ++edge_index) { - const float current_sharpness = base_mesh_topology.getEdgeSharpness(edge_index); - const float requested_sharpness = getEffectiveEdgeSharpness(converter, edge_index); - - if (current_sharpness != requested_sharpness) { - return false; - } - } - - return true; -} - -// TODO(sergey): Make this function usable by factory as well. -float getEffectiveVertexSharpness(const OpenSubdiv_Converter *converter, const int vertex_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); - } - - return 0.0f; -} - -bool checkVertexSharpnessMatch(const TopologyRefinerImpl *topology_refiner_impl, - 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_mesh_topology.getVertexSharpness(vertex_index); - const float requested_sharpness = getEffectiveVertexSharpness(converter, vertex_index); - - if (current_sharpness != requested_sharpness) { - return false; - } - } - - return true; -} - bool checkSingleUVLayerMatch(const OpenSubdiv::Far::TopologyLevel &base_level, const OpenSubdiv_Converter *converter, const int layer_index) @@ -339,9 +279,10 @@ bool checkUVLayersMatch(const TopologyRefinerImpl *topology_refiner_impl, bool checkTopologyAttributesMatch(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter) { - return checkEdgeTagsMatch(topology_refiner_impl, converter) && - checkVertexSharpnessMatch(topology_refiner_impl, converter) && - checkUVLayersMatch(topology_refiner_impl, converter); + if (!topology_refiner_impl->base_mesh_topology.isEqualToConverter(converter)) { + return false; + } + return checkUVLayersMatch(topology_refiner_impl, converter); } } // namespace -- cgit v1.2.3