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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-01-16 12:21:31 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-01-16 13:00:43 +0300
commit6ae72d2d41a30bf96e425656bbca166287a5f359 (patch)
treef48b896238ee7962c8221f3f36d1b407568b0a23 /intern/opensubdiv
parent7eda267df1a997c1525a0aa62ad2de2f1b77c6e5 (diff)
OpenSubdiv: Remove topology orientation code
It is no longer used and has some issues in corner cases which are not handled in a way which OpenSubdiv expects.
Diffstat (limited to 'intern/opensubdiv')
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.cc199
-rw-r--r--intern/opensubdiv/internal/opensubdiv_internal.h5
2 files changed, 0 insertions, 204 deletions
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
index df78e12104d..0e8af7b8cdb 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
@@ -119,70 +119,6 @@ TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology(
IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge_index);
converter->getEdgeFaces(converter, edge_index, &dst_edge_faces[0]);
}
- // TODO(sergey): Find a way to move this to an utility function.
-#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
- // Make face normals consistent.
- vector<bool> face_used(num_faces, false);
- stack<int> traverse_stack;
- int face_start = 0, num_traversed_faces = 0;
- // Traverse all islands.
- while (num_traversed_faces != num_faces) {
- // Find first face of any untraversed islands.
- while (face_used[face_start]) {
- ++face_start;
- }
- // Add first face to the stack.
- traverse_stack.push(face_start);
- face_used[face_start] = true;
- // Go over whole connected component.
- while (!traverse_stack.empty()) {
- int face = traverse_stack.top();
- traverse_stack.pop();
- IndexArray face_edges = getBaseFaceEdges(refiner, face);
- ConstIndexArray face_vertices = getBaseFaceVertices(refiner, face);
- for (int i = 0; i < face_edges.size(); ++i) {
- const int edge = face_edges[i];
- ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge);
- if (edge_faces.size() != 2) {
- /* Can't make consistent normals for non-manifolds. */
- continue;
- }
- ConstIndexArray edge_vertices = getBaseEdgeVertices(refiner, edge);
- // Get winding of the reference face.
- const int vert0_of_face = face_vertices.FindIndex(edge_vertices[0]);
- const int vert1_of_face = face_vertices.FindIndex(edge_vertices[1]);
- const int delta_face =
- opensubdiv_capi::getLoopWinding(vert0_of_face, vert1_of_face);
- for (int edge_face = 0; edge_face < edge_faces.size(); ++edge_face) {
- const int other_face_index = edge_faces[edge_face];
- // Never re-traverse faces, only move forward.
- if (face_used[other_face_index]) {
- continue;
- }
- IndexArray other_face_vertics =
- getBaseFaceVertices(refiner, other_face_index);
- const int vert0_of_other_face =
- other_face_vertics.FindIndex(edge_vertices[0]);
- const int vert1_of_other_face =
- other_face_vertics.FindIndex(edge_vertices[1]);
- const int delta_other_face = opensubdiv_capi::getLoopWinding(
- vert0_of_other_face, vert1_of_other_face);
- if (delta_face * delta_other_face > 0) {
- IndexArray other_face_vertices =
- getBaseFaceVertices(refiner, other_face_index);
- IndexArray other_face_edges =
- getBaseFaceEdges(refiner, other_face_index);
- opensubdiv_capi::reverseFaceLoops(&other_face_vertices,
- &other_face_edges);
- }
- traverse_stack.push(other_face_index);
- face_used[other_face_index] = true;
- }
- }
- ++num_traversed_faces;
- }
- }
-#endif // OPENSUBDIV_ORIENT_TOPOLOGY
// Vertex relations.
const int num_vertices = converter->getNumVertices(converter);
vector<int> vertex_faces, vertex_edges;
@@ -199,145 +135,10 @@ TopologyRefinerFactory<TopologyRefinerData>::assignComponentTopology(
converter->getNumVertexEdges(converter, vertex_index);
vertex_edges.resize(num_vertex_edges);
converter->getVertexEdges(converter, vertex_index, &vertex_edges[0]);
-// TODO(sergey): Find a way to move this to an utility function.
-#ifdef OPENSUBDIV_ORIENT_TOPOLOGY
- // Order vertex edges and faces to be in a CCW order.
- fill(face_used.begin(), face_used.end(), false);
- // Number of edges and faces added to the ordered array.
- int edge_count_ordered = 0, face_count_ordered = 0;
- // Add loose edges straight into the edges array.
- bool has_fan_connections = false;
- for (int i = 0; i < num_vertex_edges; ++i) {
- IndexArray edge_faces = getBaseEdgeFaces(refiner, vertex_edges[i]);
- if (edge_faces.size() == 0) {
- dst_vertex_edges[edge_count_ordered++] = vertex_edges[i];
- } else if (edge_faces.size() > 2) {
- has_fan_connections = true;
- }
- }
- if (has_fan_connections) {
- // OpenSubdiv currently doesn't give us clues how to handle fan face
- // connections. and since handling such connections complicates the loop
- // below we simply don't do special orientation for them.
- memcpy(&dst_vertex_edges[0], &vertex_edges[0],
- sizeof(int) * num_vertex_edges);
- memcpy(&dst_vertex_faces[0], &vertex_faces[0],
- sizeof(int) * num_vertex_faces);
- continue;
- }
- // Perform at max numbder of vert-edges iteration and try to avoid
- // deadlock here for malformed mesh.
- for (int global_iter = 0; global_iter < num_vertex_edges; ++global_iter) {
- // Number of edges and faces which are still to be ordered.
- const int num_vertex_edges_remained =
- num_vertex_edges - edge_count_ordered;
- const int num_vertex_faces_remained =
- num_vertex_faces - face_count_ordered;
- if (num_vertex_edges_remained == 0 && num_vertex_faces_remained == 0) {
- // All done, nothing to do anymore.
- break;
- }
- // Face, edge and face-vertex index to start traversal from.
- int face_start = -1, edge_start = -1, face_vertex_start = -1;
- if (num_vertex_edges_remained == num_vertex_faces_remained) {
- // Vertex is either complete manifold or is connected to several
- // manifold islands (hourglass-like configuration), can pick up
- // random edge unused and start from it.
- //
- // TODO(sergey): Start from previous edge from which traversal began at
- // previous iteration.
- for (int i = 0; i < num_vertex_edges; ++i) {
- face_start = vertex_faces[i];
- if (!face_used[face_start]) {
- ConstIndexArray face_vertices =
- getBaseFaceVertices(refiner, face_start);
- ConstIndexArray face_edges = getBaseFaceEdges(refiner, face_start);
- face_vertex_start = face_vertices.FindIndex(vertex_index);
- edge_start = face_edges[face_vertex_start];
- break;
- }
- }
- } else {
- // Special handle of non-manifold vertex.
- for (int i = 0; i < num_vertex_edges; ++i) {
- edge_start = vertex_edges[i];
- IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_start);
- if (edge_faces.size() == 1) {
- face_start = edge_faces[0];
- if (!face_used[face_start]) {
- ConstIndexArray face_vertices =
- getBaseFaceVertices(refiner, face_start);
- ConstIndexArray face_edges =
- getBaseFaceEdges(refiner, face_start);
- face_vertex_start = face_vertices.FindIndex(vertex_index);
- if (edge_start == face_edges[face_vertex_start]) {
- break;
- }
- }
- }
- // Reset indices for sanity check below.
- face_start = edge_start = face_vertex_start = -1;
- }
- }
- // Sanity check.
- assert(face_start != -1);
- assert(edge_start != -1);
- assert(face_vertex_start != -1);
- // Traverse faces starting from the current one. */
- int edge_first = edge_start;
- dst_vertex_faces[face_count_ordered++] = face_start;
- dst_vertex_edges[edge_count_ordered++] = edge_start;
- face_used[face_start] = true;
- while (edge_count_ordered < num_vertex_edges) {
- IndexArray face_vertices = getBaseFaceVertices(refiner, face_start);
- IndexArray face_edges = getBaseFaceEdges(refiner, face_start);
- int face_edge_start = face_vertex_start;
- int face_edge_next = (face_edge_start > 0) ? (face_edge_start - 1)
- : (face_vertices.size() - 1);
- Index edge_next = face_edges[face_edge_next];
- if (edge_next == edge_first) {
- // Multiple manifolds found, stop for now and handle rest
- // in the next iteration.
- break;
- }
- dst_vertex_edges[edge_count_ordered++] = edge_next;
- if (face_count_ordered < num_vertex_faces) {
- IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_next);
- assert(edge_faces.size() != 0);
- if (edge_faces.size() == 1) {
- assert(edge_faces[0] == face_start);
- break;
- } else if (edge_faces.size() != 2) {
- break;
- }
- assert(edge_faces.size() == 2);
- face_start = edge_faces[(edge_faces[0] == face_start) ? 1 : 0];
- face_vertex_start =
- getBaseFaceEdges(refiner, face_start).FindIndex(edge_next);
- dst_vertex_faces[face_count_ordered++] = face_start;
- face_used[face_start] = true;
- }
- edge_start = edge_next;
- }
- }
- // Verify ordering doesn't ruin connectivity information.
- assert(face_count_ordered == num_vertex_faces);
- assert(edge_count_ordered == num_vertex_edges);
- opensubdiv_capi::checkOrientedVertexConnectivity(
- num_vertex_edges, num_vertex_faces, &vertex_edges[0], &vertex_faces[0],
- &dst_vertex_edges[0], &dst_vertex_faces[0]);
- // For the release builds we're failing mesh construction so instead of
- // nasty bugs the unsupported mesh will simply disappear from the viewport.
- if (face_count_ordered != num_vertex_faces ||
- edge_count_ordered != num_vertex_edges) {
- return false;
- }
-#else // OPENSUBDIV_ORIENT_TOPOLOGY
memcpy(&dst_vertex_edges[0], &vertex_edges[0],
sizeof(int) * num_vertex_edges);
memcpy(&dst_vertex_faces[0], &vertex_faces[0],
sizeof(int) * num_vertex_faces);
-#endif // OPENSUBDIV_ORIENT_TOPOLOGY
}
populateBaseLocalIndices(refiner);
return true;
diff --git a/intern/opensubdiv/internal/opensubdiv_internal.h b/intern/opensubdiv/internal/opensubdiv_internal.h
index 16365896edf..1ddf199c013 100644
--- a/intern/opensubdiv/internal/opensubdiv_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_internal.h
@@ -27,9 +27,4 @@
# define OPENSUBDIV_VALIDATE_TOPOLOGY
#endif
-// Currently OpenSubdiv expects topology to be oriented, but sometimes it's
-// handy to disable orientation code to check whether it causes some weird
-// issues by using pre-oriented model.
-#define OPENSUBDIV_ORIENT_TOPOLOGY
-
#endif // OPENSUBDIV_INTERNAL_H_