Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2010-11-04 19:00:28 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2010-11-04 19:00:28 +0300
commitf478cef43b845f007cb6340df761cb43ff62c762 (patch)
treee43aba34fe006f8991dbe1d4770e1433f229a281 /source/blender
parent6753882e42282ccf9dea49bdef2fc5455d852710 (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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_multires.h7
-rw-r--r--source/blender/blenkernel/intern/customdata.c20
-rw-r--r--source/blender/blenkernel/intern/multires.c87
-rw-r--r--source/blender/editors/mesh/editmesh.c4
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)