diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2010-09-09 04:14:51 +0400 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2010-09-09 04:14:51 +0400 |
commit | 4eaa10aa02994c4609e1c12e38d0eda6355f9077 (patch) | |
tree | d2a8fcc7adc471dee1c5b2f29e2431c8afbfa469 /source | |
parent | 2d4e8ba22fc4fd304c35af629480e80d4cb8bac2 (diff) |
== 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
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_multires.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 34 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 4 |
6 files changed, 64 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index d6ab99d6534..95a9394427f 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -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); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 39fc795e6ff..fc0ab2eea1e 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -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); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 94131fdbe9d..2f8553b06b3 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 63f0f1fa091..43d26f26d1f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -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); + } + } +} diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 56d517f1e13..57f568e6094 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -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); diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 766a3756d4a..dd99c88a684 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -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; } } |