Sculpt: Multires

* Displacement coordinates are now stored differently, as a grid per
  face corner. This means there is duplication of coordinates, especially
  at low subdivision levels, but the simpler implementation justifies it
  I think.
* ToDo: conversion of existing multires files (2.4x or 2.5x), loading them
  may even crash now.
* Editmode preservation/interpolation code also has not been updated yet.

* Multires now works on the CCGDerivedMesh grids instead of CDDerivedMesh,
  which should be more memory efficient.
* There are still bad memory peaks (if you're using 32bit) when subdividing
  or propagating displacements. Though at least there should be no huge
  memory blocks allocated, which windows is now to have trouble with.
* Still found some weird spike artifacts at lower multires levels, some also
  happening before this commit. Perhaps computation of tangents needs to be
  tweaked more.

* Multires modifier now has viewport, sculpt and render levels. Also the
  levels have been made consistent with subsurf, previously the same level
  of subdivision was one less for multires.
* Both multires and subsurf modifier now can have their subdivision level
  set to 0 for no subdivision.
This commit is contained in:
Brecht Van Lommel 2009-11-25 14:07:12 +00:00
parent 134935a8db
commit fffce6c554
15 changed files with 602 additions and 1296 deletions

View File

@ -228,7 +228,7 @@ typedef struct ModifierTypeInfo {
*
* This function is optional (assumes never disabled if not present).
*/
int (*isDisabled)(struct ModifierData *md);
int (*isDisabled)(struct ModifierData *md, int userRenderParams);
/* Add the appropriate relations to the DEP graph depending on the
* modifier data.

View File

@ -39,23 +39,6 @@ typedef struct MultiresSubsurf {
int local_mmd;
} MultiresSubsurf;
/* MultiresDM */
struct Object *MultiresDM_get_object(struct DerivedMesh *dm);
struct Mesh *MultiresDM_get_mesh(struct DerivedMesh *dm);
struct DerivedMesh *MultiresDM_new(struct MultiresSubsurf *, struct DerivedMesh*, int, int, int);
void *MultiresDM_get_vertnorm(struct DerivedMesh *);
void *MultiresDM_get_orco(struct DerivedMesh *);
struct MVert *MultiresDM_get_subco(struct DerivedMesh *);
struct ListBase *MultiresDM_get_vert_face_map(struct DerivedMesh *);
struct ListBase *MultiresDM_get_vert_edge_map(struct DerivedMesh *);
int *MultiresDM_get_face_offsets(struct DerivedMesh *);
int MultiresDM_get_totlvl(struct DerivedMesh *);
int MultiresDM_get_lvl(struct DerivedMesh *);
void MultiresDM_set_update(struct DerivedMesh *, void (*)(struct DerivedMesh*));
/* The displacements will only be updated when
the MultiresDM has been marked as modified */
void MultiresDM_mark_as_modified(struct DerivedMesh *);
void multires_mark_as_modified(struct Object *ob);
void multires_force_update(struct Object *ob);
@ -64,10 +47,9 @@ struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*
struct Object *, int, int);
struct MultiresModifierData *find_multires_modifier(struct Object *ob);
int multiresModifier_switch_level(struct Object *, const int);
void multiresModifier_join(struct Object *);
void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);
void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int distance,
void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob,
int updateblock, int simple);
int multiresModifier_reshape(struct MultiresModifierData *mmd, struct Object *dst, struct Object *src);

View File

@ -1535,7 +1535,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
md->scene= scene;
if (!(md->mode&eModifierMode_Realtime)) return NULL;
if (mti->isDisabled && mti->isDisabled(md)) return NULL;
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
if (mti->type==eModifierTypeType_OnlyDeform) {
int numVerts;

View File

@ -1810,215 +1810,3 @@ MFace *CDDM_get_faces(DerivedMesh *dm)
return ((CDDerivedMesh*)dm)->mface;
}
/* Multires DerivedMesh, extends CDDM */
typedef struct MultiresDM {
CDDerivedMesh cddm;
MultiresModifierData *mmd;
int local_mmd;
int lvl, totlvl;
float (*orco)[3];
MVert *subco;
ListBase *vert_face_map, *vert_edge_map;
IndexNode *vert_face_map_mem, *vert_edge_map_mem;
int *face_offsets;
Object *ob;
int modified;
void (*update)(DerivedMesh*);
} MultiresDM;
static void MultiresDM_release(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
int mvert_layer;
/* Before freeing, need to update the displacement map */
if(dm->needsFree && mrdm->modified) {
/* Check that mmd still exists */
if(!mrdm->local_mmd && BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0)
mrdm->mmd = NULL;
if(mrdm->mmd)
mrdm->update(dm);
}
/* If the MVert data is being used as the sculpt undo store, don't free it */
mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
if(mvert_layer != -1) {
CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts)
cd->flag |= CD_FLAG_NOFREE;
}
if(DM_release(dm)) {
cdDM_free_internal(&mrdm->cddm);
MEM_freeN(mrdm->subco);
MEM_freeN(mrdm->orco);
if(mrdm->vert_face_map)
MEM_freeN(mrdm->vert_face_map);
if(mrdm->vert_face_map_mem)
MEM_freeN(mrdm->vert_face_map_mem);
if(mrdm->vert_edge_map)
MEM_freeN(mrdm->vert_edge_map);
if(mrdm->vert_edge_map_mem)
MEM_freeN(mrdm->vert_edge_map_mem);
if(mrdm->face_offsets)
MEM_freeN(mrdm->face_offsets);
MEM_freeN(mrdm);
}
}
DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
{
MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
DerivedMesh *dm = NULL;
mrdm->cddm = *cddm;
MEM_freeN(cddm);
dm = &mrdm->cddm.dm;
mrdm->mmd = ms->mmd;
mrdm->ob = ms->ob;
mrdm->local_mmd = ms->local_mmd;
if(dm) {
MDisps *disps;
MVert *mvert;
int i;
DM_from_template(dm, orig, numVerts, numEdges, numFaces);
CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
if(disps)
CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
for(i = 0; i < orig->getNumVerts(orig); ++i)
copy_v3_v3(mrdm->orco[i], mvert[i].co);
}
else
DM_init(dm, numVerts, numEdges, numFaces);
if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
mrdm->lvl = ms->mmd->lvl;
mrdm->totlvl = ms->mmd->totlvl;
mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
mrdm->modified = 0;
dm->release = MultiresDM_release;
return dm;
}
Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
{
return get_mesh(((MultiresDM*)dm)->ob);
}
Object *MultiresDM_get_object(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->ob;
}
void *MultiresDM_get_orco(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->orco;
}
MVert *MultiresDM_get_subco(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->subco;
}
int MultiresDM_get_totlvl(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->totlvl;
}
int MultiresDM_get_lvl(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->lvl;
}
void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
{
((MultiresDM*)dm)->orco = orco;
}
void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
{
((MultiresDM*)dm)->update = update;
}
ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
Mesh *me = mrdm->ob->data;
if(!mrdm->vert_face_map)
create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface,
me->totvert, me->totface);
return mrdm->vert_face_map;
}
ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
Mesh *me = mrdm->ob->data;
if(!mrdm->vert_edge_map)
create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge,
me->totvert, me->totedge);
return mrdm->vert_edge_map;
}
int *MultiresDM_get_face_offsets(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
Mesh *me = mrdm->ob->data;
int i, accum = 0;
if(!mrdm->face_offsets) {
int len = (int)pow(2, mrdm->lvl - 2) - 1;
int area = len * len;
int t = 1 + len * 3 + area * 3, q = t + len + area;
mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets");
for(i = 0; i < me->totface; ++i) {
mrdm->face_offsets[i] = accum;
accum += (me->mface[i].v4 ? q : t);
}
}
return mrdm->face_offsets;
}
void MultiresDM_mark_as_modified(DerivedMesh *dm)
{
((MultiresDM*)dm)->modified = 1;
}

View File

@ -381,6 +381,7 @@ static void layerDefault_origspace_face(void *data, int count)
osf[i] = default_osf;
}
#if 0
/* Adapted from sculptmode.c */
static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
{
@ -426,9 +427,12 @@ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, fl
add_v3_v3v3(out, d2[0], d2[1]);
}
#endif
static void layerSwap_mdisps(void *data, int *ci)
{
// XXX
#if 0
MDisps *s = data;
float (*d)[3] = NULL;
int x, y, st;
@ -447,11 +451,14 @@ static void layerSwap_mdisps(void *data, int *ci)
if(s->disps)
MEM_freeN(s->disps);
s->disps = d;
#endif
}
static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
int count, void *dest)
{
// XXX
#if 0
MDisps *d = dest;
MDisps *s = NULL;
int st, stl;
@ -496,6 +503,7 @@ static void layerInterp_mdisps(void **sources, float *weights, float *sub_weight
copy_v3_v3(d->disps[y * st + x], srcdisp);
}
}
#endif
}
static void layerCopy_mdisps(const void *source, void *dest, int count)

View File

@ -1225,7 +1225,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
preTesselatePoint = md;
@ -1275,7 +1275,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
md->scene= scene;
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform) continue;
if (!deformedVerts) {
@ -1330,7 +1330,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
md->scene= scene;
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
/* need to put all verts in 1 block for curve deform */

View File

@ -1002,7 +1002,7 @@ void lattice_calc_modifiers(Scene *scene, Object *ob)
if (!(md->mode&eModifierMode_Realtime)) continue;
if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform) continue;
if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);

View File

@ -187,7 +187,7 @@ static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)
/***/
static int noneModifier_isDisabled(ModifierData *md)
static int noneModifier_isDisabled(ModifierData *md, int userRenderParams)
{
return 1;
}
@ -222,7 +222,7 @@ static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *m
return dataMask;
}
static int curveModifier_isDisabled(ModifierData *md)
static int curveModifier_isDisabled(ModifierData *md, int userRenderParams)
{
CurveModifierData *cmd = (CurveModifierData*) md;
@ -298,7 +298,7 @@ static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData
return dataMask;
}
static int latticeModifier_isDisabled(ModifierData *md)
static int latticeModifier_isDisabled(ModifierData *md, int userRenderParams)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
@ -402,6 +402,13 @@ static void subsurfModifier_freeData(ModifierData *md)
}
}
static int subsurfModifier_isDisabled(ModifierData *md, int useRenderParams)
{
SubsurfModifierData *smd = (SubsurfModifierData*) md;
return (useRenderParams)? (smd->renderLevels == 0): (smd->levels == 0);
}
static DerivedMesh *subsurfModifier_applyModifier(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
int useRenderParams, int isFinalCalc)
@ -410,8 +417,13 @@ static DerivedMesh *subsurfModifier_applyModifier(
DerivedMesh *result;
result = subsurf_make_derived_from_derived(derivedData, smd,
useRenderParams, NULL,
isFinalCalc, 0);
useRenderParams, NULL, isFinalCalc, 0);
if(useRenderParams || !isFinalCalc) {
DerivedMesh *cddm= CDDM_copy(result);
result->release(result);
result= cddm;
}
return result;
}
@ -3524,7 +3536,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob,
displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static int displaceModifier_isDisabled(ModifierData *md)
static int displaceModifier_isDisabled(ModifierData *md, int useRenderParams)
{
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
@ -4268,7 +4280,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
}
static int smoothModifier_isDisabled(ModifierData *md)
static int smoothModifier_isDisabled(ModifierData *md, int useRenderParams)
{
SmoothModifierData *smd = (SmoothModifierData*) md;
short flag;
@ -4498,7 +4510,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
}
static int castModifier_isDisabled(ModifierData *md)
static int castModifier_isDisabled(ModifierData *md, int useRenderParams)
{
CastModifierData *cmd = (CastModifierData*) md;
short flag;
@ -5487,7 +5499,7 @@ static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData
return dataMask;
}
static int armatureModifier_isDisabled(ModifierData *md)
static int armatureModifier_isDisabled(ModifierData *md, int useRenderParams)
{
ArmatureModifierData *amd = (ArmatureModifierData*) md;
@ -5610,7 +5622,7 @@ static void hookModifier_freeData(ModifierData *md)
if (hmd->indexar) MEM_freeN(hmd->indexar);
}
static int hookModifier_isDisabled(ModifierData *md)
static int hookModifier_isDisabled(ModifierData *md, int useRenderParams)
{
HookModifierData *hmd = (HookModifierData*) md;
@ -6308,7 +6320,7 @@ static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
tbmd->operation = bmd->operation;
}
static int booleanModifier_isDisabled(ModifierData *md)
static int booleanModifier_isDisabled(ModifierData *md, int useRenderParams)
{
BooleanModifierData *bmd = (BooleanModifierData*) md;
@ -7757,7 +7769,7 @@ static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierDa
return dataMask;
}
static int meshdeformModifier_isDisabled(ModifierData *md)
static int meshdeformModifier_isDisabled(ModifierData *md, int useRenderParams)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
@ -8047,15 +8059,10 @@ static void multiresModifier_initData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
mmd->lvl = mmd->totlvl = 1;
}
static void multiresModifier_freeData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
if(mmd->undo_verts)
MEM_freeN(mmd->undo_verts);
mmd->lvl = 0;
mmd->sculptlvl = 0;
mmd->renderlvl = 0;
mmd->totlvl = 0;
}
static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
@ -8063,37 +8070,35 @@ static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
MultiresModifierData *mmd = (MultiresModifierData*) md;
MultiresModifierData *tmmd = (MultiresModifierData*) target;
tmmd->totlvl = mmd->totlvl;
tmmd->lvl = mmd->lvl;
tmmd->sculptlvl = mmd->sculptlvl;
tmmd->renderlvl = mmd->renderlvl;
tmmd->totlvl = mmd->totlvl;
}
static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
int useRenderParams, int isFinalCalc)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
DerivedMesh *final;
DerivedMesh *result;
/* TODO: for now just skip a level1 mesh */
if(mmd->lvl == 1)
result = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
if(result == dm)
return dm;
final = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
int i;
MVert *dst = CDDM_get_verts(final);
for(i = 0; i < mmd->undo_verts_tot; ++i) {
copy_v3_v3(dst[i].co, mmd->undo_verts[i].co);
}
CDDM_calc_normals(final);
MultiresDM_mark_as_modified(final);
MEM_freeN(mmd->undo_verts);
mmd->undo_signal = 0;
mmd->undo_verts = NULL;
if(useRenderParams || !isFinalCalc) {
DerivedMesh *cddm= CDDM_copy(result);
result->release(result);
result= cddm;
}
else if(ob->mode & OB_MODE_SCULPT) {
/* would be created on the fly too, just nicer this
way on first stroke after e.g. switching levels */
result->getPBVH(ob, result);
}
return final;
return result;
}
/* Shrinkwrap */
@ -8142,7 +8147,7 @@ static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierDa
return dataMask;
}
static int shrinkwrapModifier_isDisabled(ModifierData *md)
static int shrinkwrapModifier_isDisabled(ModifierData *md, int useRenderParams)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
return !smd->target;
@ -8438,6 +8443,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->initData = subsurfModifier_initData;
mti->copyData = subsurfModifier_copyData;
mti->freeData = subsurfModifier_freeData;
mti->isDisabled = subsurfModifier_isDisabled;
mti->applyModifier = subsurfModifier_applyModifier;
mti->applyModifierEM = subsurfModifier_applyModifierEM;
@ -8770,7 +8776,6 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
mti->initData = multiresModifier_initData;
mti->freeData = multiresModifier_freeData;
mti->copyData = multiresModifier_copyData;
mti->applyModifier = multiresModifier_applyModifier;
@ -8920,7 +8925,7 @@ int modifier_couldBeCage(ModifierData *md)
return ( (md->mode & eModifierMode_Realtime) &&
(md->mode & eModifierMode_Editmode) &&
(!mti->isDisabled || !mti->isDisabled(md)) &&
(!mti->isDisabled || !mti->isDisabled(md, 0)) &&
modifier_supportsMapping(md));
}
@ -8957,7 +8962,7 @@ int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual
if (!(md->mode & eModifierMode_Realtime)) continue;
if (!(md->mode & eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
if (md->mode & eModifierMode_DisableTemporary) continue;
@ -8999,7 +9004,7 @@ int modifier_isEnabled(ModifierData *md, int required_mode)
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if((md->mode & required_mode) != required_mode) return 0;
if(mti->isDisabled && mti->isDisabled(md)) return 0;
if(mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return 0;
if(md->mode & eModifierMode_DisableTemporary) return 0;
if(required_mode & eModifierMode_Editmode)
if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;

File diff suppressed because it is too large Load Diff

View File

@ -3922,12 +3922,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
SWITCH_INT(mmd->dynverts[a])
}
}
else if (md->type==eModifierType_Multires) {
MultiresModifierData *mmd = (MultiresModifierData*) md;
mmd->undo_verts = newdataadr(fd, mmd->undo_verts);
mmd->undo_signal = !!mmd->undo_verts;
}
}
}
@ -9595,7 +9589,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ToolSettings *ts;
//PTCacheID *pid;
//ListBase pidlist;
int i, a;
int /*i, */a;
for(ob = main->object.first; ob; ob = ob->id.next) {
//BKE_ptcache_ids_from_object(&pidlist, ob);
@ -9613,6 +9607,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ob->data = me;
if(me && me->id.lib==NULL && me->mr) { /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid - Campbell */
// XXX
#if 0
MultiresLevel *lvl;
ModifierData *md;
MultiresModifierData *mmd;
@ -9648,7 +9644,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
BLI_insertlinkbefore(&ob->modifiers, md, mmd);
multiresModifier_subdivide(mmd, ob, me->mr->level_count - 1, 1, 0);
for(i = 0; i < me->mr->level_count - 1; ++i)
multiresModifier_subdivide(mmd, ob, 1, 0);
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me, NULL);
@ -9662,6 +9659,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* Remove the old multires */
multires_free(me->mr);
#endif
me->mr = NULL;
}

View File

@ -1214,12 +1214,6 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
}
else if (md->type==eModifierType_Multires) {
MultiresModifierData *mmd = (MultiresModifierData*) md;
if(mmd->undo_verts)
writestruct(wd, DATA, "MVert", mmd->undo_verts_tot, mmd->undo_verts);
}
}
}

View File

@ -373,7 +373,7 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return 0;
}
@ -684,6 +684,13 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
/************* multires delete higher levels operator ****************/
static int multires_poll(bContext *C)
{
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
ID *id= ptr.id.data;
return (ptr.data && id && !id->lib);
}
static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
@ -702,8 +709,8 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
{
ot->name= "Delete Higher Levels";
ot->idname= "OBJECT_OT_multires_higher_levels_delete";
ot->poll= ED_operator_object_active;
ot->poll= multires_poll;
ot->exec= multires_higher_levels_delete_exec;
/* flags */
@ -718,7 +725,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
Object *ob= ptr.id.data;
MultiresModifierData *mmd= ptr.data;
multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);

View File

@ -2027,13 +2027,13 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
//MultiresModifierData *mmd = sculpt_multires_active(ob);
MultiresModifierData *mmd = sculpt_multires_active(ob);
if(ob->mode & OB_MODE_SCULPT) {
multires_force_update(ob);
/*if(mmd && mmd->sculptlvl != mmd->lvl)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);*/
if(mmd && mmd->sculptlvl != mmd->lvl)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* Leave sculptmode */
ob->mode &= ~OB_MODE_SCULPT;
@ -2044,8 +2044,8 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
/* Enter sculptmode */
ob->mode |= OB_MODE_SCULPT;
/*if(mmd && mmd->sculptlvl != mmd->lvl)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);*/
if(mmd && mmd->sculptlvl != mmd->lvl)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* Create persistent sculpt mode data */
if(!ts->sculpt)

View File

@ -581,12 +581,8 @@ typedef struct ExplodeModifierData {
typedef struct MultiresModifierData {
ModifierData modifier;
struct MVert *undo_verts; /* Store DerivedMesh vertices for multires undo */
int undo_verts_tot; /* Length of undo_verts array */
char undo_signal; /* If true, signals to replace verts with undo verts */
char lvl, totlvl;
char simple;
char lvl, sculptlvl, renderlvl, totlvl;
char simple, pad[3];
} MultiresModifierData;
typedef struct FluidsimModifierData {

View File

@ -39,6 +39,7 @@
#include "BKE_animsys.h"
#include "BKE_bmesh.h" /* For BevelModifierData */
#include "BKE_global.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
#include "WM_api.h"
@ -335,10 +336,36 @@ static void rna_MultiresModifier_level_range(PointerRNA *ptr, int *min, int *max
{
MultiresModifierData *mmd = (MultiresModifierData*)ptr->data;
*min = 1;
*min = 0;
*max = mmd->totlvl;
}
/*static int rna_MultiresModifier_external_get(PointerRNA *ptr)
{
Object *ob= (Object*)ptr->id.data;
Mesh *me= ob->data;
return CustomData_external_test(&me->fdata, CD_MDISPS);
}
static void rna_MultiresModifier_external_set(PointerRNA *ptr, int value)
{
Object *ob= (Object*)ptr->id.data;
Mesh *me= ob->data;
if(CustomData_external_test(&me->fdata, CD_MDISPS) && !value)
CustomData_external_remove(&me->fdata, CD_MDISPS, me->totface);
else if(!CustomData_external_test(&me->fdata, CD_MDISPS) && value)
CustomData_external_add(&me->fdata, CD_MDISPS, me->id.name+2, me->totface);
}
static int rna_MultiresModifier_external_editable(PointerRNA *ptr)
{
MultiresModifierData *mmd = ptr->data;
return (G.save_over && mmd->totlvl > 0);
}*/
static void modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value)
{
Object *ob= value.data;
@ -487,17 +514,15 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna)
rna_def_property_subdivision_common(srna, "subdivType");
prop= RNA_def_property(srna, "levels", PROP_INT, PROP_NONE);
prop= RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "levels");
RNA_def_property_range(prop, 1, 6);
RNA_def_property_ui_range(prop, 1, 6, 1, 0);
RNA_def_property_ui_range(prop, 0, 6, 1, 0);
RNA_def_property_ui_text(prop, "Levels", "Number of subdivisions to perform.");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_NONE);
prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "renderLevels");
RNA_def_property_range(prop, 1, 6);
RNA_def_property_ui_range(prop, 1, 6, 1, 0);
RNA_def_property_ui_range(prop, 0, 6, 1, 0);
RNA_def_property_ui_text(prop, "Render Levels", "Number of subdivisions to perform when rendering.");
prop= RNA_def_property(srna, "optimal_draw", PROP_BOOLEAN, PROP_NONE);
@ -523,11 +548,32 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
rna_def_property_subdivision_common(srna, "simple");
prop= RNA_def_property(srna, "level", PROP_INT, PROP_NONE);
prop= RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "lvl");
RNA_def_property_ui_text(prop, "Level", "");
RNA_def_property_ui_text(prop, "Levels", "Number of subdivisions to use in the viewport.");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop= RNA_def_property(srna, "sculpt_levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "sculptlvl");
RNA_def_property_ui_text(prop, "Sculpt Levels", "Number of subdivisions to use in sculpt mode.");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "renderlvl");
RNA_def_property_ui_text(prop, "Render Levels", "");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
prop= RNA_def_property(srna, "total_levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "totlvl");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Total Levels", "Number of subdivisions for which displacements are stored.");
/*prop= RNA_def_property(srna, "external", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", "rna_MultiresModifier_external_set");
RNA_def_property_editable_func(prop, "rna_MultiresModifier_external_editable");
RNA_def_property_ui_text(prop, "External", "Store multires displacements outside the .blend file, to save memory.");*/
}
static void rna_def_modifier_lattice(BlenderRNA *brna)