OpenSubdiv: Refactor, move mesh topology comparison to own file
Makes it easier to follow and extend.
This commit is contained in:
parent
ece54172d0
commit
6a8193e505
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <cassert>
|
||||
#include <opensubdiv/sdc/crease.h>
|
||||
|
||||
#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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue