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>2020-03-19 12:41:43 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2020-03-19 13:59:45 +0300
commit317a9cf83575e71255c9b706a63b477c7f5f55de (patch)
treea30759bb162827965a84f8f080664894073df152 /source/blender/blenkernel/intern/multires_reshape_smooth.c
parent6e39445f80bea7abf19c9a82d0dcc3cc3dddc7d2 (diff)
Multires: Subdiv, properly support base edge crease
The title says it all actually. The test case is to get default cube, set some edges to non-zero crease, add multires modifier and hit the "Subdivide" button few times. The memory footprint might be optimized by not storing information about inner generated edges.
Diffstat (limited to 'source/blender/blenkernel/intern/multires_reshape_smooth.c')
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index 2f57b5fc569..1fbd1832d0c 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -32,6 +32,7 @@
#include "BLI_task.h"
#include "BLI_utildefines.h"
+#include "BKE_customdata.h"
#include "BKE_multires.h"
#include "BKE_subdiv.h"
#include "BKE_subdiv_eval.h"
@@ -72,6 +73,13 @@ typedef struct Face {
int num_corners;
} Face;
+typedef struct Edge {
+ int v1;
+ int v2;
+
+ float sharpness;
+} Edge;
+
typedef struct MultiresReshapeSmoothContext {
const MultiresReshapeContext *reshape_context;
@@ -80,6 +88,9 @@ typedef struct MultiresReshapeSmoothContext {
int num_vertices;
Vertex *vertices;
+ int num_edges;
+ Edge *edges;
+
int num_corners;
Corner *corners;
@@ -372,6 +383,8 @@ static void context_init(MultiresReshapeSmoothContext *reshape_smooth_context,
reshape_smooth_context->geometry.num_vertices = 0;
reshape_smooth_context->geometry.vertices = NULL;
+ reshape_smooth_context->geometry.num_edges = 0;
+ reshape_smooth_context->geometry.edges = NULL;
reshape_smooth_context->geometry.num_corners = 0;
reshape_smooth_context->geometry.corners = NULL;
reshape_smooth_context->geometry.num_faces = 0;
@@ -391,6 +404,7 @@ static void context_free_geometry(MultiresReshapeSmoothContext *reshape_smooth_c
MEM_SAFE_FREE(reshape_smooth_context->geometry.vertices);
MEM_SAFE_FREE(reshape_smooth_context->geometry.corners);
MEM_SAFE_FREE(reshape_smooth_context->geometry.faces);
+ MEM_SAFE_FREE(reshape_smooth_context->geometry.edges);
}
static void context_free_subdiv(MultiresReshapeSmoothContext *reshape_smooth_context)
@@ -410,7 +424,7 @@ static void context_free(MultiresReshapeSmoothContext *reshape_smooth_context)
static bool foreach_topology_info(const SubdivForeachContext *foreach_context,
const int num_vertices,
- const int UNUSED(num_edges),
+ const int num_edges,
const int num_loops,
const int num_polygons)
{
@@ -421,6 +435,10 @@ static bool foreach_topology_info(const SubdivForeachContext *foreach_context,
reshape_smooth_context->geometry.vertices = MEM_calloc_arrayN(
sizeof(Vertex), num_vertices, "smooth vertices");
+ reshape_smooth_context->geometry.num_edges = num_edges;
+ reshape_smooth_context->geometry.edges = MEM_malloc_arrayN(
+ sizeof(Edge), num_edges, "smooth edges");
+
reshape_smooth_context->geometry.num_corners = num_loops;
reshape_smooth_context->geometry.corners = MEM_malloc_arrayN(
sizeof(Corner), num_loops, "smooth corners");
@@ -603,6 +621,30 @@ static void foreach_vertex_of_loose_edge(const struct SubdivForeachContext *fore
}
}
+void foreach_edge(const struct SubdivForeachContext *foreach_context,
+ void *tls,
+ const int coarse_edge_index,
+ const int subdiv_edge_index,
+ const int subdiv_v1,
+ const int subdiv_v2)
+{
+ const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data;
+ const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
+
+ Edge *edge = &reshape_smooth_context->geometry.edges[subdiv_edge_index];
+ edge->v1 = subdiv_v1;
+ edge->v2 = subdiv_v2;
+
+ if (coarse_edge_index == ORIGINDEX_NONE) {
+ edge->sharpness = 0.0f;
+ return;
+ }
+
+ const Mesh *base_mesh = reshape_context->base_mesh;
+ const MEdge *base_edge = &base_mesh->medge[coarse_edge_index];
+ edge->sharpness = BKE_subdiv_edge_crease_to_sharpness_char(base_edge->crease);
+}
+
static void geometry_create(MultiresReshapeSmoothContext *reshape_smooth_context)
{
const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
@@ -615,6 +657,7 @@ static void geometry_create(MultiresReshapeSmoothContext *reshape_smooth_context
.loop = foreach_loop,
.poly = foreach_poly,
.vertex_of_loose_edge = foreach_vertex_of_loose_edge,
+ .edge = foreach_edge,
.user_data = reshape_smooth_context,
};
@@ -697,10 +740,33 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter,
}
}
+static int get_num_edges(const struct OpenSubdiv_Converter *converter)
+{
+ const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data;
+ return reshape_smooth_context->geometry.num_edges;
+}
+
+static void get_edge_vertices(const OpenSubdiv_Converter *converter,
+ const int edge_index,
+ int edge_vertices[2])
+{
+ const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data;
+ const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index];
+ edge_vertices[0] = edge->v1;
+ edge_vertices[1] = edge->v2;
+}
+
+static float get_edge_sharpness(const OpenSubdiv_Converter *converter, const int edge_index)
+{
+ const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data;
+ const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index];
+ return edge->sharpness;
+}
+
static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, int vertex_index)
{
const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data;
- Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index];
+ const Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index];
return vertex->is_infinite_sharp;
}
@@ -714,17 +780,17 @@ static void converter_init(const MultiresReshapeSmoothContext *reshape_smooth_co
converter->specifiesFullTopology = specifies_full_topology;
converter->getNumFaces = get_num_faces;
- converter->getNumEdges = NULL;
+ converter->getNumEdges = get_num_edges;
converter->getNumVertices = get_num_vertices;
converter->getNumFaceVertices = get_num_face_vertices;
converter->getFaceVertices = get_face_vertices;
converter->getFaceEdges = NULL;
- converter->getEdgeVertices = NULL;
+ converter->getEdgeVertices = get_edge_vertices;
converter->getNumEdgeFaces = NULL;
converter->getEdgeFaces = NULL;
- converter->getEdgeSharpness = NULL;
+ converter->getEdgeSharpness = get_edge_sharpness;
converter->getNumVertexEdges = NULL;
converter->getVertexEdges = NULL;