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:
authorPiotr Ostrowski <postrowski>2020-09-30 16:47:08 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-09-30 17:39:02 +0300
commit53f20b940a1e520e131b8bb31cf0529ed4d30f9e (patch)
tree80ac24fc8b9e08a925a6cacd726c82b665a9eb79
parentecdfb465cc9d992632feec13229fd31666f6b4e8 (diff)
Subdivision Surfaces: add option disable using the limit surface
This makes subdivision surfaces compatible with the old subdivision surface modifier and other applications that do not use the limit surface. This option is available on the Subdivision Surface modifier. Differential Revision: https://developer.blender.org/D8413
-rw-r--r--intern/opensubdiv/internal/evaluator/evaluator_impl.cc17
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c9
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c31
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);