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.
This commit is contained in:
Sergey Sharybin 2018-07-17 18:09:18 +02:00
parent 433bb9bbcb
commit 5fd677c83c
4 changed files with 96 additions and 13 deletions

View File

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

View File

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

View File

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

View File

@ -35,8 +35,9 @@
#include <stddef.h>
#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,10 +184,74 @@ 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)
{
#ifdef WITH_OPENSUBDIV
@ -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,