Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/opensubdiv/internal/topology/mesh_topology.cc91
-rw-r--r--intern/opensubdiv/internal/topology/mesh_topology.h41
-rw-r--r--intern/opensubdiv/internal/topology/topology_refiner_factory.cc4
-rw-r--r--intern/opensubdiv/internal/topology/topology_refiner_impl_compare.cc101
4 files changed, 147 insertions, 90 deletions
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);
- const int num_edges = base_level.GetNumEdges();
- // Create mapping for quick lookup of edge index from its vertices indices.
- //
- // TODO(sergey): Consider caching it in some sort of wrapper around topology
- // refiner.
- EdgeTagMap<int> edge_map;
+ const int num_edges = base_mesh_topology.getNumEdges();
for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
- ConstIndexArray edge_vertices = base_level.GetEdgeVertices(edge_index);
- edge_map.insert(edge_vertices[0], edge_vertices[1], edge_index);
- }
- // Compare all edges.
- for (int converter_edge_index = 0; converter_edge_index < num_edges; ++converter_edge_index) {
- // Get edge vertices indices, and lookup corresponding edge index in the
- // base topology level.
- int edge_vertices[2];
- converter->getEdgeVertices(converter, converter_edge_index, edge_vertices);
- const int base_level_edge_index = edge_map.at(edge_vertices[0], edge_vertices[1]);
- // Perform actual test.
- if (!checkSingleEdgeTagMatch(
- base_level, base_level_edge_index, converter, converter_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;
-}
-bool checkEdgeTagsMatch(const TopologyRefinerImpl *topology_refiner_impl,
- const OpenSubdiv_Converter *converter)
-{
- if (converter->specifiesFullTopology(converter)) {
- return checkEdgeTagsMatchFullTopology(topology_refiner_impl, converter);
- }
- else {
- return checkEdgeTagsMatchAutoOrient(topology_refiner_impl, converter);
- }
+ 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 &&
@@ -350,13 +284,14 @@ bool checkVertexSharpnessMatch(const TopologyRefinerImpl *topology_refiner_impl,
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.vertices[vertex_index].sharpness;
+ 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;
}