From 5e696fdcd646ca8643f617046a22da0a825f56d4 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 14 Aug 2018 12:17:10 +0200 Subject: Multires: Begin hooking it up to the new subdiv code Currently behaves same as subsurf, support of displacement is the next task in the line to tackle! --- source/blender/blenkernel/BKE_multires.h | 2 + source/blender/blenkernel/BKE_subdiv.h | 6 +++ source/blender/blenkernel/intern/multires.c | 4 +- source/blender/blenkernel/intern/subdiv.c | 22 +++++++++ source/blender/modifiers/intern/MOD_multires.c | 63 ++++++++++++++++++++++++++ source/blender/modifiers/intern/MOD_subsurf.c | 42 ++++------------- 6 files changed, 104 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 3a70e145744..08feaec6644 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -82,6 +82,8 @@ struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm, struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene, struct ModifierData *lastmd); struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, bool use_first); +int multires_get_level(struct Scene *scene, struct Object *ob, const struct MultiresModifierData *mmd, + bool render, bool ignore_simplify); struct DerivedMesh *get_multires_dm(struct Depsgraph *depsgraph, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *ob); void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Scene *scene, struct Object *object, int direction); diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 03d765a154f..c4628cb9da7 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -111,6 +111,12 @@ typedef struct Subdiv { SubdivStats stats; } Subdiv; +/* ================================ HELPERS ================================= */ + +/* NOTE: uv_smooth is eSubsurfUVSmooth. */ +eSubdivFVarLinearInterpolation +BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth); + /* =============================== STATISTICS =============================== */ void BKE_subdiv_stats_init(SubdivStats *stats); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index bb261ec9590..ab0327652cd 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -337,8 +337,8 @@ MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_f return mmd; } -static int multires_get_level(Scene *scene, Object *ob, MultiresModifierData *mmd, - bool render, bool ignore_simplify) +int multires_get_level(Scene *scene, Object *ob, const MultiresModifierData *mmd, + bool render, bool ignore_simplify) { if (render) return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) : mmd->renderlvl; diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 207fdf43c55..4f630e8c38c 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -30,6 +30,7 @@ #include "BKE_subdiv.h" #include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" #include "BLI_utildefines.h" @@ -42,6 +43,27 @@ #include "opensubdiv_evaluator_capi.h" #include "opensubdiv_topology_refiner_capi.h" +eSubdivFVarLinearInterpolation +BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth) +{ + switch (uv_smooth) { + case SUBSURF_UV_SMOOTH_NONE: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS; + case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE; + case SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES; + case SUBSURF_UV_SMOOTH_ALL: + return SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE; + } + BLI_assert(!"Unknown uv smooth flag"); + return SUBSURF_UV_SMOOTH_NONE; +} + Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, struct OpenSubdiv_Converter *converter) { diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 36bfa4fcd56..ca60dceb052 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -37,6 +37,7 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BLI_utildefines.h" @@ -44,6 +45,7 @@ #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" +#include "BKE_subdiv.h" #include "BKE_subsurf.h" #include "DEG_depsgraph_query.h" @@ -139,6 +141,63 @@ static DerivedMesh *applyModifier( return result; } +#ifdef WITH_OPENSUBDIV_MODIFIER +static int subdiv_levels_for_modifier_get(const MultiresModifierData *mmd, + const ModifierEvalContext *ctx) +{ + Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + return multires_get_level( + scene, ctx->object, mmd, use_render_params, false); +} + +static void subdiv_settings_init(SubdivSettings *settings, + const MultiresModifierData *mmd) +{ + settings->is_simple = (mmd->simple != 0); + settings->is_adaptive = !settings->is_simple; + settings->level = mmd->quality; + settings->fvar_linear_interpolation = + BKE_subdiv_fvar_interpolation_from_uv_smooth(mmd->uv_smooth); +} + +static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, + const MultiresModifierData *mmd, + const ModifierEvalContext *ctx) +{ + const int level = subdiv_levels_for_modifier_get(mmd, ctx); + settings->resolution = (1 << level) + 1; +} + +static Mesh *applyModifier_subdiv(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh) +{ + Mesh *result = mesh; + MultiresModifierData *mmd = (MultiresModifierData *)md; + SubdivSettings subdiv_settings; + subdiv_settings_init(&subdiv_settings, mmd); + if (subdiv_settings.level == 0) { + /* NOTE: Shouldn't really happen, is supposed to be catched by + * isDisabled() callback. + */ + return result; + } + /* TODO(sergey): Try to re-use subdiv when possible. */ + Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh); + if (subdiv == NULL) { + /* Happens on bad topology, ut also on empty input mesh. */ + return result; + } + SubdivToMeshSettings mesh_settings; + subdiv_mesh_settings_init(&mesh_settings, mmd, ctx); + result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + /* TODO(sergey): Cache subdiv somehow. */ + // BKE_subdiv_stats_print(&subdiv->stats); + BKE_subdiv_free(subdiv); + return result; +} +#endif ModifierTypeInfo modifierType_Multires = { /* name */ "Multires", @@ -162,7 +221,11 @@ ModifierTypeInfo modifierType_Multires = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, +#ifdef WITH_OPENSUBDIV_MODIFIER + /* applyModifier */ applyModifier_subdiv, +#else /* applyModifier */ NULL, +#endif /* applyModifierEM */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 4cf830f9787..38683cff42a 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -150,13 +150,13 @@ static DerivedMesh *applyModifierEM( 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, @@ -165,32 +165,8 @@ static void subdiv_settings_init(SubdivSettings *settings, settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); settings->is_adaptive = !settings->is_simple; settings->level = smd->quality; - 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; - } + settings->fvar_linear_interpolation = + BKE_subdiv_fvar_interpolation_from_uv_smooth(smd->uv_smooth); } static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, -- cgit v1.2.3