== Multires ==

Fixed bug #23657, "Modifiers dosen't work when you select diffrent mesh for object"

Multires modifier now adds empty mdisps if they're missing, rather than displaying a warning
Switching an object's mesh will now check for a multires modifier; if found the modifier's total number of levels are reset to match the mesh's mdisps
Switching the mesh also forces a multires update so that sculpted changes aren't lost
This commit is contained in:
Nicholas Bishop 2010-09-09 00:14:51 +00:00
parent 2d4e8ba22f
commit 4eaa10aa02
6 changed files with 64 additions and 2 deletions

View File

@ -321,6 +321,9 @@ struct LinkNode *modifiers_calcDataMasks(struct Scene *scene,
int required_mode);
struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob);
/* ensure modifier correctness when changing ob->data */
void test_object_modifiers(struct Object *ob);
/* here for do_versions */
void modifier_mdef_compact_influences(struct ModifierData *md);

View File

@ -44,6 +44,8 @@ void multires_force_update(struct Object *ob);
void multires_force_render_update(struct Object *ob);
void multires_force_external_reload(struct Object *ob);
void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob);
struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*,
int local_mmd, struct DerivedMesh*, struct Object *, int, int);

View File

@ -51,6 +51,8 @@
#include "BKE_displist.h"
#include "BKE_library.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_key.h"
/* these 2 are only used by conversion functions */
#include "BKE_curve.h"
@ -492,6 +494,8 @@ Mesh *get_mesh(Object *ob)
void set_mesh(Object *ob, Mesh *me)
{
Mesh *old=0;
multires_force_update(ob);
if(ob==0) return;
@ -504,6 +508,8 @@ void set_mesh(Object *ob, Mesh *me)
}
test_object_materials((ID *)me);
test_object_modifiers(ob);
}
/* ************** make edges in a Mesh, for outside of editmode */

View File

@ -49,6 +49,7 @@
#include "BKE_bmesh.h"
#include "BKE_cloth.h"
#include "BKE_key.h"
#include "BKE_multires.h"
#include "MOD_modifiertypes.h"
@ -526,5 +527,21 @@ void modifier_freeTemporaryData(ModifierData *md)
}
}
/* ensure modifier correctness when changing ob->data */
void test_object_modifiers(Object *ob)
{
ModifierData *md;
/* just multires checked for now, since only multires
modifies mesh data */
if(ob->type != OB_MESH) return;
for(md = ob->modifiers.first; md; md = md->next) {
if(md->type == eModifierType_Multires) {
MultiresModifierData *mmd = (MultiresModifierData*)md;
multiresModifier_set_levels_from_disps(mmd, ob);
}
}
}

View File

@ -275,6 +275,40 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm
return result;
}
/* reset the multires levels to match the number of mdisps */
void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
{
Mesh *me = ob->data;
MDisps *mdisp;
int i;
mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS);
if(mdisp) {
for(i = 0; i < me->totface; ++i, ++mdisp) {
int S = me->mface[i].v4 ? 4 : 3;
if(mdisp->totdisp == 0) continue;
while(1) {
int side = (1 << (mmd->totlvl-1)) + 1;
int lvl_totdisp = side*side*S;
if(mdisp->totdisp == lvl_totdisp)
break;
else if(mdisp->totdisp < lvl_totdisp)
--mmd->totlvl;
else
++mmd->totlvl;
}
}
mmd->lvl = MIN2(mmd->sculptlvl, mmd->totlvl);
mmd->sculptlvl = MIN2(mmd->sculptlvl, mmd->totlvl);
mmd->renderlvl = MIN2(mmd->renderlvl, mmd->totlvl);
}
}
static void multires_set_tot_mdisps(Mesh *me, int lvl)
{
MDisps *mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);

View File

@ -72,8 +72,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
if(mmd->totlvl) {
if(!CustomData_get_layer(&me->fdata, CD_MDISPS)) {
/* multires can't work without displacement layer */
modifier_setError(md, "Modifier needs mesh with displacement data.");
/* multires always needs a displacement layer */
CustomData_add_layer(&me->fdata, CD_MDISPS, CD_CALLOC, NULL, me->totface);
return dm;
}
}