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:
Diffstat (limited to 'intern/opensubdiv')
-rw-r--r--intern/opensubdiv/internal/topology/topology_refiner_capi.cc72
-rw-r--r--intern/opensubdiv/internal/topology/topology_refiner_factory.cc26
-rw-r--r--intern/opensubdiv/internal/topology/topology_refiner_impl.h21
3 files changed, 67 insertions, 52 deletions
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
index 58c0ffbb7cf..8c3f8f1f896 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_capi.cc
@@ -22,6 +22,7 @@
#include "internal/base/edge_map.h"
#include "internal/base/type.h"
#include "internal/base/type_convert.h"
+#include "internal/topology/mesh_topology.h"
#include "internal/topology/topology_refiner_impl.h"
#include "opensubdiv_converter_capi.h"
@@ -553,55 +554,32 @@ bool checkEdgeTagsMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
}
}
-bool checkvertexSharpnessMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
- const OpenSubdiv_Converter *converter)
+float getEffectiveVertexSharpness(const OpenSubdiv_Converter *converter, const int vertex_index)
{
- using OpenSubdiv::Far::ConstIndexArray;
- using OpenSubdiv::Far::TopologyLevel;
- using OpenSubdiv::Sdc::Crease;
- const TopologyLevel &base_level = getOSDTopologyRefiner(topology_refiner)->GetLevel(0);
- // Create mapping for quick lookup of edge index from its vertices 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);
+ if (converter->isInfiniteSharpVertex != nullptr &&
+ converter->isInfiniteSharpVertex(converter, vertex_index)) {
+ return OpenSubdiv::Sdc::Crease::SHARPNESS_INFINITE;
+ }
+
+ if (converter->getVertexSharpness != nullptr) {
+ return converter->getVertexSharpness(converter, vertex_index);
}
- const int num_vertices = base_level.GetNumVertices();
+
+ return 0.0f;
+}
+
+bool checkVertexSharpnessMatch(const OpenSubdiv_TopologyRefiner *topology_refiner,
+ const OpenSubdiv_Converter *converter)
+{
+ const MeshTopology &base_mesh_topology = topology_refiner->impl->base_mesh_topology;
+
+ const int num_vertices = base_mesh_topology.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;
- }
+ const float current_sharpness = base_mesh_topology.vertices[vertex_index].sharpness;
+ const float requested_sharpness = getEffectiveVertexSharpness(converter, vertex_index);
+
+ if (current_sharpness != requested_sharpness) {
+ return false;
}
}
return true;
@@ -652,7 +630,7 @@ bool checkTopologyAttributesMatch(const OpenSubdiv_TopologyRefiner *topology_ref
const OpenSubdiv_Converter *converter)
{
return checkEdgeTagsMatch(topology_refiner, converter) &&
- checkvertexSharpnessMatch(topology_refiner, converter) &&
+ checkVertexSharpnessMatch(topology_refiner, converter) &&
checkUVLayersMatch(topology_refiner, converter);
}
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
index 1a51fce6e24..c9c72f18349 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
+++ b/intern/opensubdiv/internal/topology/topology_refiner_factory.cc
@@ -29,6 +29,8 @@
#include "internal/base/type.h"
#include "internal/base/type_convert.h"
+#include "internal/topology/mesh_topology.h"
+
#include "opensubdiv_converter_capi.h"
using blender::opensubdiv::min;
@@ -37,6 +39,7 @@ using blender::opensubdiv::vector;
struct TopologyRefinerData {
const OpenSubdiv_Converter *converter;
+ blender::opensubdiv::MeshTopology *base_mesh_topology;
};
typedef OpenSubdiv::Far::TopologyRefinerFactory<TopologyRefinerData> TopologyRefinerFactoryType;
@@ -49,7 +52,11 @@ template<>
inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology(
TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
{
+ using blender::opensubdiv::MeshTopology;
+
const OpenSubdiv_Converter *converter = cb_data.converter;
+ MeshTopology *base_mesh_topology = cb_data.base_mesh_topology;
+
// Faces and face-vertices.
const int num_faces = converter->getNumFaces(converter);
setNumBaseFaces(refiner, num_faces);
@@ -57,13 +64,17 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
const int num_face_vertices = converter->getNumFaceVertices(converter, face_index);
setNumBaseFaceVertices(refiner, face_index, num_face_vertices);
}
+
// Vertices.
const int num_vertices = converter->getNumVertices(converter);
+ base_mesh_topology->setNumVertices(num_vertices);
setNumBaseVertices(refiner, num_vertices);
+
// If converter does not provide full topology, we are done.
if (!converter->specifiesFullTopology(converter)) {
return true;
}
+
// Edges and edge-faces.
const int num_edges = converter->getNumEdges(converter);
setNumBaseEdges(refiner, num_edges);
@@ -71,6 +82,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
const int num_edge_faces = converter->getNumEdgeFaces(converter, edge_index);
setNumBaseEdgeFaces(refiner, edge_index, num_edge_faces);
}
+
// Vertex-faces and vertex-edges.
for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
const int num_vert_edges = converter->getNumVertexEdges(converter, vertex_index);
@@ -78,6 +90,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::resizeComponentTopology
setNumBaseVertexEdges(refiner, vertex_index, num_vert_edges);
setNumBaseVertexFaces(refiner, vertex_index, num_vert_faces);
}
+
return true;
}
@@ -137,8 +150,12 @@ template<>
inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
TopologyRefiner &refiner, const TopologyRefinerData &cb_data)
{
+ using blender::opensubdiv::MeshTopology;
using OpenSubdiv::Sdc::Crease;
+
const OpenSubdiv_Converter *converter = cb_data.converter;
+ MeshTopology *base_mesh_topology = cb_data.base_mesh_topology;
+
const bool full_topology_specified = converter->specifiesFullTopology(converter);
if (full_topology_specified || converter->getEdgeVertices != NULL) {
const int num_edges = converter->getNumEdges(converter);
@@ -151,6 +168,8 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
setBaseEdgeSharpness(refiner, edge_index, sharpness);
}
else {
+ // TODO(sergey): Should be a faster way to find reconstructed edge to
+ // specify sharpness for (assuming, findBaseEdge has linear complexity).
int edge_vertices[2];
converter->getEdgeVertices(converter, edge_index, edge_vertices);
const int base_edge_index = findBaseEdge(refiner, edge_vertices[0], edge_vertices[1]);
@@ -162,6 +181,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
}
}
}
+
// OpenSubdiv expects non-manifold vertices to be sharp but at the time it
// handles correct cases when vertex is a corner of plane. Currently mark
// vertices which are adjacent to a loose edge as sharp, but this decision
@@ -170,6 +190,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) {
ConstIndexArray vertex_edges = getBaseVertexEdges(refiner, vertex_index);
if (converter->isInfiniteSharpVertex(converter, vertex_index)) {
+ base_mesh_topology->setVertexSharpness(vertex_index, Crease::SHARPNESS_INFINITE);
setBaseVertexSharpness(refiner, vertex_index, Crease::SHARPNESS_INFINITE);
continue;
}
@@ -178,6 +199,7 @@ inline bool TopologyRefinerFactory<TopologyRefinerData>::assignComponentTags(
float sharpness = 0.0f;
if (converter->getVertexSharpness != NULL) {
sharpness = converter->getVertexSharpness(converter, vertex_index);
+ base_mesh_topology->setVertexSharpness(vertex_index, sharpness);
}
// If it's vertex where 2 non-manifold edges meet adjust vertex sharpness to
@@ -291,8 +313,11 @@ TopologyRefinerImpl *TopologyRefinerImpl::createFromConverter(
{
using OpenSubdiv::Far::TopologyRefiner;
+ blender::opensubdiv::MeshTopology base_mesh_topology;
+
TopologyRefinerData cb_data;
cb_data.converter = converter;
+ cb_data.base_mesh_topology = &base_mesh_topology;
// Create OpenSubdiv descriptor for the topology refiner.
TopologyRefinerFactoryType::Options topology_refiner_options = getTopologyRefinerOptions(
@@ -307,6 +332,7 @@ TopologyRefinerImpl *TopologyRefinerImpl::createFromConverter(
TopologyRefinerImpl *topology_refiner_impl = new TopologyRefinerImpl();
topology_refiner_impl->topology_refiner = topology_refiner;
topology_refiner_impl->settings = settings;
+ topology_refiner_impl->base_mesh_topology = move(base_mesh_topology);
return topology_refiner_impl;
}
diff --git a/intern/opensubdiv/internal/topology/topology_refiner_impl.h b/intern/opensubdiv/internal/topology/topology_refiner_impl.h
index 5232e97b24b..4a6e6c0fcec 100644
--- a/intern/opensubdiv/internal/topology/topology_refiner_impl.h
+++ b/intern/opensubdiv/internal/topology/topology_refiner_impl.h
@@ -26,6 +26,7 @@
#include <opensubdiv/far/topologyRefiner.h>
#include "internal/base/memory.h"
+#include "internal/topology/mesh_topology.h"
#include "opensubdiv_topology_refiner_capi.h"
struct OpenSubdiv_Converter;
@@ -46,13 +47,23 @@ class TopologyRefinerImpl {
OpenSubdiv::Far::TopologyRefiner *topology_refiner;
// Subdivision settingsa this refiner is created for.
+ OpenSubdiv_TopologyRefinerSettings settings;
+
+ // Topology of the mesh which corresponds to the base level.
//
- // We store it here since OpenSubdiv's refiner will only know about level and
- // "adaptivity" after performing actual "refine" step.
+ // All the indices and values are kept exactly the same as user-defined
+ // converter provided them. This allows to easily compare values which might
+ // be touched by the refinement process.
//
- // Ideally, we would also support refining topology without re-importing it
- // from external world, but that is for later.
- OpenSubdiv_TopologyRefinerSettings settings;
+ // On a more technical note this allows to easier/faster to compare following
+ // things:
+ //
+ // - Face vertices, where OpenSubdiv could re-arrange them to keep winding
+ // uniform.
+ //
+ // - Vertex crease where OpenSubdiv will force crease for non-manifold or
+ // corner vertices.
+ MeshTopology base_mesh_topology;
MEM_CXX_CLASS_ALLOC_FUNCS("TopologyRefinerImpl");
};