2.5 Multires:
* Fixed a memory corruption bug when deleting a multiresmodifier, was hanging on to a bad pointer. Reported on IRC by lusque
This commit is contained in:
@@ -35,10 +35,11 @@ struct Object;
|
|||||||
|
|
||||||
typedef struct MultiresSubsurf {
|
typedef struct MultiresSubsurf {
|
||||||
struct MultiresModifierData *mmd;
|
struct MultiresModifierData *mmd;
|
||||||
struct Mesh *me;
|
struct Object *ob;
|
||||||
} MultiresSubsurf;
|
} MultiresSubsurf;
|
||||||
|
|
||||||
/* MultiresDM */
|
/* MultiresDM */
|
||||||
|
struct Object *MultiresDM_get_object(struct DerivedMesh *dm);
|
||||||
struct Mesh *MultiresDM_get_mesh(struct DerivedMesh *dm);
|
struct Mesh *MultiresDM_get_mesh(struct DerivedMesh *dm);
|
||||||
struct DerivedMesh *MultiresDM_new(struct MultiresSubsurf *, struct DerivedMesh*, int, int, int);
|
struct DerivedMesh *MultiresDM_new(struct MultiresSubsurf *, struct DerivedMesh*, int, int, int);
|
||||||
void *MultiresDM_get_vertnorm(struct DerivedMesh *);
|
void *MultiresDM_get_vertnorm(struct DerivedMesh *);
|
||||||
@@ -59,7 +60,7 @@ void multires_mark_as_modified(struct Object *ob);
|
|||||||
void multires_force_update(struct Object *ob);
|
void multires_force_update(struct Object *ob);
|
||||||
|
|
||||||
struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, struct DerivedMesh*,
|
struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, struct DerivedMesh*,
|
||||||
struct Mesh *, int, int);
|
struct Object *, int, int);
|
||||||
|
|
||||||
struct MultiresModifierData *find_multires_modifier(struct Object *ob);
|
struct MultiresModifierData *find_multires_modifier(struct Object *ob);
|
||||||
int multiresModifier_switch_level(struct Object *, const int);
|
int multiresModifier_switch_level(struct Object *, const int);
|
||||||
|
|||||||
@@ -1297,7 +1297,7 @@ typedef struct MultiresDM {
|
|||||||
IndexNode *vert_face_map_mem, *vert_edge_map_mem;
|
IndexNode *vert_face_map_mem, *vert_edge_map_mem;
|
||||||
int *face_offsets;
|
int *face_offsets;
|
||||||
|
|
||||||
Mesh *me;
|
Object *ob;
|
||||||
int modified;
|
int modified;
|
||||||
|
|
||||||
void (*update)(DerivedMesh*);
|
void (*update)(DerivedMesh*);
|
||||||
@@ -1308,15 +1308,19 @@ static void MultiresDM_release(DerivedMesh *dm)
|
|||||||
MultiresDM *mrdm = (MultiresDM*)dm;
|
MultiresDM *mrdm = (MultiresDM*)dm;
|
||||||
int mvert_layer;
|
int mvert_layer;
|
||||||
|
|
||||||
|
/* Check that mmd still exists */
|
||||||
|
if(BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0)
|
||||||
|
mrdm->mmd = NULL;
|
||||||
|
|
||||||
/* Before freeing, need to update the displacement map */
|
/* Before freeing, need to update the displacement map */
|
||||||
if(dm->needsFree && mrdm->modified)
|
if(dm->needsFree && mrdm->modified && mrdm->mmd)
|
||||||
mrdm->update(dm);
|
mrdm->update(dm);
|
||||||
|
|
||||||
/* If the MVert data is being used as the sculpt undo store, don't free it */
|
/* 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);
|
mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
|
||||||
if(mvert_layer != -1) {
|
if(mvert_layer != -1) {
|
||||||
CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
|
CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
|
||||||
if(cd->data == mrdm->mmd->undo_verts)
|
if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts)
|
||||||
cd->flag |= CD_FLAG_NOFREE;
|
cd->flag |= CD_FLAG_NOFREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,7 +1352,7 @@ DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts
|
|||||||
dm = &mrdm->cddm.dm;
|
dm = &mrdm->cddm.dm;
|
||||||
|
|
||||||
mrdm->mmd = ms->mmd;
|
mrdm->mmd = ms->mmd;
|
||||||
mrdm->me = ms->me;
|
mrdm->ob = ms->ob;
|
||||||
|
|
||||||
if(dm) {
|
if(dm) {
|
||||||
MDisps *disps;
|
MDisps *disps;
|
||||||
@@ -1391,7 +1395,12 @@ DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts
|
|||||||
|
|
||||||
Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
|
Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
return ((MultiresDM*)dm)->me;
|
return get_mesh(((MultiresDM*)dm)->ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *MultiresDM_get_object(DerivedMesh *dm)
|
||||||
|
{
|
||||||
|
return ((MultiresDM*)dm)->ob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *MultiresDM_get_orco(DerivedMesh *dm)
|
void *MultiresDM_get_orco(DerivedMesh *dm)
|
||||||
@@ -1428,10 +1437,11 @@ void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
|
|||||||
ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
|
ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
MultiresDM *mrdm = (MultiresDM*)dm;
|
MultiresDM *mrdm = (MultiresDM*)dm;
|
||||||
|
Mesh *me = mrdm->ob->data;
|
||||||
|
|
||||||
if(!mrdm->vert_face_map)
|
if(!mrdm->vert_face_map)
|
||||||
create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, mrdm->me->mface,
|
create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface,
|
||||||
mrdm->me->totvert, mrdm->me->totface);
|
me->totvert, me->totface);
|
||||||
|
|
||||||
return mrdm->vert_face_map;
|
return mrdm->vert_face_map;
|
||||||
}
|
}
|
||||||
@@ -1439,10 +1449,11 @@ ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
|
|||||||
ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
|
ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
MultiresDM *mrdm = (MultiresDM*)dm;
|
MultiresDM *mrdm = (MultiresDM*)dm;
|
||||||
|
Mesh *me = mrdm->ob->data;
|
||||||
|
|
||||||
if(!mrdm->vert_edge_map)
|
if(!mrdm->vert_edge_map)
|
||||||
create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, mrdm->me->medge,
|
create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge,
|
||||||
mrdm->me->totvert, mrdm->me->totedge);
|
me->totvert, me->totedge);
|
||||||
|
|
||||||
return mrdm->vert_edge_map;
|
return mrdm->vert_edge_map;
|
||||||
}
|
}
|
||||||
@@ -1450,6 +1461,7 @@ ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
|
|||||||
int *MultiresDM_get_face_offsets(DerivedMesh *dm)
|
int *MultiresDM_get_face_offsets(DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
MultiresDM *mrdm = (MultiresDM*)dm;
|
MultiresDM *mrdm = (MultiresDM*)dm;
|
||||||
|
Mesh *me = mrdm->ob->data;
|
||||||
int i, accum = 0;
|
int i, accum = 0;
|
||||||
|
|
||||||
if(!mrdm->face_offsets) {
|
if(!mrdm->face_offsets) {
|
||||||
@@ -1457,11 +1469,11 @@ int *MultiresDM_get_face_offsets(DerivedMesh *dm)
|
|||||||
int area = len * len;
|
int area = len * len;
|
||||||
int t = 1 + len * 3 + area * 3, q = t + len + area;
|
int t = 1 + len * 3 + area * 3, q = t + len + area;
|
||||||
|
|
||||||
mrdm->face_offsets = MEM_callocN(sizeof(int) * mrdm->me->totface, "mrdm face offsets");
|
mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets");
|
||||||
for(i = 0; i < mrdm->me->totface; ++i) {
|
for(i = 0; i < me->totface; ++i) {
|
||||||
mrdm->face_offsets[i] = accum;
|
mrdm->face_offsets[i] = accum;
|
||||||
|
|
||||||
accum += (mrdm->me->mface[i].v4 ? q : t);
|
accum += (me->mface[i].v4 ? q : t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8102,14 +8102,13 @@ static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob,
|
|||||||
int useRenderParams, int isFinalCalc)
|
int useRenderParams, int isFinalCalc)
|
||||||
{
|
{
|
||||||
MultiresModifierData *mmd = (MultiresModifierData*)md;
|
MultiresModifierData *mmd = (MultiresModifierData*)md;
|
||||||
Mesh *me = get_mesh(ob);
|
|
||||||
DerivedMesh *final;
|
DerivedMesh *final;
|
||||||
|
|
||||||
/* TODO: for now just skip a level1 mesh */
|
/* TODO: for now just skip a level1 mesh */
|
||||||
if(mmd->lvl == 1)
|
if(mmd->lvl == 1)
|
||||||
return dm;
|
return dm;
|
||||||
|
|
||||||
final = multires_dm_create_from_derived(mmd, dm, me, useRenderParams, isFinalCalc);
|
final = multires_dm_create_from_derived(mmd, dm, ob, useRenderParams, isFinalCalc);
|
||||||
if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
|
if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
|
||||||
int i;
|
int i;
|
||||||
MVert *dst = CDDM_get_verts(final);
|
MVert *dst = CDDM_get_verts(final);
|
||||||
|
|||||||
@@ -204,10 +204,11 @@ static void VecAddUf(float a[3], float b[3])
|
|||||||
a[2] += b[2];
|
a[2] += b[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void multires_subdisp(DerivedMesh *orig, Mesh *me, DerivedMesh *final, int lvl, int totlvl,
|
static void multires_subdisp(DerivedMesh *orig, Object *ob, DerivedMesh *final, int lvl, int totlvl,
|
||||||
int totsubvert, int totsubedge, int totsubface, int addverts)
|
int totsubvert, int totsubedge, int totsubface, int addverts)
|
||||||
{
|
{
|
||||||
DerivedMesh *mrdm;
|
DerivedMesh *mrdm;
|
||||||
|
Mesh *me = ob->data;
|
||||||
MultiresModifierData mmd_sub;
|
MultiresModifierData mmd_sub;
|
||||||
MVert *mvs = CDDM_get_verts(final);
|
MVert *mvs = CDDM_get_verts(final);
|
||||||
MVert *mvd, *mvd_f1, *mvs_f1, *mvd_f3, *mvd_f4;
|
MVert *mvd, *mvd_f1, *mvs_f1, *mvd_f3, *mvd_f4;
|
||||||
@@ -222,7 +223,7 @@ static void multires_subdisp(DerivedMesh *orig, Mesh *me, DerivedMesh *final, in
|
|||||||
|
|
||||||
memset(&mmd_sub, 0, sizeof(MultiresModifierData));
|
memset(&mmd_sub, 0, sizeof(MultiresModifierData));
|
||||||
mmd_sub.lvl = mmd_sub.totlvl = totlvl;
|
mmd_sub.lvl = mmd_sub.totlvl = totlvl;
|
||||||
mrdm = multires_dm_create_from_derived(&mmd_sub, orig, me, 0, 0);
|
mrdm = multires_dm_create_from_derived(&mmd_sub, orig, ob, 0, 0);
|
||||||
|
|
||||||
mvd = CDDM_get_verts(mrdm);
|
mvd = CDDM_get_verts(mrdm);
|
||||||
/* Need to map from ccg to mrdm */
|
/* Need to map from ccg to mrdm */
|
||||||
@@ -395,7 +396,7 @@ static void multires_subdisp(DerivedMesh *orig, Mesh *me, DerivedMesh *final, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final->needsFree = 1;
|
final->needsFree = 1;
|
||||||
final->release(final);
|
final->release(final);
|
||||||
mrdm->needsFree = 1;
|
mrdm->needsFree = 1;
|
||||||
MultiresDM_mark_as_modified(mrdm);
|
MultiresDM_mark_as_modified(mrdm);
|
||||||
@@ -468,7 +469,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int dista
|
|||||||
orig = CDDM_from_mesh(me, NULL);
|
orig = CDDM_from_mesh(me, NULL);
|
||||||
memset(&mmd_sub, 0, sizeof(MultiresModifierData));
|
memset(&mmd_sub, 0, sizeof(MultiresModifierData));
|
||||||
mmd_sub.lvl = mmd_sub.totlvl = mmd->lvl;
|
mmd_sub.lvl = mmd_sub.totlvl = mmd->lvl;
|
||||||
mrdm = multires_dm_create_from_derived(&mmd_sub, orig, me, 0, 0);
|
mrdm = multires_dm_create_from_derived(&mmd_sub, orig, ob, 0, 0);
|
||||||
totsubvert = mrdm->getNumVerts(mrdm);
|
totsubvert = mrdm->getNumVerts(mrdm);
|
||||||
totsubedge = mrdm->getNumEdges(mrdm);
|
totsubedge = mrdm->getNumEdges(mrdm);
|
||||||
totsubface = mrdm->getNumFaces(mrdm);
|
totsubface = mrdm->getNumFaces(mrdm);
|
||||||
@@ -497,7 +498,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int dista
|
|||||||
|
|
||||||
orig = CDDM_from_mesh(me, NULL);
|
orig = CDDM_from_mesh(me, NULL);
|
||||||
|
|
||||||
multires_subdisp(orig, me, final, mmd->lvl, mmd->totlvl, totsubvert, totsubedge, totsubface, 0);
|
multires_subdisp(orig, ob, final, mmd->lvl, mmd->totlvl, totsubvert, totsubedge, totsubface, 0);
|
||||||
|
|
||||||
orig->needsFree = 1;
|
orig->needsFree = 1;
|
||||||
orig->release(orig);
|
orig->release(orig);
|
||||||
@@ -1166,9 +1167,11 @@ static void multiresModifier_disp_run(DerivedMesh *dm, MVert *subco, int invert)
|
|||||||
|
|
||||||
static void multiresModifier_update(DerivedMesh *dm)
|
static void multiresModifier_update(DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
|
Object *ob;
|
||||||
Mesh *me;
|
Mesh *me;
|
||||||
MDisps *mdisps;
|
MDisps *mdisps;
|
||||||
|
|
||||||
|
ob = MultiresDM_get_object(dm);
|
||||||
me = MultiresDM_get_mesh(dm);
|
me = MultiresDM_get_mesh(dm);
|
||||||
mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
|
mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
|
||||||
|
|
||||||
@@ -1189,7 +1192,7 @@ static void multiresModifier_update(DerivedMesh *dm)
|
|||||||
(includes older displacements but not new sculpts) */
|
(includes older displacements but not new sculpts) */
|
||||||
mmd.totlvl = totlvl;
|
mmd.totlvl = totlvl;
|
||||||
mmd.lvl = lvl;
|
mmd.lvl = lvl;
|
||||||
subco_dm = multires_dm_create_from_derived(&mmd, orig, me, 0, 0);
|
subco_dm = multires_dm_create_from_derived(&mmd, orig, ob, 0, 0);
|
||||||
cur_lvl_orig_verts = CDDM_get_verts(subco_dm);
|
cur_lvl_orig_verts = CDDM_get_verts(subco_dm);
|
||||||
|
|
||||||
/* Subtract the original vertex cos from the new vertex cos */
|
/* Subtract the original vertex cos from the new vertex cos */
|
||||||
@@ -1199,7 +1202,7 @@ static void multiresModifier_update(DerivedMesh *dm)
|
|||||||
|
|
||||||
final = multires_subdisp_pre(dm, totlvl - lvl, 0);
|
final = multires_subdisp_pre(dm, totlvl - lvl, 0);
|
||||||
|
|
||||||
multires_subdisp(orig, me, final, lvl, totlvl, dm->getNumVerts(dm), dm->getNumEdges(dm),
|
multires_subdisp(orig, ob, final, lvl, totlvl, dm->getNumVerts(dm), dm->getNumEdges(dm),
|
||||||
dm->getNumFaces(dm), 1);
|
dm->getNumFaces(dm), 1);
|
||||||
|
|
||||||
subco_dm->release(subco_dm);
|
subco_dm->release(subco_dm);
|
||||||
@@ -1226,7 +1229,7 @@ void multires_force_update(Object *ob)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, DerivedMesh *dm, Mesh *me,
|
struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, DerivedMesh *dm, Object *ob,
|
||||||
int useRenderParams, int isFinalCalc)
|
int useRenderParams, int isFinalCalc)
|
||||||
{
|
{
|
||||||
SubsurfModifierData smd;
|
SubsurfModifierData smd;
|
||||||
@@ -1235,7 +1238,7 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, D
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
ms.mmd = mmd;
|
ms.mmd = mmd;
|
||||||
ms.me = me;
|
ms.ob = ob;
|
||||||
|
|
||||||
memset(&smd, 0, sizeof(SubsurfModifierData));
|
memset(&smd, 0, sizeof(SubsurfModifierData));
|
||||||
smd.levels = smd.renderLevels = mmd->lvl - 1;
|
smd.levels = smd.renderLevels = mmd->lvl - 1;
|
||||||
|
|||||||
@@ -9416,7 +9416,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
|
|
||||||
mmd->lvl = mmd->totlvl;
|
mmd->lvl = mmd->totlvl;
|
||||||
orig = CDDM_from_mesh(me, NULL);
|
orig = CDDM_from_mesh(me, NULL);
|
||||||
dm = multires_dm_create_from_derived(mmd, orig, me, 0, 0);
|
dm = multires_dm_create_from_derived(mmd, orig, ob, 0, 0);
|
||||||
|
|
||||||
multires_load_old(dm, me->mr);
|
multires_load_old(dm, me->mr);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user