Fix T63030: Edge crease is not applied for boundary edges

Caused by missing vertex sharpness comparison in the topology
comparator.
This commit is contained in:
Sergey Sharybin 2019-03-28 11:48:22 +01:00
parent 33b43dd933
commit 9d1cab2eba
1 changed files with 57 additions and 1 deletions

View File

@ -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<int> 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);
}