diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-01-16 12:21:31 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-01-16 13:00:43 +0300 |
commit | 6ae72d2d41a30bf96e425656bbca166287a5f359 (patch) | |
tree | f48b896238ee7962c8221f3f36d1b407568b0a23 /intern/opensubdiv/internal | |
parent | 7eda267df1a997c1525a0aa62ad2de2f1b77c6e5 (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/internal')
-rw-r--r-- | intern/opensubdiv/internal/opensubdiv_converter_factory.cc | 199 | ||||
-rw-r--r-- | intern/opensubdiv/internal/opensubdiv_internal.h | 5 |
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_ |