diff --git a/CMakeLists.txt b/CMakeLists.txt index 708e5192c19..e3fe49fce2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,6 +237,9 @@ option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON) option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" _init_OPENSUBDIV) +option(WITH_OPENSUBDIV_MODIFIER "Use OpenSubdiv for CPU side of Subsurf/Multires modifiers" OFF) +mark_as_advanced(WITH_OPENSUBDIV_MODIFIER) + option(WITH_OPENVDB "Enable features relying on OpenVDB" OFF) option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" OFF) option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 434c697230f..5dfd8994ed4 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -986,6 +986,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label(text="Subdivisions:") col.prop(md, "levels", text="View") col.prop(md, "render_levels", text="Render") + if hasattr(md, "quality"): + col.prop(md, "quality") col = split.column() col.label(text="Options:") diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index d35d363428b..0774d65182f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -728,6 +728,7 @@ static DerivedMesh *subsurf_dm_create_local( SubsurfFlags flags = 0; smd.levels = smd.renderLevels = lvl; + smd.quality = 3; if (!is_plain_uv) { smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index f9bf1d9baa6..fbc98a594a2 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1855,5 +1855,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "SubsurfModifier", "short", "quality")) { + for (Object *object = bmain->object.first; object != NULL; object = object->id.next) { + for (ModifierData *md = object->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Subsurf) { + SubsurfModifierData *smd = (SubsurfModifierData *)md; + smd->quality = 3; + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 87e632defe1..404e8d2d137 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -162,7 +162,8 @@ typedef struct SubsurfModifierData { short subdivType, levels, renderLevels, flags; short uv_smooth; - short pad[3]; + short quality; + short pad[2]; void *emCache, *mCache; } SubsurfModifierData; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index ec240c222a1..b98eb84eaae 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -305,6 +305,10 @@ if(WITH_OPENSUBDIV) add_definitions(-DWITH_OPENSUBDIV) endif() +if(WITH_OPENSUBDIV_MODIFIER) + add_definitions(-DWITH_OPENSUBDIV_MODIFIER) +endif() + if(WITH_OPENVDB) add_definitions(-DWITH_OPENVDB) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index eeeee5d4c9a..50907503aca 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1249,6 +1249,15 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) RNA_def_property_enum_items(prop, prop_uv_smooth_items); RNA_def_property_ui_text(prop, "UV Smooth", "Controls how smoothing is applied to UVs"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + +#ifdef WITH_OPENSUBDIV_MODIFIER + prop = RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "quality"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_range(prop, 1, 6, 1, -1); + RNA_def_property_ui_text(prop, "Quality", "Accuracy of vertex positions, lower value is faster but less precise"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +#endif } static void rna_def_modifier_generic_map_info(StructRNA *srna) diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 045a5d31fcb..522e15be856 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -144,8 +144,8 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() -if(WITH_OPENSUBDIV) - add_definitions(-DWITH_OPENSUBDIV) +if(WITH_OPENSUBDIV_MODIFIER) + add_definitions(-DWITH_OPENSUBDIV_MODIFIER) endif() # So we can have special tricks in modifier system. diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 58cdea0df10..4cf830f9787 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -39,10 +39,6 @@ #include "DNA_scene_types.h" #include "DNA_mesh_types.h" -#ifdef WITH_OPENSUBDIV -# include "DNA_userdef_types.h" -#endif - #include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" @@ -57,8 +53,6 @@ #include "intern/CCGSubSurf.h" -// #define USE_OPENSUBDIV - static void initData(ModifierData *md) { SubsurfModifierData *smd = (SubsurfModifierData *) md; @@ -66,6 +60,7 @@ static void initData(ModifierData *md) smd->levels = 1; smd->renderLevels = 2; smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; + smd->quality = 3; } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -151,26 +146,25 @@ static DerivedMesh *applyModifierEM( return result; } -#ifdef USE_OPENSUBDIV +#ifdef WITH_OPENSUBDIV_MODIFIER static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd, const ModifierEvalContext *ctx) { - Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); - const int requested_levels = (use_render_params) ? smd->renderLevels - : smd->levels; - return get_render_subsurf_level(&scene->r, - requested_levels, - use_render_params); + Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + const int requested_levels = (use_render_params) ? smd->renderLevels + : smd->levels; + return get_render_subsurf_level(&scene->r, + requested_levels, + use_render_params); } static void subdiv_settings_init(SubdivSettings *settings, - const SubsurfModifierData *smd, - const ModifierEvalContext *ctx) + const SubsurfModifierData *smd) { settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); settings->is_adaptive = !settings->is_simple; - settings->level = subdiv_levels_for_modifier_get(smd, ctx); + settings->level = smd->quality; switch (smd->uv_smooth) { case SUBSURF_UV_SMOOTH_NONE: settings->fvar_linear_interpolation = @@ -200,9 +194,11 @@ static void subdiv_settings_init(SubdivSettings *settings, } static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, - const SubdivSettings *subdiv_settings) + const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) { - settings->resolution = (1 << subdiv_settings->level) + 1; + const int level = subdiv_levels_for_modifier_get(smd, ctx); + settings->resolution = (1 << level) + 1; } static Mesh *applyModifier_subdiv(ModifierData *md, @@ -212,7 +208,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, Mesh *result = mesh; SubsurfModifierData *smd = (SubsurfModifierData *) md; SubdivSettings subdiv_settings; - subdiv_settings_init(&subdiv_settings, smd, ctx); + subdiv_settings_init(&subdiv_settings, smd); if (subdiv_settings.level == 0) { /* NOTE: Shouldn't really happen, is supposed to be catched by * isDisabled() callback. @@ -226,7 +222,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, return result; } SubdivToMeshSettings mesh_settings; - subdiv_mesh_settings_init(&mesh_settings, &subdiv_settings); + subdiv_mesh_settings_init(&mesh_settings, smd, ctx); result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); /* TODO(sergey): Cache subdiv somehow. */ // BKE_subdiv_stats_print(&subdiv->stats); @@ -259,7 +255,7 @@ ModifierTypeInfo modifierType_Subsurf = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, -#ifdef USE_OPENSUBDIV +#ifdef WITH_OPENSUBDIV_MODIFIER /* applyModifier */ applyModifier_subdiv, #else /* applyModifier */ NULL, diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 05ccf234638..a5d2a359472 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -684,6 +684,7 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) if (ss_lvl > 0) { smd.levels = smd.renderLevels = ss_lvl; smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; + smd.quality = 3; if (bkr->simple) smd.subdivType = ME_SIMPLE_SUBSURF;