From 5fd677c83c80aa33cac9f4fe47dc149e61b96f67 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jul 2018 18:09:18 +0200 Subject: Subsurf: Add subdivision code which uses new module The code is ifdef-ed for now, since there is more work needed to be done before we can officially switch to it. Uses new subdiv module. --- source/blender/blenkernel/CMakeLists.txt | 9 +++- source/blender/makesdna/DNA_modifier_types.h | 19 ++++--- source/blender/makesrna/intern/rna_modifier.c | 4 +- source/blender/modifiers/intern/MOD_subsurf.c | 75 ++++++++++++++++++++++++++- 4 files changed, 95 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0578a3ecc69..0517eb8e732 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -186,6 +186,11 @@ set(SRC intern/sound.c intern/speaker.c intern/studiolight.c + intern/subdiv.c + intern/subdiv_converter.c + intern/subdiv_converter_mesh.c + intern/subdiv_eval.c + intern/subdiv_mesh.c intern/subsurf_ccg.c intern/suggestions.c intern/text.c @@ -306,6 +311,7 @@ set(SRC BKE_sound.h BKE_speaker.h BKE_studiolight.h + BKE_subdiv.h BKE_subsurf.h BKE_suggestions.h BKE_text.h @@ -323,8 +329,9 @@ set(SRC intern/CCGSubSurf.h intern/CCGSubSurf_inline.h intern/CCGSubSurf_intern.h - intern/pbvh_intern.h intern/data_transfer_intern.h + intern/pbvh_intern.h + intern/subdiv_converter.h ) if(WITH_BINRELOC) diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ecece648ce1..803be15f03e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -123,13 +123,6 @@ typedef enum { eModifierFlag_SharedCaches = (1 << 1), } ModifierFlag; -typedef enum { - eSubsurfModifierFlag_Incremental = (1 << 0), - eSubsurfModifierFlag_DebugIncr = (1 << 1), - eSubsurfModifierFlag_ControlEdges = (1 << 2), - eSubsurfModifierFlag_SubsurfUv = (1 << 3), -} SubsurfModifierFlag; - /* not a real modifier */ typedef struct MappingInfoModifierData { ModifierData modifier; @@ -141,6 +134,18 @@ typedef struct MappingInfoModifierData { int texmapping; } MappingInfoModifierData; +typedef enum { + eSubsurfModifierFlag_Incremental = (1 << 0), + eSubsurfModifierFlag_DebugIncr = (1 << 1), + eSubsurfModifierFlag_ControlEdges = (1 << 2), + eSubsurfModifierFlag_SubsurfUv = (1 << 3), +} SubsurfModifierFlag; + +typedef enum { + SUBSURF_TYPE_CATMULL_CLARK = 0, + SUBSURF_TYPE_SIMPLE = 1, +} eSubsurfModifierType; + typedef struct SubsurfModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 57b12d6a3fd..d90a578d9f2 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1175,8 +1175,8 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr, co static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) { static const EnumPropertyItem prop_subdivision_type_items[] = { - {0, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, - {1, "SIMPLE", 0, "Simple", ""}, + {SUBSURF_TYPE_CATMULL_CLARK, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, + {SUBSURF_TYPE_SIMPLE, "SIMPLE", 0, "Simple", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index f532c168b04..c92845a24eb 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -35,8 +35,9 @@ #include -#include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_mesh_types.h" #ifdef WITH_OPENSUBDIV # include "DNA_userdef_types.h" @@ -44,9 +45,9 @@ #include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" #include "BKE_scene.h" +#include "BKE_subdiv.h" #include "BKE_subsurf.h" #include "DEG_depsgraph.h" @@ -56,6 +57,8 @@ #include "intern/CCGSubSurf.h" +// #define USE_OPENSUBDIV + static void initData(ModifierData *md) { SubsurfModifierData *smd = (SubsurfModifierData *) md; @@ -181,9 +184,73 @@ static DerivedMesh *applyModifierEM( #endif result = subsurf_make_derived_from_derived(derivedData, smd, scene, NULL, ss_flags); + return result; +} + +#ifdef USE_OPENSUBDIV +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); +} + +static void subdiv_settings_init(SubdivSettings *settings, + const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) +{ + settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); + settings->is_adaptive = !settings->is_simple; + settings->level = subdiv_levels_for_modifier_get(smd, ctx); + settings->fvar_linear_interpolation = + (smd->flags & eSubsurfModifierFlag_SubsurfUv) + ? SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY + : SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; +} + +static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, + const SubdivSettings *subdiv_settings) +{ + settings->resolution = (1 << subdiv_settings->level) + 1; +} +static Mesh *applyModifier_subdiv(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh) +{ + Mesh *result = mesh; + SubsurfModifierData *smd = (SubsurfModifierData *) md; + SubdivSettings subdiv_settings; + subdiv_settings_init(&subdiv_settings, smd, ctx); + 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. */ + /* TODO(sergey): This also happens on meshes without faces, so probably + * need to handle those differently (i.e. set modifier error when + * topology itself is bad, and not do anything when there are no faces). + */ + return result; + } + SubdivToMeshSettings mesh_settings; + subdiv_mesh_settings_init(&mesh_settings, &subdiv_settings); + result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + /* TODO(sergey): Cache subdiv somehow. */ + BKE_subdiv_free(subdiv); return result; } +#endif static bool dependsOnNormals(ModifierData *md) { @@ -222,7 +289,11 @@ ModifierTypeInfo modifierType_Subsurf = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, +#ifdef USE_OPENSUBDIV + /* applyModifier */ applyModifier_subdiv, +#else /* applyModifier */ NULL, +#endif /* applyModifierEM */ NULL, /* initData */ initData, -- cgit v1.2.3