diff options
-rw-r--r-- | intern/opensubdiv/internal/evaluator/evaluator_impl.cc | 17 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 9 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_subsurf.c | 31 |
4 files changed, 50 insertions, 8 deletions
diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc index 341e8dbc233..b3fc021e1ee 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc +++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc @@ -232,6 +232,8 @@ class FaceVaryingVolatileEval { src_face_varying_desc_.stride; const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( evaluator_cache_, src_face_varying_desc_, dst_face_varying_desc, device_context_); + // in and out points to same buffer so output is put directly after coarse vertices, needed in + // adaptive mode EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_, src_face_varying_data_, @@ -249,8 +251,21 @@ class FaceVaryingVolatileEval { ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords); const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( evaluator_cache_, src_face_varying_desc_, face_varying_desc, device_context_); + + // src_face_varying_data_ always contains coarse vertices at the beginning. + // In adaptive mode they are followed by number of blocks for intermediate + // subdivision levels, and this is what OSD expects in this mode. + // In non-adaptive mode (generateIntermediateLevels == false), + // they are followed by max subdivision level, but they break interpolation as OSD + // expects only one subd level in this buffer. + // So in non-adaptive mode we put offset into buffer descriptor to skip over coarse vertices. + BufferDescriptor src_desc = src_face_varying_desc_; + if (!patch_table_->GetPatchArrayBuffer()[0].GetDescriptor().IsAdaptive()) { + src_desc.offset += num_coarse_face_varying_vertices_ * src_face_varying_desc_.stride; + } + EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_, - src_face_varying_desc_, + src_desc, &face_varying_data, face_varying_desc, patch_coord_buffer.GetNumVertices(), diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 035ac6cf7cb..d7a41b5cb3b 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -162,6 +162,7 @@ typedef enum { eSubsurfModifierFlag_SubsurfUv_DEPRECATED = (1 << 3), eSubsurfModifierFlag_UseCrease = (1 << 4), eSubsurfModifierFlag_UseCustomNormals = (1 << 5), + eSubsurfModifierFlag_UseRecursiveSubdivision = (1 << 6), } SubsurfModifierFlag; typedef enum { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 0070f9873b0..134ce15e3f2 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1762,6 +1762,15 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_limit_surface", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna( + prop, NULL, "flags", eSubsurfModifierFlag_UseRecursiveSubdivision); + RNA_def_property_ui_text(prop, + "Use Limit Surface", + "Place vertices at the surface that would be produced with infinite " + "levels of subdivision (smoothest possible shape)"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + RNA_define_lib_overridable(false); } diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index c3b8492db9e..7a118c6c14d 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -154,11 +154,18 @@ static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd, return get_render_subsurf_level(&scene->r, requested_levels, use_render_params); } -static void subdiv_settings_init(SubdivSettings *settings, const SubsurfModifierData *smd) +static void subdiv_settings_init(SubdivSettings *settings, + const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) { + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels; + settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); - settings->is_adaptive = true; - settings->level = settings->is_simple ? 1 : smd->quality; + settings->is_adaptive = !(smd->flags & eSubsurfModifierFlag_UseRecursiveSubdivision); + settings->level = settings->is_simple ? + 1 : + (settings->is_adaptive ? smd->quality : requested_levels); settings->use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease); settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY; settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth( @@ -252,7 +259,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif SubsurfModifierData *smd = (SubsurfModifierData *)md; SubdivSettings subdiv_settings; - subdiv_settings_init(&subdiv_settings, smd); + subdiv_settings_init(&subdiv_settings, smd, ctx); if (subdiv_settings.level == 0) { return result; } @@ -296,7 +303,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } static void deformMatrices(ModifierData *md, - const ModifierEvalContext *UNUSED(ctx), + const ModifierEvalContext *ctx, Mesh *mesh, float (*vertex_cos)[3], float (*deform_matrices)[3][3], @@ -312,7 +319,7 @@ static void deformMatrices(ModifierData *md, SubsurfModifierData *smd = (SubsurfModifierData *)md; SubdivSettings subdiv_settings; - subdiv_settings_init(&subdiv_settings, smd); + subdiv_settings_init(&subdiv_settings, smd, ctx); if (subdiv_settings.level == 0) { return; } @@ -345,6 +352,11 @@ static bool get_show_adaptive_options(const bContext *C, Panel *panel) return false; } + /* Don't show adaptive options if regular subdivision used*/ + if (!RNA_boolean_get(ptr, "use_limit_surface")) { + return false; + } + /* Don't show adaptive options if the cycles experimental feature set is disabled. */ Scene *scene = CTX_data_scene(C); PointerRNA scene_ptr; @@ -452,7 +464,12 @@ static void advanced_panel_draw(const bContext *C, Panel *panel) uiLayoutSetPropSep(layout, true); uiLayoutSetActive(layout, !(show_adaptive_options && ob_use_adaptive_subdivision)); - uiItemR(layout, ptr, "quality", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_limit_surface", 0, NULL, ICON_NONE); + + uiLayout *col = uiLayoutColumn(layout, true); + uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "use_limit_surface")); + uiItemR(col, ptr, "quality", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "uv_smooth", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "use_creases", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "use_custom_normals", 0, NULL, ICON_NONE); |