Multires: Prepare for cached topology
Note that the actual caching is still disabled, since more tests is needed with more production-looking files.
This commit is contained in:
@@ -5393,6 +5393,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
BevelModifierData *bmd = (BevelModifierData *)md;
|
||||
bmd->clnordata.faceHash = NULL;
|
||||
}
|
||||
else if (md->type == eModifierType_Multires) {
|
||||
MultiresModifierData *mmd = (MultiresModifierData *)md;
|
||||
mmd->subdiv = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -949,6 +949,8 @@ typedef struct MultiresModifierData {
|
||||
short quality;
|
||||
short uv_smooth;
|
||||
short pad2[2];
|
||||
struct Subdiv *subdiv;
|
||||
void *pad3;
|
||||
} MultiresModifierData;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -67,6 +67,28 @@ static void initData(ModifierData *md)
|
||||
mmd->quality = 3;
|
||||
}
|
||||
|
||||
static void freeData(ModifierData *md)
|
||||
{
|
||||
MultiresModifierData *mmd = (MultiresModifierData *) md;
|
||||
if (mmd->subdiv != NULL) {
|
||||
BKE_subdiv_free(mmd->subdiv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Main goal of this function is to give usable subdivision surface descriptor
|
||||
* which matches settings and topology. */
|
||||
static Subdiv *subdiv_descriptor_ensure(MultiresModifierData *mmd,
|
||||
const SubdivSettings *subdiv_settings,
|
||||
const Mesh *mesh)
|
||||
{
|
||||
Subdiv *subdiv = BKE_subdiv_update_from_mesh(
|
||||
mmd->subdiv, subdiv_settings, mesh);
|
||||
if (false) {
|
||||
mmd->subdiv = subdiv;
|
||||
}
|
||||
return subdiv;
|
||||
}
|
||||
|
||||
/* Subdivide into fully qualified mesh. */
|
||||
|
||||
static Mesh *multires_as_mesh(MultiresModifierData *mmd,
|
||||
@@ -137,16 +159,14 @@ static Mesh *applyModifier(ModifierData *md,
|
||||
if (subdiv_settings.level == 0) {
|
||||
return result;
|
||||
}
|
||||
/* TODO(sergey): Try to re-use subdiv when possible. */
|
||||
Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh);
|
||||
Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
|
||||
if (subdiv == NULL) {
|
||||
/* Happens on bad topology, ut also on empty input mesh. */
|
||||
return result;
|
||||
}
|
||||
/* NOTE: Orco needs final coordinates on CPU side, which are expected to be
|
||||
* accessible via MVert. For this reason we do not evaluate multires to
|
||||
* grids when orco is requested.
|
||||
*/
|
||||
* grids when orco is requested. */
|
||||
const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
|
||||
if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
|
||||
/* NOTE: CCG takes ownership over Subdiv. */
|
||||
@@ -156,9 +176,10 @@ static Mesh *applyModifier(ModifierData *md,
|
||||
}
|
||||
else {
|
||||
result = multires_as_mesh(mmd, ctx, mesh, subdiv);
|
||||
/* TODO(sergey): Cache subdiv somehow. */
|
||||
// BKE_subdiv_stats_print(&subdiv->stats);
|
||||
BKE_subdiv_free(subdiv);
|
||||
if (subdiv != mmd->subdiv) {
|
||||
BKE_subdiv_free(subdiv);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -188,7 +209,7 @@ ModifierTypeInfo modifierType_Multires = {
|
||||
|
||||
/* initData */ initData,
|
||||
/* requiredDataMask */ NULL,
|
||||
/* freeData */ NULL,
|
||||
/* freeData */ freeData,
|
||||
/* isDisabled */ NULL,
|
||||
/* updateDepsgraph */ NULL,
|
||||
/* dependsOnTime */ NULL,
|
||||
|
||||
Reference in New Issue
Block a user