From 9d1cab2eba0a839ce965de40eaedec8f6dc45276 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 28 Mar 2019 11:48:22 +0100 Subject: Fix T63030: Edge crease is not applied for boundary edges Caused by missing vertex sharpness comparison in the topology comparator. --- .../internal/opensubdiv_topology_refiner.cc | 58 +++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'intern/opensubdiv') diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc index b31146a644e..c77ddc49df7 100644 --- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc @@ -548,6 +548,61 @@ bool checkEdgeTagsMatch( } } +bool checkvertexSharpnessMatch( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + using OpenSubdiv::Far::ConstIndexArray; + using OpenSubdiv::Far::TopologyLevel; + using OpenSubdiv::Sdc::Crease; + const TopologyLevel& base_level = topology_refiner->GetLevel(0); + // Create mapping for quick lookup of edge index from its verticies indices. + // + // TODO(sergey): Consider caching it in some sort of wrapper around topology + // refiner. + const int num_edges = base_level.GetNumEdges(); + EdgeTagMap edge_map; + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + int edge_vertices[2]; + converter->getEdgeVertices(converter, edge_index, edge_vertices); + edge_map.insert(edge_vertices[0], edge_vertices[1], edge_index); + } + const int num_vertices = base_level.GetNumVertices(); + for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { + const float current_sharpness = base_level.GetVertexSharpness(vertex_index); + if (converter->isInfiniteSharpVertex(converter, vertex_index)) { + if (current_sharpness != Crease::SHARPNESS_INFINITE) { + return false; + } + } else { + ConstIndexArray vertex_edges = base_level.GetVertexEdges(vertex_index); + float sharpness = converter->getVertexSharpness(converter, vertex_index); + if (vertex_edges.size() == 2) { + const int edge0 = vertex_edges[0], edge1 = vertex_edges[1]; + // Construct keys for lookup. + ConstIndexArray edge0_vertices = base_level.GetEdgeVertices(edge0); + ConstIndexArray edge1_vertices = base_level.GetEdgeVertices(edge1); + EdgeKey edge0_key(edge0_vertices[0], edge0_vertices[1]); + EdgeKey edge1_key(edge1_vertices[0], edge1_vertices[1]); + // Lookup edge indices in the converter. + const int edge0_converter_index = edge_map[edge0_key]; + const int edge1_converter_index = edge_map[edge1_key]; + // Lookup sharpness. + const float sharpness0 = converter->getEdgeSharpness( + converter, edge0_converter_index); + const float sharpness1 = converter->getEdgeSharpness( + converter, edge1_converter_index); + // TODO(sergey): Find a better mixing between edge and vertex sharpness. + sharpness += min(sharpness0, sharpness1); + sharpness = min(sharpness, 10.0f); + } + if (sharpness != current_sharpness) { + return false; + } + } + } + return true; +} + bool checkSingleUVLayerMatch( const OpenSubdiv::Far::TopologyLevel& base_level, const OpenSubdiv_Converter* converter, @@ -578,7 +633,7 @@ bool checkUVLayersMatch( using OpenSubdiv::Far::TopologyLevel; const int num_layers = converter->getNumUVLayers(converter); const TopologyLevel& base_level = topology_refiner->GetLevel(0); - // Number of UF layers should match. + // Number of UV layers should match. if (base_level.GetNumFVarChannels() != num_layers) { return false; } @@ -594,6 +649,7 @@ bool checkTopologyAttributesMatch( const OpenSubdiv::Far::TopologyRefiner* topology_refiner, const OpenSubdiv_Converter* converter) { return checkEdgeTagsMatch(topology_refiner, converter) && + checkvertexSharpnessMatch(topology_refiner, converter) && checkUVLayersMatch(topology_refiner, converter); } -- cgit v1.2.3