diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_subsurf.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_subsurf.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 2b2f6893a2e..8424b549f85 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -36,6 +36,7 @@ #include "DNA_screen_types.h" #include "BKE_context.h" +#include "BKE_mesh.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_subdiv.h" @@ -57,6 +58,8 @@ #include "MOD_modifiertypes.h" #include "MOD_ui_common.h" +#include "BLO_read_write.h" + #include "intern/CCGSubSurf.h" typedef struct SubsurfRuntimeData { @@ -75,6 +78,26 @@ static void initData(ModifierData *md) smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges); } +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) +{ + SubsurfModifierData *smd = (SubsurfModifierData *)md; + if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) { + r_cddata_masks->lmask |= CD_MASK_NORMAL; + r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; + } +} + +static bool dependsOnNormals(ModifierData *md) +{ + SubsurfModifierData *smd = (SubsurfModifierData *)md; + if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) { + return true; + } + return false; +} + static void copyData(const ModifierData *md, ModifierData *target, const int flag) { #if 0 @@ -240,6 +263,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Happens on bad topology, but also on empty input mesh. */ return result; } + const bool use_clnors = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && + (mesh->flag & ME_AUTOSMOOTH) && + CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + if (use_clnors) { + /* If custom normals are present and the option is turned on calculate the split + * normals and clear flag so the normals get interpolated to the result mesh. */ + BKE_mesh_calc_normals_split(mesh); + CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); + } /* TODO(sergey): Decide whether we ever want to use CCG for subsurf, * maybe when it is a last modifier in the stack? */ if (true) { @@ -248,6 +280,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * else { result = subdiv_as_ccg(smd, ctx, mesh, subdiv); } + + if (use_clnors) { + float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL); + BLI_assert(lnors != NULL); + BKE_mesh_set_custom_normals(result, lnors); + CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); + CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); + } // BKE_subdiv_stats_print(&subdiv->stats); if (subdiv != runtime_data->subdiv) { BKE_subdiv_free(subdiv); @@ -348,9 +388,9 @@ static void panel_draw(const bContext *C, Panel *panel) } #endif - uiLayoutSetPropSep(layout, true); + uiItemR(layout, &ptr, "subdivision_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - uiItemR(layout, &ptr, "subdivision_type", 0, IFACE_("Type"), ICON_NONE); + uiLayoutSetPropSep(layout, true); if (show_adaptive_options) { uiItemR(layout, @@ -414,8 +454,7 @@ static void advanced_panel_draw(const bContext *C, Panel *panel) uiItemR(layout, &ptr, "quality", 0, NULL, ICON_NONE); uiItemR(layout, &ptr, "uv_smooth", 0, NULL, ICON_NONE); uiItemR(layout, &ptr, "use_creases", 0, NULL, ICON_NONE); - - modifier_panel_end(layout, &ptr); + uiItemR(layout, &ptr, "use_custom_normals", 0, NULL, ICON_NONE); } static void panelRegister(ARegionType *region_type) @@ -425,6 +464,13 @@ static void panelRegister(ARegionType *region_type) region_type, "advanced", "Advanced", NULL, advanced_panel_draw, panel_type); } +static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) +{ + SubsurfModifierData *smd = (SubsurfModifierData *)md; + + smd->emCache = smd->mCache = NULL; +} + ModifierTypeInfo modifierType_Subsurf = { /* name */ "Subdivision", /* structName */ "SubsurfModifierData", @@ -446,15 +492,17 @@ ModifierTypeInfo modifierType_Subsurf = { /* modifyVolume */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ isDisabled, /* updateDepsgraph */ NULL, /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, + /* dependsOnNormals */ dependsOnNormals, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, /* foreachTexLink */ NULL, /* freeRuntimeData */ freeRuntimeData, /* panelRegister */ panelRegister, + /* blendWrite */ NULL, + /* blendRead */ blendRead, }; |