diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-11-04 19:00:28 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-11-04 19:00:28 +0300 |
commit | f478cef43b845f007cb6340df761cb43ff62c762 (patch) | |
tree | e43aba34fe006f8991dbe1d4770e1433f229a281 | |
parent | 6753882e42282ccf9dea49bdef2fc5455d852710 (diff) |
Fix #24388: multires base mesh
- MDisp should be re-allocated if face changed amount of vertices
- Allocate disps array in layerSwap_mdisps to prevent loosing all highres data
-rw-r--r-- | source/blender/blenkernel/BKE_multires.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 20 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 87 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh.c | 4 |
4 files changed, 83 insertions, 35 deletions
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 4a9b2ec5c0d..a05dce81fbc 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -37,6 +37,8 @@ struct Multires; struct MultiresModifierData; struct ModifierData; struct Object; +struct Scene; +struct MDisps; void multires_mark_as_modified(struct Object *ob); @@ -74,5 +76,10 @@ void multires_load_old_250(struct Mesh *); void multiresModifier_scale_disp(struct Scene *scene, struct Object *ob); void multiresModifier_prepare_join(struct Scene *scene, struct Object *ob, struct Object *to_ob); +int multires_mdisp_corners(struct MDisps *s); + +/* update multires data after topology changing */ +void multires_topology_changed(struct Object *ob); + #endif diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index c1aaa869876..cd476d8491b 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -50,6 +50,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_utildefines.h" +#include "BKE_multires.h" /* number of layers to add when growing a CustomData object */ #define CUSTOMDATA_GROW 5 @@ -441,19 +442,6 @@ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, fl } #endif -static int mdisp_corners(MDisps *s) -{ - int lvl= 13; - - while(lvl > 0) { - int side = (1 << (lvl-1)) + 1; - if ((s->totdisp % (side*side)) == 0) return s->totdisp / (side*side); - lvl--; - } - - return 0; -} - static void layerSwap_mdisps(void *data, const int *ci) { MDisps *s = data; @@ -462,7 +450,7 @@ static void layerSwap_mdisps(void *data, const int *ci) if(s->disps) { int nverts= (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */ - corners= mdisp_corners(s); + corners= multires_mdisp_corners(s); cornersize= s->totdisp/corners; if(corners!=nverts) { @@ -470,8 +458,8 @@ static void layerSwap_mdisps(void *data, const int *ci) if it happened, just forgot displacement */ MEM_freeN(s->disps); - s->disps= NULL; - s->totdisp= 0; /* flag to update totdisp */ + s->totdisp= (s->totdisp/corners)*nverts; + s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap"); return; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index bf1cd9b9994..23a81e53728 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -305,33 +305,45 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm } /* reset the multires levels to match the number of mdisps */ -void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob) +static int get_levels_from_disps(Object *ob) { Mesh *me = ob->data; MDisps *mdisp; - int i; + int i, totlvl= 0; 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; - - } + 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 << (totlvl-1)) + 1; + int lvl_totdisp = side*side*S; + if(mdisp->totdisp == lvl_totdisp) + break; + else if(mdisp->totdisp < lvl_totdisp) + --totlvl; + else + ++totlvl; + } + } + return totlvl; +} + +/* 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; + + mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS); + + if(mdisp) { + mmd->totlvl = get_levels_from_disps(ob); mmd->lvl = MIN2(mmd->sculptlvl, mmd->totlvl); mmd->sculptlvl = MIN2(mmd->sculptlvl, mmd->totlvl); mmd->renderlvl = MIN2(mmd->renderlvl, mmd->totlvl); @@ -1555,6 +1567,19 @@ void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) subdm->release(subdm); } +int multires_mdisp_corners(MDisps *s) +{ + int lvl= 13; + + while(lvl > 0) { + int side = (1 << (lvl-1)) + 1; + if ((s->totdisp % (side*side)) == 0) return s->totdisp / (side*side); + lvl--; + } + + return 0; +} + void multiresModifier_scale_disp(Scene *scene, Object *ob) { float smat[3][3]; @@ -1578,3 +1603,27 @@ void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob) multires_apply_smat(scene, ob, mat); } + +/* update multires data after topology changing */ +void multires_topology_changed(Object *ob) +{ + Mesh *me= (Mesh*)ob->data; + MDisps *mdisp= CustomData_get_layer(&me->fdata, CD_MDISPS); + int i; + + if(!mdisp) return; + + for(i = 0; i < me->totface; i++, mdisp++) { + int corners= multires_mdisp_corners(mdisp); + int nvert= me->mface[i].v4 ? 4 : 3; + + if(corners!=nvert) { + mdisp->totdisp= (mdisp->totdisp/corners)*nvert; + + if(mdisp->disps) + MEM_freeN(mdisp->disps); + + mdisp->disps= MEM_callocN(mdisp->totdisp*sizeof(float)*3, "mdisp topology"); + } + } +} diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 6665e82af19..d95a2570e80 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -54,6 +54,7 @@ #include "BKE_mesh.h" #include "BKE_paint.h" #include "BKE_report.h" +#include "BKE_multires.h" #include "ED_mesh.h" #include "ED_object.h" @@ -1306,6 +1307,9 @@ void load_editMesh(Scene *scene, Object *ob) } mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + + /* topology could be changed, ensure mdisps are ok */ + multires_topology_changed(ob); } void remake_editMesh(Scene *scene, Object *ob) |