diff options
Diffstat (limited to 'source/blender/blenkernel')
7 files changed, 104 insertions, 35 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 0237661cd16..697b3e9ace7 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -306,8 +306,8 @@ BLI_INLINE void BKE_subdiv_rotate_grid_to_quad( int corner, float grid_u, float grid_v, float *r_quad_u, float *r_quad_v); /* Convert Blender edge crease value to OpenSubdiv sharpness. */ -BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_f(float edge_crease); -BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease); +BLI_INLINE float BKE_subdiv_crease_to_sharpness_f(float edge_crease); +BLI_INLINE float BKE_subdiv_crease_to_sharpness_char(char edge_crease); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index feb5ecb8f04..e1bc025efd2 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -1692,7 +1692,9 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 29: CD_BWEIGHT */ {sizeof(float), "", 0, N_("BevelWeight"), nullptr, nullptr, layerInterp_bweight}, /* 30: CD_CREASE */ - {sizeof(float), "", 0, N_("SubSurfCrease"), nullptr, nullptr, layerInterp_bweight}, + /* NOTE: we do not interpolate crease data as it should be either inherited for subdivided + * edges, or for vertex creases, only present on the original vertex. */ + {sizeof(float), "", 0, N_("SubSurfCrease"), nullptr, nullptr, nullptr}, /* 31: CD_ORIGSPACE_MLOOP */ {sizeof(OrigSpaceLoop), "OrigSpaceLoop", @@ -1938,7 +1940,7 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { }; const CustomData_MeshMasks CD_MASK_MESH = { /* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | - CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR), + CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ @@ -1950,7 +1952,7 @@ const CustomData_MeshMasks CD_MASK_MESH = { }; const CustomData_MeshMasks CD_MASK_EDITMESH = { /* vmask */ (CD_MASK_MDEFORMVERT | CD_MASK_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | - CD_MASK_SHAPE_KEYINDEX | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR), + CD_MASK_SHAPE_KEYINDEX | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), /* emask */ (CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ (CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), @@ -1961,7 +1963,7 @@ const CustomData_MeshMasks CD_MASK_EDITMESH = { const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR), + CD_MASK_PROP_COLOR | CD_MASK_CREASE), /* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT), /* pmask */ @@ -1974,7 +1976,7 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { const CustomData_MeshMasks CD_MASK_BMESH = { /* vmask */ (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR), + CD_MASK_PROP_COLOR | CD_MASK_CREASE), /* emask */ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ @@ -2001,7 +2003,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { /* vmask */ (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_NORMAL | CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | - CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR), + CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), @@ -4409,7 +4411,12 @@ bool CustomData_verify_versions(struct CustomData *data, int index) /* 0 structnum is used in writing code to tag layer types that should not be written. */ else if (typeInfo->structnum == 0 && /* XXX Not sure why those three are exception, maybe that should be fixed? */ - !ELEM(layer->type, CD_PAINT_MASK, CD_FACEMAP, CD_MTEXPOLY, CD_SCULPT_FACE_SETS)) { + !ELEM(layer->type, + CD_PAINT_MASK, + CD_FACEMAP, + CD_MTEXPOLY, + CD_SCULPT_FACE_SETS, + CD_CREASE)) { keeplayer = false; CLOG_WARN(&LOG, ".blend file read: removing a data layer that should not have been written"); } @@ -5080,6 +5087,10 @@ void CustomData_blend_write(BlendWriter *writer, const bool *layer_data = static_cast<const bool *>(layer->data); BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); } + else if (layer->type == CD_CREASE) { + const float *layer_data = static_cast<const float *>(layer->data); + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } else { const char *structname; int structnum; diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h index 8a37d0ea785..a038ce5f108 100644 --- a/source/blender/blenkernel/intern/multires_reshape.h +++ b/source/blender/blenkernel/intern/multires_reshape.h @@ -106,6 +106,9 @@ typedef struct MultiresReshapeContext { /* Indexed by base face index, returns first ptex face index corresponding * to that base face. */ int *face_ptex_offset; + + /* Vertex crease custom data layer, null if none is present. */ + const float *cd_vertex_crease; } MultiresReshapeContext; /** diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c index 50b4410a28e..839c457dd84 100644 --- a/source/blender/blenkernel/intern/multires_reshape_smooth.c +++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c @@ -75,6 +75,7 @@ typedef struct Vertex { int num_grid_coords; GridCoord *grid_coords; + float sharpness; bool is_infinite_sharp; } Vertex; @@ -489,19 +490,33 @@ static int get_reshape_level_resolution(const MultiresReshapeContext *reshape_co return (1 << reshape_context->reshape.level) + 1; } +static bool is_crease_supported(const MultiresReshapeSmoothContext *reshape_smooth_context) +{ + return !ELEM(reshape_smooth_context->smoothing_type, + MULTIRES_SUBDIVIDE_LINEAR, + MULTIRES_SUBDIVIDE_SIMPLE); +} + /* Get crease which will be used for communication to OpenSubdiv topology. * Note that simple subdivision treats all base edges as infinitely sharp. */ -static char get_effective_edge_crease_char( - const MultiresReshapeSmoothContext *reshape_smooth_context, const MEdge *base_edge) +static char get_effective_crease_char(const MultiresReshapeSmoothContext *reshape_smooth_context, + const MEdge *base_edge) { - if (ELEM(reshape_smooth_context->smoothing_type, - MULTIRES_SUBDIVIDE_LINEAR, - MULTIRES_SUBDIVIDE_SIMPLE)) { + if (!is_crease_supported(reshape_smooth_context)) { return 255; } return base_edge->crease; } +static float get_effective_crease_float(const MultiresReshapeSmoothContext *reshape_smooth_context, + const float crease) +{ + if (!is_crease_supported(reshape_smooth_context)) { + return 1.0f; + } + return crease; +} + static void context_init(MultiresReshapeSmoothContext *reshape_smooth_context, const MultiresReshapeContext *reshape_context, const eMultiresSubdivideModeType mode) @@ -596,6 +611,7 @@ static bool foreach_topology_info(const SubdivForeachContext *foreach_context, static void foreach_single_vertex(const SubdivForeachContext *foreach_context, const GridCoord *grid_coord, + const int coarse_vertex_index, const int subdiv_vertex_index) { const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; @@ -608,11 +624,32 @@ static void foreach_single_vertex(const SubdivForeachContext *foreach_context, sizeof(Vertex) * (vertex->num_grid_coords + 1)); vertex->grid_coords[vertex->num_grid_coords] = *grid_coord; ++vertex->num_grid_coords; + + if (coarse_vertex_index == -1) { + return; + } + + const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; + const float *cd_vertex_crease = reshape_context->cd_vertex_crease; + + if (cd_vertex_crease == NULL) { + return; + } + + float crease = cd_vertex_crease[coarse_vertex_index]; + + if (crease == 0.0f) { + return; + } + + crease = get_effective_crease_float(reshape_smooth_context, crease); + vertex->sharpness = BKE_subdiv_crease_to_sharpness_f(crease); } /* TODO(sergey): De-duplicate with similar function in multires_reshape_vertcos.c */ static void foreach_vertex(const SubdivForeachContext *foreach_context, const PTexCoord *ptex_coord, + const int coarse_vertex_index, const int subdiv_vertex_index) { const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; @@ -632,12 +669,13 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context, for (int current_corner = 0; current_corner < num_corners; ++current_corner) { GridCoord corner_grid_coord = grid_coord; corner_grid_coord.grid_index = start_grid_index + current_corner; - foreach_single_vertex(foreach_context, &corner_grid_coord, subdiv_vertex_index); + foreach_single_vertex( + foreach_context, &corner_grid_coord, coarse_vertex_index, subdiv_vertex_index); } return; } - foreach_single_vertex(foreach_context, &grid_coord, subdiv_vertex_index); + foreach_single_vertex(foreach_context, &grid_coord, coarse_vertex_index, subdiv_vertex_index); if (grid_coord.u == 0.0f) { GridCoord prev_grid_coord; @@ -645,7 +683,8 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context, prev_grid_coord.u = grid_coord.v; prev_grid_coord.v = 0.0f; - foreach_single_vertex(foreach_context, &prev_grid_coord, subdiv_vertex_index); + foreach_single_vertex( + foreach_context, &prev_grid_coord, coarse_vertex_index, subdiv_vertex_index); } if (grid_coord.v == 0.0f) { @@ -654,7 +693,8 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context, next_grid_coord.u = 0.0f; next_grid_coord.v = grid_coord.u; - foreach_single_vertex(foreach_context, &next_grid_coord, subdiv_vertex_index); + foreach_single_vertex( + foreach_context, &next_grid_coord, coarse_vertex_index, subdiv_vertex_index); } } @@ -672,7 +712,7 @@ static void foreach_vertex_inner(const struct SubdivForeachContext *foreach_cont .u = ptex_face_u, .v = ptex_face_v, }; - foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); + foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index); } static void foreach_vertex_every_corner(const struct SubdivForeachContext *foreach_context, @@ -680,7 +720,7 @@ static void foreach_vertex_every_corner(const struct SubdivForeachContext *forea const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_vertex_index), + const int coarse_vertex_index, const int UNUSED(coarse_face_index), const int UNUSED(coarse_face_corner), const int subdiv_vertex_index) @@ -690,7 +730,7 @@ static void foreach_vertex_every_corner(const struct SubdivForeachContext *forea .u = ptex_face_u, .v = ptex_face_v, }; - foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); + foreach_vertex(foreach_context, &ptex_coord, coarse_vertex_index, subdiv_vertex_index); } static void foreach_vertex_every_edge(const struct SubdivForeachContext *foreach_context, @@ -708,7 +748,7 @@ static void foreach_vertex_every_edge(const struct SubdivForeachContext *foreach .u = ptex_face_u, .v = ptex_face_v, }; - foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); + foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index); } static void foreach_loop(const struct SubdivForeachContext *foreach_context, @@ -778,7 +818,7 @@ static void store_edge(MultiresReshapeSmoothContext *reshape_smooth_context, Edge *edge = &reshape_smooth_context->geometry.edges[edge_index]; edge->v1 = subdiv_v1; edge->v2 = subdiv_v2; - edge->sharpness = BKE_subdiv_edge_crease_to_sharpness_char(crease); + edge->sharpness = BKE_subdiv_crease_to_sharpness_char(crease); } static void foreach_edge(const struct SubdivForeachContext *foreach_context, @@ -809,7 +849,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context, /* Edges without crease are to be ignored as well. */ const Mesh *base_mesh = reshape_context->base_mesh; const MEdge *base_edge = &base_mesh->medge[coarse_edge_index]; - const char crease = get_effective_edge_crease_char(reshape_smooth_context, base_edge); + const char crease = get_effective_crease_char(reshape_smooth_context, base_edge); if (crease == 0) { return; } @@ -835,8 +875,7 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap if (!BLI_BITMAP_TEST_BOOL(reshape_smooth_context->non_loose_base_edge_map, loop->e)) { BLI_BITMAP_ENABLE(reshape_smooth_context->non_loose_base_edge_map, loop->e); - const char crease = get_effective_edge_crease_char(reshape_smooth_context, - &base_edge[loop->e]); + const char crease = get_effective_crease_char(reshape_smooth_context, &base_edge[loop->e]); if (crease != 0) { ++num_used_edges; } @@ -979,6 +1018,15 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, const int return edge->sharpness; } +static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, const int vertex_index) +{ + const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + BLI_assert(vertex_index < reshape_smooth_context->geometry.num_vertices); + + const Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index]; + return vertex->sharpness; +} + static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, int vertex_index) { const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; @@ -1015,7 +1063,7 @@ static void converter_init(const MultiresReshapeSmoothContext *reshape_smooth_co converter->getNumVertexFaces = NULL; converter->getVertexFaces = NULL; converter->isInfiniteSharpVertex = is_infinite_sharp_vertex; - converter->getVertexSharpness = NULL; + converter->getVertexSharpness = get_vertex_sharpness; converter->getNumUVLayers = NULL; converter->precalcUVLayer = NULL; diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c index 49d880e04cc..810cf328531 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.c @@ -211,6 +211,8 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape reshape_context->top.level = mmd->totlvl; reshape_context->top.grid_size = BKE_subdiv_grid_size_from_level(reshape_context->top.level); + reshape_context->cd_vertex_crease = CustomData_get_layer(&base_mesh->vdata, CD_CREASE); + context_init_commoon(reshape_context); return context_verify_or_free(reshape_context); diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 41fc28c5d52..fc7ef887879 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -40,6 +40,8 @@ #include "opensubdiv_capi.h" #include "opensubdiv_converter_capi.h" +#include "bmesh_class.h" + /* Enable work-around for non-working CPU evaluator when using bilinear scheme. * This forces Catmark scheme with all edges marked as infinitely sharp. */ #define BUGGY_SIMPLE_SCHEME_WORKAROUND 1 @@ -47,6 +49,8 @@ typedef struct ConverterStorage { SubdivSettings settings; const Mesh *mesh; + /* CustomData layer for vertex sharpnesses. */ + const float *cd_vertex_crease; /* Indexed by loop index, value denotes index of face-varying vertex * which corresponds to the UV coordinate. */ @@ -168,7 +172,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif } const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index]; const MEdge *medge = storage->mesh->medge; - return BKE_subdiv_edge_crease_to_sharpness_char(medge[edge_index].crease); + return BKE_subdiv_crease_to_sharpness_char(medge[edge_index].crease); } static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, @@ -184,14 +188,14 @@ static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, return BLI_BITMAP_TEST_BOOL(storage->infinite_sharp_vertices_map, vertex_index); } -static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, - int UNUSED(manifold_vertex_index)) +static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, int manifold_vertex_index) { ConverterStorage *storage = converter->user_data; - if (!storage->settings.use_creases) { + if (!storage->settings.use_creases || storage->cd_vertex_crease == NULL) { return 0.0f; } - return 0.0f; + const int vertex_index = storage->manifold_vertex_index_reverse[manifold_vertex_index]; + return BKE_subdiv_crease_to_sharpness_f(storage->cd_vertex_crease[vertex_index]); } static int get_num_uv_layers(const OpenSubdiv_Converter *converter) @@ -393,6 +397,7 @@ static void init_user_data(OpenSubdiv_Converter *converter, ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__); user_data->settings = *settings; user_data->mesh = mesh; + user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE); user_data->loop_uv_indices = NULL; initialize_manifold_indices(user_data); converter->user_data = user_data; diff --git a/source/blender/blenkernel/intern/subdiv_inline.h b/source/blender/blenkernel/intern/subdiv_inline.h index ba45d0a4997..d52adff1e61 100644 --- a/source/blender/blenkernel/intern/subdiv_inline.h +++ b/source/blender/blenkernel/intern/subdiv_inline.h @@ -103,13 +103,13 @@ BLI_INLINE void BKE_subdiv_rotate_grid_to_quad( } } -BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_f(float edge_crease) +BLI_INLINE float BKE_subdiv_crease_to_sharpness_f(float edge_crease) { return edge_crease * edge_crease * 10.0f; } -BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease) +BLI_INLINE float BKE_subdiv_crease_to_sharpness_char(char edge_crease) { const float edge_crease_f = edge_crease / 255.0f; - return BKE_subdiv_edge_crease_to_sharpness_f(edge_crease_f); + return BKE_subdiv_crease_to_sharpness_f(edge_crease_f); } |