From 38b50fe3933d99daba6e4cee93b5317cf3220a2f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 26 May 2020 10:01:46 +0200 Subject: OpenSubdiv: Hide individual topology elements Move all API to happen via MeshTopology. This is a preparation for an upcoming memory optimization. --- .../opensubdiv/internal/topology/mesh_topology.cc | 57 ++++++---- .../opensubdiv/internal/topology/mesh_topology.h | 122 ++++++++++----------- .../internal/topology/mesh_topology_compare.cc | 12 +- .../internal/topology/topology_refiner_factory.cc | 12 +- 4 files changed, 109 insertions(+), 94 deletions(-) (limited to 'intern/opensubdiv/internal') diff --git a/intern/opensubdiv/internal/topology/mesh_topology.cc b/intern/opensubdiv/internal/topology/mesh_topology.cc index ae7c1e069b6..e4bd9ce5fb2 100644 --- a/intern/opensubdiv/internal/topology/mesh_topology.cc +++ b/intern/opensubdiv/internal/topology/mesh_topology.cc @@ -89,7 +89,7 @@ int MeshTopology::getNumEdges() const return num_edges_; } -void MeshTopology::setEdgevertexIndices(int edge_index, int v1, int v2) +void MeshTopology::setEdgeVertexIndices(int edge_index, int v1, int v2) { assert(edge_index >= 0); assert(edge_index < getNumEdges()); @@ -102,7 +102,7 @@ void MeshTopology::setEdgevertexIndices(int edge_index, int v1, int v2) ensureNumEdgesAtLeast(edge_index + 1); - EdgeTopology &edge = getEdge(edge_index); + Edge &edge = edges_[edge_index]; // Prevent attempts to override edges. // This is currently not supposed to happen. @@ -112,17 +112,23 @@ void MeshTopology::setEdgevertexIndices(int edge_index, int v1, int v2) edge.v2 = v2; } -EdgeTopology &MeshTopology::getEdge(int edge_index) +void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const { - const MeshTopology *const_this = this; - return const_cast(const_this->getEdge(edge_index)); + assert(edge_index >= 0); + assert(edge_index < getNumEdges()); + + const Edge &edge = edges_[edge_index]; + *v1 = edge.v1; + *v2 = edge.v2; } -const EdgeTopology &MeshTopology::getEdge(int edge_index) const + +bool MeshTopology::isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const { assert(edge_index >= 0); assert(edge_index < getNumEdges()); - return edges_[edge_index]; + const Edge &edge = edges_[edge_index]; + return edge.v1 == expected_v1 && edge.v2 == expected_v2; } void MeshTopology::setEdgeSharpness(int edge_index, float sharpness) @@ -130,7 +136,8 @@ void MeshTopology::setEdgeSharpness(int edge_index, float sharpness) assert(edge_index >= 0); assert(edge_index < getNumEdges()); - assert(getEdge(edge_index).isValid()); + Edge &edge = edges_[edge_index]; + assert(edge.isValid()); if (sharpness < 1e-6f) { return; @@ -183,30 +190,42 @@ int MeshTopology::getNumFaces() const return num_faces_; } -FaceTopology &MeshTopology::getFace(int face_index) -{ - const MeshTopology *const_this = this; - return const_cast(const_this->getFace(face_index)); -} -const FaceTopology &MeshTopology::getFace(int face_index) const +void MeshTopology::setNumFaceVertices(int face_index, int num_face_vertices) { assert(face_index >= 0); assert(face_index < getNumFaces()); - return faces_[face_index]; + Face &face = faces_[face_index]; + face.setNumVertices(num_face_vertices); } -void MeshTopology::setNumFaceVertices(int face_index, int num_face_vertices) +int MeshTopology::getNumFaceVertices(int face_index) const { - FaceTopology &face = getFace(face_index); - face.setNumVertices(num_face_vertices); + assert(face_index >= 0); + assert(face_index < getNumFaces()); + + const Face &face = faces_[face_index]; + return face.getNumVertices(); } void MeshTopology::setFaceVertexIndices(int face_index, int *face_vertex_indices) { - FaceTopology &face = getFace(face_index); + assert(face_index >= 0); + assert(face_index < getNumFaces()); + + Face &face = faces_[face_index]; face.setVertexIndices(face_vertex_indices); } +bool MeshTopology::isFaceVertexIndicesEqual(int face_index, + const vector &expected_vertices_of_face) const +{ + assert(face_index >= 0); + assert(face_index < getNumFaces()); + + const Face &face = faces_[face_index]; + return face.vertex_indices == expected_vertices_of_face; +} + } // namespace opensubdiv } // namespace blender diff --git a/intern/opensubdiv/internal/topology/mesh_topology.h b/intern/opensubdiv/internal/topology/mesh_topology.h index 196d79c87df..aef521fbd44 100644 --- a/intern/opensubdiv/internal/topology/mesh_topology.h +++ b/intern/opensubdiv/internal/topology/mesh_topology.h @@ -29,58 +29,6 @@ struct OpenSubdiv_Converter; namespace blender { namespace opensubdiv { -class VertexTopologyTag { - public: - float sharpness = 0.0f; -}; - -class EdgeTopology { - public: - bool isValid() const - { - return v1 >= 0 && v2 >= 0; - } - - int v1 = -1; - 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 vertex_indices; -}; - -class EdgeTopologyTag { - public: - float sharpness = 0.0f; -}; - // Simplified representation of mesh topology. // Only includes parts of actual mesh topology which is needed to perform // comparison between Application side and OpenSubddiv side. @@ -112,10 +60,10 @@ class MeshTopology { // on last edge index for which topology tag was specified. int getNumEdges() const; - void setEdgevertexIndices(int edge_index, int v1, int v2); + void setEdgeVertexIndices(int edge_index, int v1, int v2); + void getEdgeVertexIndices(int edge_index, int *v1, int *v2) const; - EdgeTopology &getEdge(int edge_index); - const EdgeTopology &getEdge(int edge_index) const; + bool isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const; void setEdgeSharpness(int edge_index, float sharpness); float getEdgeSharpness(int edge_index) const; @@ -127,12 +75,14 @@ class MeshTopology { int getNumFaces() const; - FaceTopology &getFace(int face_index); - const FaceTopology &getFace(int face_index) const; - void setNumFaceVertices(int face_index, int num_face_vertices); + int getNumFaceVertices(int face_index) const; + void setFaceVertexIndices(int face_index, int *face_vertex_indices); + bool isFaceVertexIndicesEqual(int face_index, + const vector &expected_vertices_of_face) const; + ////////////////////////////////////////////////////////////////////////////// // Comparison. @@ -152,15 +102,63 @@ class MeshTopology { void ensureVertexTagsSize(int num_vertices); void ensureEdgeTagsSize(int num_edges); + struct VertexTag { + float sharpness = 0.0f; + }; + + struct Edge { + bool isValid() const + { + return v1 >= 0 && v2 >= 0; + } + + int v1 = -1; + int v2 = -1; + }; + + struct EdgeTag { + float sharpness = 0.0f; + }; + + struct Face { + 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 vertex_indices; + }; + int num_vertices_; - vector vertex_tags_; + vector vertex_tags_; int num_edges_; - vector edges_; - vector edge_tags_; + vector edges_; + vector edge_tags_; int num_faces_; - vector faces_; + vector 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 0aa217ac711..fe30c3f43a5 100644 --- a/intern/opensubdiv/internal/topology/mesh_topology_compare.cc +++ b/intern/opensubdiv/internal/topology/mesh_topology_compare.cc @@ -75,9 +75,9 @@ bool isEqualGeometryEdge(const MeshTopology &mesh_topology, const OpenSubdiv_Con int requested_edge_vertices[2]; converter->getEdgeVertices(converter, edge_index, requested_edge_vertices); - const EdgeTopology ¤t_edge = mesh_topology.getEdge(edge_index); - if (current_edge.v1 != requested_edge_vertices[0] || - current_edge.v2 != requested_edge_vertices[1]) { + if (!mesh_topology.isEdgeEqual( + edge_index, requested_edge_vertices[0], requested_edge_vertices[1])) { + printf("edge mismatch\n"); return false; } } @@ -96,17 +96,15 @@ bool isEqualGeometryFace(const MeshTopology &mesh_topology, const OpenSubdiv_Con vector vertices_of_face; for (int face_index = 0; face_index < num_requested_faces; ++face_index) { - const FaceTopology ¤t_face = mesh_topology.getFace(face_index); - int num_face_vertices = converter->getNumFaceVertices(converter, face_index); - if (current_face.getNumVertices() != num_face_vertices) { + if (mesh_topology.getNumFaceVertices(face_index) != 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) { + if (!mesh_topology.isFaceVertexIndicesEqual(face_index, vertices_of_face)) { return false; } } diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc index c01cf158668..5a84c45101b 100644 --- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc +++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc @@ -52,7 +52,6 @@ template<> inline bool TopologyRefinerFactory::resizeComponentTopology( TopologyRefiner &refiner, const TopologyRefinerData &cb_data) { - using blender::opensubdiv::FaceTopology; using blender::opensubdiv::MeshTopology; const OpenSubdiv_Converter *converter = cb_data.converter; @@ -121,7 +120,6 @@ template<> inline bool TopologyRefinerFactory::assignComponentTopology( TopologyRefiner &refiner, const TopologyRefinerData &cb_data) { - using blender::opensubdiv::EdgeTopology; using blender::opensubdiv::MeshTopology; using Far::IndexArray; @@ -141,7 +139,7 @@ inline bool TopologyRefinerFactory::assignComponentTopology int edge_vertices[2]; converter->getEdgeVertices(converter, edge_index, edge_vertices); - base_mesh_topology->setEdgevertexIndices(edge_index, edge_vertices[0], edge_vertices[1]); + base_mesh_topology->setEdgeVertexIndices(edge_index, edge_vertices[0], edge_vertices[1]); } } @@ -185,10 +183,12 @@ inline bool TopologyRefinerFactory::assignComponentTopology const int num_edges = converter->getNumEdges(converter); for (int edge_index = 0; edge_index < num_edges; ++edge_index) { // Vertices this edge connects. - const EdgeTopology &edge = base_mesh_topology->getEdge(edge_index); + int v1, v2; + base_mesh_topology->getEdgeVertexIndices(edge_index, &v1, &v2); + IndexArray dst_edge_vertices = getBaseEdgeVertices(refiner, edge_index); - dst_edge_vertices[0] = edge.v1; - dst_edge_vertices[1] = edge.v2; + dst_edge_vertices[0] = v1; + dst_edge_vertices[1] = v2; // Faces adjacent to this edge. IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge_index); -- cgit v1.2.3