OpenSubdiv: Hide individual topology elements
Move all API to happen via MeshTopology. This is a preparation for an upcoming memory optimization.
This commit is contained in:
parent
15bcfc5b19
commit
38b50fe393
@ -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)
|
||||
{
|
||||
const MeshTopology *const_this = this;
|
||||
return const_cast<EdgeTopology &>(const_this->getEdge(edge_index));
|
||||
}
|
||||
const EdgeTopology &MeshTopology::getEdge(int edge_index) const
|
||||
void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
|
||||
{
|
||||
assert(edge_index >= 0);
|
||||
assert(edge_index < getNumEdges());
|
||||
|
||||
return edges_[edge_index];
|
||||
const Edge &edge = edges_[edge_index];
|
||||
*v1 = edge.v1;
|
||||
*v2 = edge.v2;
|
||||
}
|
||||
|
||||
bool MeshTopology::isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const
|
||||
{
|
||||
assert(edge_index >= 0);
|
||||
assert(edge_index < getNumEdges());
|
||||
|
||||
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<FaceTopology &>(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<int> &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
|
||||
|
@ -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<int> 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<int> &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<int> vertex_indices;
|
||||
};
|
||||
|
||||
int num_vertices_;
|
||||
vector<VertexTopologyTag> vertex_tags_;
|
||||
vector<VertexTag> vertex_tags_;
|
||||
|
||||
int num_edges_;
|
||||
vector<EdgeTopology> edges_;
|
||||
vector<EdgeTopologyTag> edge_tags_;
|
||||
vector<Edge> edges_;
|
||||
vector<EdgeTag> edge_tags_;
|
||||
|
||||
int num_faces_;
|
||||
vector<FaceTopology> faces_;
|
||||
vector<Face> faces_;
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("MeshTopology");
|
||||
};
|
||||
|
@ -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<int> 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;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ template<>
|
||||
inline bool TopologyRefinerFactory<TopologyRefinerData>::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<TopologyRefinerData>::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<TopologyRefinerData>::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<TopologyRefinerData>::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);
|
||||
|
Loading…
Reference in New Issue
Block a user