diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-06 18:06:17 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-11 17:37:02 +0300 |
commit | 3fbdcefa174dd85972b7b63c0955e3a8d42f6943 (patch) | |
tree | 6b1d4b1538f18e847f2e12204a79d89b937edc28 /source/blender/modifiers/intern | |
parent | 998a80435819387ce88d922d7fd7049e8e27b7bf (diff) |
Subdiv: Initial implementation of CCG
Attempts to substitude CCGDM with an OpenSubdiv based structure
which has less abstraction levels. The missing part in this
substitude is a face pointers which old CCGDM/multires code was
using to stitch faces (averaging boundaries).
Another curial bit missing: "reshaping" of multires CD_MDISPS
to the state of new PBVH grids.
The new code is only available when OpenSubdiv modifier is
enabled (WITH_OPENSUBDIV_MODIFIER=ON) and with debug value of
128. This is so this WIP code is not interfering with current
production machines in the studio.
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D3685
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 84 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_subsurf.c | 64 |
2 files changed, 129 insertions, 19 deletions
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 870d91282b6..847b34b7aa6 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -42,10 +42,12 @@ #include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" +#include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" #include "BKE_subdiv.h" +#include "BKE_subdiv_ccg.h" #include "BKE_subdiv_mesh.h" #include "BKE_subsurf.h" @@ -143,25 +145,74 @@ static DerivedMesh *applyModifier( } #ifdef WITH_OPENSUBDIV_MODIFIER -static Mesh *applyModifier_subdiv(ModifierData *md, - const ModifierEvalContext *ctx, - Mesh *mesh) + +/* Subdivide into fully qualified mesh. */ + +static Mesh *multires_as_mesh(MultiresModifierData *mmd, + const ModifierEvalContext *ctx, + Mesh *mesh, + Subdiv *subdiv) +{ + Mesh *result = mesh; + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY); + const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + Object *object = ctx->object; + SubdivToMeshSettings mesh_settings; + BKE_multires_subdiv_mesh_settings_init( + &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify); + if (mesh_settings.resolution < 3) { + return result; + } + BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd); + result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + return result; +} + +/* Subdivide into CCG. */ + +static void multires_ccg_settings_init(SubdivToCCGSettings *settings, + const MultiresModifierData *mmd, + const ModifierEvalContext *ctx, + Mesh *mesh) { + const bool has_mask = + CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK); const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY); const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); Object *object = ctx->object; + const int level = multires_get_level( + scene, object, mmd, use_render_params, ignore_simplify); + settings->resolution = (1 << level) + 1; + settings->need_normal = true; + settings->need_mask = has_mask; +} + +static Mesh *multires_as_ccg(MultiresModifierData *mmd, + const ModifierEvalContext *ctx, + Mesh *mesh, + Subdiv *subdiv) +{ + Mesh *result = mesh; + SubdivToCCGSettings ccg_settings; + multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh); + if (ccg_settings.resolution < 3) { + return result; + } + result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh); + return result; +} + +static Mesh *applyModifier_subdiv(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh) +{ Mesh *result = mesh; MultiresModifierData *mmd = (MultiresModifierData *)md; SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); - SubdivToMeshSettings mesh_settings; - BKE_multires_subdiv_mesh_settings_init( - &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify); - if (subdiv_settings.level == 0 || mesh_settings.resolution < 3) { - /* NOTE: Shouldn't really happen, is supposed to be catched by - * isDisabled() callback. - */ + if (subdiv_settings.level == 0) { return result; } /* TODO(sergey): Try to re-use subdiv when possible. */ @@ -170,8 +221,17 @@ static Mesh *applyModifier_subdiv(ModifierData *md, /* Happens on bad topology, ut also on empty input mesh. */ return result; } - BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd); - result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + /* TODO(sergey): Some of production machines are using OpenSubdiv already. + * so better not enable semi-finished multires sculpting for now. Will give + * a wrong impression that things do work, eben though crucial areas are + * styill missing in implementation. + */ + if ((ctx->object->mode & OB_MODE_SCULPT) && G.debug_value == 128) { + result = multires_as_ccg(mmd, ctx, mesh, subdiv); + } + else { + result = multires_as_mesh(mmd, ctx, mesh, subdiv); + } /* TODO(sergey): Cache subdiv somehow. */ // BKE_subdiv_stats_print(&subdiv->stats); BKE_subdiv_free(subdiv); diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index ae9ffd076f7..deccec05190 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -44,6 +44,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_scene.h" #include "BKE_subdiv.h" +#include "BKE_subdiv_ccg.h" #include "BKE_subdiv_mesh.h" #include "BKE_subsurf.h" @@ -170,6 +171,8 @@ static void subdiv_settings_init(SubdivSettings *settings, BKE_subdiv_fvar_interpolation_from_uv_smooth(smd->uv_smooth); } +/* Subdivide into fully qualified mesh. */ + static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, const SubsurfModifierData *smd, const ModifierEvalContext *ctx) @@ -178,6 +181,50 @@ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, settings->resolution = (1 << level) + 1; } +static Mesh *subdiv_as_mesh(SubsurfModifierData *smd, + const ModifierEvalContext *ctx, + Mesh *mesh, + Subdiv *subdiv) +{ + Mesh *result = mesh; + SubdivToMeshSettings mesh_settings; + subdiv_mesh_settings_init(&mesh_settings, smd, ctx); + if (mesh_settings.resolution < 3) { + return result; + } + result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + return result; +} + +/* Subdivide into CCG. */ + +static void subdiv_ccg_settings_init(SubdivToCCGSettings *settings, + const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) +{ + const int level = subdiv_levels_for_modifier_get(smd, ctx); + settings->resolution = (1 << level) + 1; + settings->need_normal = true; + settings->need_mask = false; +} + +static Mesh *subdiv_as_ccg(SubsurfModifierData *smd, + const ModifierEvalContext *ctx, + Mesh *mesh, + Subdiv *subdiv) +{ + Mesh *result = mesh; + SubdivToCCGSettings ccg_settings; + subdiv_ccg_settings_init(&ccg_settings, smd, ctx); + if (ccg_settings.resolution < 3) { + return result; + } + result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh); + return result; +} + +/* Modifier itself. */ + static Mesh *applyModifier_subdiv(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) @@ -186,12 +233,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, SubsurfModifierData *smd = (SubsurfModifierData *) md; SubdivSettings subdiv_settings; subdiv_settings_init(&subdiv_settings, smd); - SubdivToMeshSettings mesh_settings; - subdiv_mesh_settings_init(&mesh_settings, smd, ctx); - if (subdiv_settings.level == 0 || mesh_settings.resolution < 3) { - /* NOTE: Shouldn't really happen, is supposed to be catched by - * isDisabled() callback. - */ + if (subdiv_settings.level == 0) { return result; } /* TODO(sergey): Try to re-use subdiv when possible. */ @@ -200,7 +242,15 @@ static Mesh *applyModifier_subdiv(ModifierData *md, /* Happens on bad topology, ut also on empty input mesh. */ return result; } - result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + /* TODO(sergey): Decide whether we ever want to use CCG for subsurf, + * maybe when it is a last modifier in the stack? + */ + if (true) { + result = subdiv_as_mesh(smd, ctx, mesh, subdiv); + } + else { + result = subdiv_as_ccg(smd, ctx, mesh, subdiv); + } /* TODO(sergey): Cache subdiv somehow. */ // BKE_subdiv_stats_print(&subdiv->stats); BKE_subdiv_free(subdiv); |