Subsurf: Introduce quality option
For users it defines how accurate vertex positions are in terms of limit surface (as in, how close the vertices locations to the condition when they are calculated for an infinitely subdivided mesh). This affects things like: - Irregular vertices (joint of 3 or more edges) - Crease Keep quality value low for performance. NOTE: Going higher does not necessarily mean real improvement in quality, ideal case might be reached well before maximum quality of 10. Quality of 3 is a good starting point. Internally quality is translated directly to adaptive subdivision level. Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D3599
This commit is contained in:
@@ -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 "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 "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_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)
|
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
|
||||||
|
@@ -986,6 +986,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
col.label(text="Subdivisions:")
|
col.label(text="Subdivisions:")
|
||||||
col.prop(md, "levels", text="View")
|
col.prop(md, "levels", text="View")
|
||||||
col.prop(md, "render_levels", text="Render")
|
col.prop(md, "render_levels", text="Render")
|
||||||
|
if hasattr(md, "quality"):
|
||||||
|
col.prop(md, "quality")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Options:")
|
col.label(text="Options:")
|
||||||
|
@@ -728,6 +728,7 @@ static DerivedMesh *subsurf_dm_create_local(
|
|||||||
SubsurfFlags flags = 0;
|
SubsurfFlags flags = 0;
|
||||||
|
|
||||||
smd.levels = smd.renderLevels = lvl;
|
smd.levels = smd.renderLevels = lvl;
|
||||||
|
smd.quality = 3;
|
||||||
if (!is_plain_uv) {
|
if (!is_plain_uv) {
|
||||||
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -162,7 +162,8 @@ typedef struct SubsurfModifierData {
|
|||||||
|
|
||||||
short subdivType, levels, renderLevels, flags;
|
short subdivType, levels, renderLevels, flags;
|
||||||
short uv_smooth;
|
short uv_smooth;
|
||||||
short pad[3];
|
short quality;
|
||||||
|
short pad[2];
|
||||||
|
|
||||||
void *emCache, *mCache;
|
void *emCache, *mCache;
|
||||||
} SubsurfModifierData;
|
} SubsurfModifierData;
|
||||||
|
@@ -305,6 +305,10 @@ if(WITH_OPENSUBDIV)
|
|||||||
add_definitions(-DWITH_OPENSUBDIV)
|
add_definitions(-DWITH_OPENSUBDIV)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_OPENSUBDIV_MODIFIER)
|
||||||
|
add_definitions(-DWITH_OPENSUBDIV_MODIFIER)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_OPENVDB)
|
if(WITH_OPENVDB)
|
||||||
add_definitions(-DWITH_OPENVDB)
|
add_definitions(-DWITH_OPENVDB)
|
||||||
|
|
||||||
|
@@ -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_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_ui_text(prop, "UV Smooth", "Controls how smoothing is applied to UVs");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
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)
|
static void rna_def_modifier_generic_map_info(StructRNA *srna)
|
||||||
|
@@ -144,8 +144,8 @@ if(WITH_INTERNATIONAL)
|
|||||||
add_definitions(-DWITH_INTERNATIONAL)
|
add_definitions(-DWITH_INTERNATIONAL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_OPENSUBDIV)
|
if(WITH_OPENSUBDIV_MODIFIER)
|
||||||
add_definitions(-DWITH_OPENSUBDIV)
|
add_definitions(-DWITH_OPENSUBDIV_MODIFIER)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# So we can have special tricks in modifier system.
|
# So we can have special tricks in modifier system.
|
||||||
|
@@ -39,10 +39,6 @@
|
|||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_mesh_types.h"
|
#include "DNA_mesh_types.h"
|
||||||
|
|
||||||
#ifdef WITH_OPENSUBDIV
|
|
||||||
# include "DNA_userdef_types.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "BKE_cdderivedmesh.h"
|
#include "BKE_cdderivedmesh.h"
|
||||||
@@ -57,8 +53,6 @@
|
|||||||
|
|
||||||
#include "intern/CCGSubSurf.h"
|
#include "intern/CCGSubSurf.h"
|
||||||
|
|
||||||
// #define USE_OPENSUBDIV
|
|
||||||
|
|
||||||
static void initData(ModifierData *md)
|
static void initData(ModifierData *md)
|
||||||
{
|
{
|
||||||
SubsurfModifierData *smd = (SubsurfModifierData *) md;
|
SubsurfModifierData *smd = (SubsurfModifierData *) md;
|
||||||
@@ -66,6 +60,7 @@ static void initData(ModifierData *md)
|
|||||||
smd->levels = 1;
|
smd->levels = 1;
|
||||||
smd->renderLevels = 2;
|
smd->renderLevels = 2;
|
||||||
smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
||||||
|
smd->quality = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
|
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
|
||||||
@@ -151,26 +146,25 @@ static DerivedMesh *applyModifierEM(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_OPENSUBDIV
|
#ifdef WITH_OPENSUBDIV_MODIFIER
|
||||||
static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd,
|
static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd,
|
||||||
const ModifierEvalContext *ctx)
|
const ModifierEvalContext *ctx)
|
||||||
{
|
{
|
||||||
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
|
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
|
||||||
const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
|
const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
|
||||||
const int requested_levels = (use_render_params) ? smd->renderLevels
|
const int requested_levels = (use_render_params) ? smd->renderLevels
|
||||||
: smd->levels;
|
: smd->levels;
|
||||||
return get_render_subsurf_level(&scene->r,
|
return get_render_subsurf_level(&scene->r,
|
||||||
requested_levels,
|
requested_levels,
|
||||||
use_render_params);
|
use_render_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subdiv_settings_init(SubdivSettings *settings,
|
static void subdiv_settings_init(SubdivSettings *settings,
|
||||||
const SubsurfModifierData *smd,
|
const SubsurfModifierData *smd)
|
||||||
const ModifierEvalContext *ctx)
|
|
||||||
{
|
{
|
||||||
settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
|
settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
|
||||||
settings->is_adaptive = !settings->is_simple;
|
settings->is_adaptive = !settings->is_simple;
|
||||||
settings->level = subdiv_levels_for_modifier_get(smd, ctx);
|
settings->level = smd->quality;
|
||||||
switch (smd->uv_smooth) {
|
switch (smd->uv_smooth) {
|
||||||
case SUBSURF_UV_SMOOTH_NONE:
|
case SUBSURF_UV_SMOOTH_NONE:
|
||||||
settings->fvar_linear_interpolation =
|
settings->fvar_linear_interpolation =
|
||||||
@@ -200,9 +194,11 @@ static void subdiv_settings_init(SubdivSettings *settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void subdiv_mesh_settings_init(SubdivToMeshSettings *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,
|
static Mesh *applyModifier_subdiv(ModifierData *md,
|
||||||
@@ -212,7 +208,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md,
|
|||||||
Mesh *result = mesh;
|
Mesh *result = mesh;
|
||||||
SubsurfModifierData *smd = (SubsurfModifierData *) md;
|
SubsurfModifierData *smd = (SubsurfModifierData *) md;
|
||||||
SubdivSettings subdiv_settings;
|
SubdivSettings subdiv_settings;
|
||||||
subdiv_settings_init(&subdiv_settings, smd, ctx);
|
subdiv_settings_init(&subdiv_settings, smd);
|
||||||
if (subdiv_settings.level == 0) {
|
if (subdiv_settings.level == 0) {
|
||||||
/* NOTE: Shouldn't really happen, is supposed to be catched by
|
/* NOTE: Shouldn't really happen, is supposed to be catched by
|
||||||
* isDisabled() callback.
|
* isDisabled() callback.
|
||||||
@@ -226,7 +222,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
SubdivToMeshSettings mesh_settings;
|
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);
|
result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
|
||||||
/* TODO(sergey): Cache subdiv somehow. */
|
/* TODO(sergey): Cache subdiv somehow. */
|
||||||
// BKE_subdiv_stats_print(&subdiv->stats);
|
// BKE_subdiv_stats_print(&subdiv->stats);
|
||||||
@@ -259,7 +255,7 @@ ModifierTypeInfo modifierType_Subsurf = {
|
|||||||
/* deformMatrices */ NULL,
|
/* deformMatrices */ NULL,
|
||||||
/* deformVertsEM */ NULL,
|
/* deformVertsEM */ NULL,
|
||||||
/* deformMatricesEM */ NULL,
|
/* deformMatricesEM */ NULL,
|
||||||
#ifdef USE_OPENSUBDIV
|
#ifdef WITH_OPENSUBDIV_MODIFIER
|
||||||
/* applyModifier */ applyModifier_subdiv,
|
/* applyModifier */ applyModifier_subdiv,
|
||||||
#else
|
#else
|
||||||
/* applyModifier */ NULL,
|
/* applyModifier */ NULL,
|
||||||
|
@@ -684,6 +684,7 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
|
|||||||
if (ss_lvl > 0) {
|
if (ss_lvl > 0) {
|
||||||
smd.levels = smd.renderLevels = ss_lvl;
|
smd.levels = smd.renderLevels = ss_lvl;
|
||||||
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
|
||||||
|
smd.quality = 3;
|
||||||
|
|
||||||
if (bkr->simple)
|
if (bkr->simple)
|
||||||
smd.subdivType = ME_SIMPLE_SUBSURF;
|
smd.subdivType = ME_SIMPLE_SUBSURF;
|
||||||
|
Reference in New Issue
Block a user