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:
authorCody Winchester <CodyWinch>2020-07-22 08:03:17 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-07-22 08:07:21 +0300
commit5c28955d3a018adf9986cc601837cde9fc011496 (patch)
tree2e73cf38fc6c6a0edb1e0fb17f161b1c5d4aa13c /source/blender/modifiers/intern/MOD_subsurf.c
parenta197b810909b7d30faae9e84cfb12767d2e24a02 (diff)
Modifiers: option to preserve custom normals for subsurf & multires
Diffstat (limited to 'source/blender/modifiers/intern/MOD_subsurf.c')
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index d5ff31bd3b1..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"
@@ -77,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
@@ -242,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) {
@@ -250,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);
@@ -416,6 +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);
+ uiItemR(layout, &ptr, "use_custom_normals", 0, NULL, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
@@ -453,12 +492,12 @@ 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,