diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 8a6480a9a42..c7378e71183 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -989,7 +989,7 @@ static void create_subd_mesh(Scene *scene, int max_subdivisions) { BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]); - bool subdivide_uvs = subsurf_mod.use_subsurf_uv(); + bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE; create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs); diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 93e789bbd19..9fbac78ebe3 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -992,7 +992,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): sub = col.column() sub.active = (not show_adaptive_options) or (not ob.cycles.use_adaptive_subdivision) - sub.prop(md, "use_subsurf_uv") + sub.prop(md, "uv_smooth", text="") col.prop(md, "show_only_control_edges") if hasattr(md, "use_opensubdiv"): diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index d81047563a7..03d765a154f 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -42,6 +42,8 @@ struct OpenSubdiv_TopologyRefiner; typedef enum { SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE, SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS, + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE, SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL, } eSubdivFVarLinearInterpolation; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 331b3797739..d35d363428b 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -729,7 +729,10 @@ static DerivedMesh *subsurf_dm_create_local( smd.levels = smd.renderLevels = lvl; if (!is_plain_uv) { - smd.flags |= eSubsurfModifierFlag_SubsurfUv; + smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; + } + else { + smd.uv_smooth = SUBSURF_UV_SMOOTH_NONE; } if (is_simple) { smd.subdivType = ME_SIMPLE_SUBSURF; diff --git a/source/blender/blenkernel/intern/subdiv_converter.c b/source/blender/blenkernel/intern/subdiv_converter.c index 0ef32200bd3..5cad2f3e4cd 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.c +++ b/source/blender/blenkernel/intern/subdiv_converter.c @@ -44,6 +44,10 @@ BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings) return OSD_FVAR_LINEAR_INTERPOLATION_NONE; case SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + case SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1; + case SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2; case SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: return OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES; case SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL: diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index cead75ae659..9fda7f585b4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2927,7 +2927,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( { int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0; CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0; - int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; + int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE); int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); CCGDerivedMesh *result; bool use_gpu_backend = subsurf_use_gpu_backend(flags); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index aed1fd8b416..f9bf1d9baa6 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -48,6 +48,7 @@ #include "DNA_lightprobe_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" #include "DNA_particle_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" @@ -1838,4 +1839,21 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + { + if (!DNA_struct_elem_find(fd->filesdna, "SubsurfModifier", "short", "uv_smooth")) { + 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; + if (smd->flags & eSubsurfModifierFlag_SubsurfUv) { + smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; + } + else { + smd->uv_smooth = SUBSURF_UV_SMOOTH_NONE; + } + } + } + } + } + } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 02e70a323c7..c53b8e3a5e2 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -139,6 +139,7 @@ typedef enum { eSubsurfModifierFlag_Incremental = (1 << 0), eSubsurfModifierFlag_DebugIncr = (1 << 1), eSubsurfModifierFlag_ControlEdges = (1 << 2), + /* DEPRECATED, ONLY USED FOR DO-VERSIONS */ eSubsurfModifierFlag_SubsurfUv = (1 << 3), } SubsurfModifierFlag; @@ -147,11 +148,22 @@ typedef enum { SUBSURF_TYPE_SIMPLE = 1, } eSubsurfModifierType; +typedef enum { + SUBSURF_UV_SMOOTH_NONE = 0, + SUBSURF_UV_SMOOTH_PRESERVE_CORNERS = 1, + SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS = 2, + SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE = 3, + SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES = 4, + SUBSURF_UV_SMOOTH_ALL = 5, +} eSubsurfModifierUVSmooth; + typedef struct SubsurfModifierData { ModifierData modifier; short subdivType, levels, renderLevels, flags; - short use_opensubdiv, pad[3]; + short uv_smooth; + short use_opensubdiv; + short pad[2]; void *emCache, *mCache; } SubsurfModifierData; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index fc0144f3f7b..8fbd906766e 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1195,6 +1195,26 @@ static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const c static void rna_def_modifier_subsurf(BlenderRNA *brna) { + static const EnumPropertyItem prop_uv_smooth_items[] = { + {SUBSURF_UV_SMOOTH_NONE, "NONE", 0, + "Sharp", "UVs are not smoothed, boundaries are kept sharp"}, + {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS, "PRESERVE_CORNERS", 0, + "Smooth, keep corners", "UVs are smoothed, corners on discontinuous boundary are kept sharp"}, +#if 0 + {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS, "PRESERVE_CORNERS_AND_JUNCTIONS", 0, + "Smooth, keep corners+junctions", "UVs are smoothed, corners on discontinuous boundary and " + "junctions of 3 or more regions are kept sharp"}, + {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE, "PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE", 0, + "Smooth, keep corners+junctions+concave", "UVs are smoothed, corners on discontinuous boundary, " + "junctions of 3 or more regions and darts and concave corners are kept sharp"}, + {SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES, "PRESERVE_BOUNDARIES", 0, + "Smooth, keep corners", "UVs are smoothed, boundaries are kept sharp"}, + {SUBSURF_UV_SMOOTH_ALL, "PRESERVE_BOUNDARIES", 0, + "Smooth all", "UVs and boundaries are smoothed"}, +#endif + {0, NULL, 0, NULL, NULL} + }; + StructRNA *srna; PropertyRNA *prop; @@ -1224,9 +1244,10 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "use_subsurf_uv", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_SubsurfUv); - RNA_def_property_ui_text(prop, "Subdivide UVs", "Use subsurf to subdivide UVs"); + prop = RNA_def_property(srna, "uv_smooth", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "uv_smooth"); + 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 diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 1b25b4f62dc..82e2d8bfe8d 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -65,7 +65,7 @@ static void initData(ModifierData *md) smd->levels = 1; smd->renderLevels = 2; - smd->flags |= eSubsurfModifierFlag_SubsurfUv; + smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -207,10 +207,32 @@ static void subdiv_settings_init(SubdivSettings *settings, settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); settings->is_adaptive = !settings->is_simple; settings->level = subdiv_levels_for_modifier_get(smd, ctx); - settings->fvar_linear_interpolation = - (smd->flags & eSubsurfModifierFlag_SubsurfUv) - ? SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY - : SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; + switch (smd->uv_smooth) { + case SUBSURF_UV_SMOOTH_NONE: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; + break; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + break; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS; + break; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE; + break; + case SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES; + break; + case SUBSURF_UV_SMOOTH_ALL: + settings->fvar_linear_interpolation = + SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE; + break; + } } static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 0cb9fd7324b..05ccf234638 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -683,7 +683,7 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) if (ss_lvl > 0) { smd.levels = smd.renderLevels = ss_lvl; - smd.flags |= eSubsurfModifierFlag_SubsurfUv; + smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; if (bkr->simple) smd.subdivType = ME_SIMPLE_SUBSURF;