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!
This commit is contained in:
Sergey Sharybin 2018-08-14 12:17:10 +02:00
parent d7ae76fa35
commit 5e696fdcd6
6 changed files with 104 additions and 35 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)
{

View File

@ -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,

View File

@ -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,