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
path: root/source
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2007-06-01 06:21:11 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2007-06-01 06:21:11 +0400
commit1a9f0e692acc3d5b2b9111e781d5e4a018c811d5 (patch)
treeb54a8c64f4fcebc3d252bb979c56bdc922bcf398 /source
parent9d0f74658001947781cd65d28fb7982b36acd1fd (diff)
== Multires ==
* Moved the multires vertex data from struct MultiresLevel to struct Multires. There's no longer any reason to store data seperately for each level; it was just taking up extra memory. * Incremented the subversion to 2 and adjusted do_versions to correctly load older files. * Refactored the multires update process (which handles propagating changes to other levels)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c21
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/include/multires.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h6
-rw-r--r--source/blender/src/multires-firstlevel.c37
-rw-r--r--source/blender/src/multires.c368
9 files changed, 257 insertions, 189 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index bf3e25b1c5a..4b9e10651cf 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,7 +44,7 @@ struct ListBase;
struct MemFile;
#define BLENDER_VERSION 244
-#define BLENDER_SUBVERSION 1
+#define BLENDER_SUBVERSION 2
#define BLENDER_MINVERSION 240
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index dc54fc7c1f0..5f8e9c7b207 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2272,7 +2272,7 @@ float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
vert_copy= MEM_callocN(sizeof(float)*3*lvl->totvert, "multires vert_copy");
for(i=0; i<lvl->totvert; ++i)
- VecCopyf(&vert_copy[i*3], lvl->verts[i].co);
+ VecCopyf(&vert_copy[i*3], me->mr->verts[i].co);
/* Goto the pin level for multires */
me->mr->newlvl= me->mr->pinlvl;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 278d49e2198..4c6bfda1517 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -504,7 +504,7 @@ static float *make_orco_mesh_internal(Object *ob, int render)
if(me->mr) {
lvl = multires_level_n(me->mr, me->mr->pinlvl);
vcos = MEM_callocN(sizeof(*vcos)*lvl->totvert, "orco mr mesh");
- mvert = lvl->verts;
+ mvert = me->mr->verts;
totvert = lvl->totvert;
}
else {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 118c2779ac0..4bbcfab74ae 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2554,6 +2554,8 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
if(!mesh->mr->edge_creases)
mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
+
+ mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
for(; lvl; lvl= lvl->next) {
lvl->verts= newdataadr(fd, lvl->verts);
@@ -6469,6 +6471,25 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for(sce= main->scene.first; sce; sce= sce->id.next)
sce->r.mode |= R_SSS;
}
+ if(main->versionfile != 244 || main->subversionfile < 2) {
+ /* Copy over old per-level multires vertex data
+ into a single vertex array in struct Multires */
+ Mesh *me;
+ for(me = main->mesh.first; me; me=me->id.next) {
+ if(me->mr) {
+ MultiresLevel *lvl = me->mr->levels.last;
+ if(lvl) {
+ me->mr->verts = lvl->verts;
+ lvl->verts = NULL;
+ /* Don't need the other vert arrays */
+ for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
+ MEM_freeN(lvl->verts);
+ lvl->verts = NULL;
+ }
+ }
+ }
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0d4d9d82ee1..226561ab97b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1156,13 +1156,17 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
writedata(wd, DATA, sizeof(short)*lvl->totedge, mesh->mr->edge_flags);
writedata(wd, DATA, sizeof(char)*lvl->totedge, mesh->mr->edge_creases);
}
+
for(; lvl; lvl= lvl->next) {
writestruct(wd, DATA, "MultiresLevel", 1, lvl);
- writestruct(wd, DATA, "MVert", lvl->totvert, lvl->verts);
writestruct(wd, DATA, "MultiresFace", lvl->totface, lvl->faces);
writestruct(wd, DATA, "MultiresEdge", lvl->totedge, lvl->edges);
writestruct(wd, DATA, "MultiresColFace", lvl->totface, lvl->colfaces);
}
+
+ lvl= mesh->mr->levels.last;
+ if(lvl)
+ writestruct(wd, DATA, "MVert", lvl->totvert, mesh->mr->verts);
}
/* PMV data */
diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h
index 6c33af2d5e3..069dbee802f 100644
--- a/source/blender/include/multires.h
+++ b/source/blender/include/multires.h
@@ -31,6 +31,7 @@
#define MULTIRES_H
struct CustomData;
+struct EditMesh;
struct Object;
struct MDeformVert;
struct Mesh;
@@ -65,6 +66,7 @@ int multires_modifier_warning();
/* multires-firstlevel.c */
/* Generic */
+void multires_update_first_level(struct Mesh *me, struct EditMesh *em);
void multires_update_customdata(struct MultiresLevel *lvl1, struct CustomData *src,
struct CustomData *dst, const int type);
void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em, struct MultiresLevel *lvl,
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 4d78f577137..af9c1ae629d 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -109,7 +109,6 @@ struct MultiresMapNode;
typedef struct MultiresLevel {
struct MultiresLevel *next, *prev;
- MVert *verts;
MultiresFace *faces;
MultiresColFace *colfaces;
MultiresEdge *edges;
@@ -118,10 +117,15 @@ typedef struct MultiresLevel {
struct MultiresMapNode *map_mem;
unsigned int totvert, totface, totedge, pad;
+
+ /* Kept for compatibility with older files */
+ MVert *verts;
} MultiresLevel;
typedef struct Multires {
ListBase levels;
+ MVert *verts;
+
unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl;
unsigned char use_col, pad;
diff --git a/source/blender/src/multires-firstlevel.c b/source/blender/src/multires-firstlevel.c
index db39a429c22..2be867b5db0 100644
--- a/source/blender/src/multires-firstlevel.c
+++ b/source/blender/src/multires-firstlevel.c
@@ -55,6 +55,8 @@
MDeformVert *subdivide_dverts(MDeformVert *src, MultiresLevel *lvl);
MTFace *subdivide_mtfaces(MTFace *src, MultiresLevel *lvl);
+void multires_update_edge_flags(Mesh *me, EditMesh *em);
+void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease);
/*********** Generic ***********/
@@ -221,6 +223,41 @@ void multires_del_lower_customdata(Multires *mr, MultiresLevel *cr_lvl)
mr->fdata= cdf;
}
+/* Update all special first-level data, if the first-level is active */
+void multires_update_first_level(Mesh *me, EditMesh *em)
+{
+ if(me && me->mr && me->mr->current == 1) {
+ multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata,
+ &me->mr->vdata, CD_MDEFORMVERT);
+ multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata,
+ &me->mr->fdata, CD_MTFACE);
+ multires_update_edge_flags(me, em);
+ }
+}
+
+/*********** Multires.edge_flags ***********/
+void multires_update_edge_flags(Mesh *me, EditMesh *em)
+{
+ MultiresLevel *lvl= me->mr->levels.first;
+ EditEdge *eed= NULL;
+ int i;
+
+ if(em) eed= em->edges.first;
+ for(i=0; i<lvl->totedge; ++i) {
+ if(em) {
+ me->mr->edge_flags[i]= 0;
+ eed_to_medge_flag(eed, &me->mr->edge_flags[i], &me->mr->edge_creases[i]);
+ eed= eed->next;
+ }
+ else {
+ me->mr->edge_flags[i]= me->medge[i].flag;
+ me->mr->edge_creases[i]= me->medge[i].crease;
+ }
+ }
+}
+
+
+
/*********** Multires.vdata ***********/
/* MDeformVert */
diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c
index a249b6b408b..33b85bd27b6 100644
--- a/source/blender/src/multires.c
+++ b/source/blender/src/multires.c
@@ -484,13 +484,14 @@ void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
tmp.v3= efa->v3->tmp.l;
tmp.v4= 0;
if(efa->v4) tmp.v4= efa->v4->tmp.l;
- tmp.flag= efa->flag;
- if(efa->f & 1) tmp.flag |= ME_FACE_SEL;
- else f->flag &= ~ME_FACE_SEL;
- if(efa->h) tmp.flag |= ME_HIDE;
test_index_face(&tmp, NULL, 0, efa->v4?4:3);
for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
- f->flag= tmp.flag;
+
+ /* Flags */
+ f->flag= efa->flag;
+ if(efa->f & 1) f->flag |= ME_FACE_SEL;
+ else f->flag &= ~ME_FACE_SEL;
+ if(efa->h) f->flag |= ME_HIDE;
f->mat_nr= efa->mat_nr;
} else {
f->v[0]= m->v1;
@@ -575,12 +576,12 @@ void multires_make(void *ob, void *me_v)
/* Load vertices and vdata (MDeformVerts) */
lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert;
- lvl->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
+ me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata,
&me->mr->vdata, CD_MDEFORMVERT);
if(em) eve= em->verts.first;
for(i=0; i<lvl->totvert; ++i) {
- multires_get_vert(&lvl->verts[i], eve, &me->mvert[i], i);
+ multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
if(em) eve= eve->next;
}
@@ -636,7 +637,6 @@ MultiresLevel *multires_level_copy(MultiresLevel *orig)
MultiresLevel *lvl= MEM_dupallocN(orig);
lvl->next= lvl->prev= NULL;
- lvl->verts= MEM_dupallocN(orig->verts);
lvl->faces= MEM_dupallocN(orig->faces);
lvl->colfaces= MEM_dupallocN(orig->colfaces);
lvl->edges= MEM_dupallocN(orig->edges);
@@ -658,6 +658,8 @@ Multires *multires_copy(Multires *orig)
for(lvl= orig->levels.first; lvl; lvl= lvl->next)
BLI_addtail(&mr->levels, multires_level_copy(lvl));
+
+ mr->verts= MEM_dupallocN(orig->verts);
lvl= mr->levels.first;
if(lvl) {
@@ -690,6 +692,8 @@ void multires_free(Multires *mr)
lvl= lvl->next;
}
+ MEM_freeN(mr->verts);
+
BLI_freelistN(&mr->levels);
MEM_freeN(mr);
@@ -700,7 +704,6 @@ void multires_free(Multires *mr)
void multires_free_level(MultiresLevel *lvl)
{
if(lvl) {
- if(lvl->verts) MEM_freeN(lvl->verts);
if(lvl->faces) MEM_freeN(lvl->faces);
if(lvl->edges) MEM_freeN(lvl->edges);
if(lvl->colfaces) MEM_freeN(lvl->colfaces);
@@ -844,6 +847,7 @@ void multires_add_level(void *ob, void *me_v)
Mesh *me= me_v;
MultiresLevel *lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel");
MultiApplyData data;
+ MVert *oldverts= NULL;
multires_check_state();
@@ -859,15 +863,16 @@ void multires_add_level(void *ob, void *me_v)
/* Create vertices
=============== */
lvl->totvert= lvl->prev->totvert + lvl->prev->totedge + lvl->prev->totface;
- lvl->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
- /* Copy previous level's verts */
+ oldverts= me->mr->verts;
+ me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert, "multitres verts");
+ /* Copy old verts */
for(i=0; i<lvl->prev->totvert; ++i)
- lvl->verts[i]= lvl->prev->verts[i];
+ me->mr->verts[i]= oldverts[i];
/* Create new edge verts */
for(i=0; i<lvl->prev->totedge; ++i) {
- VecMidf(lvl->verts[lvl->prev->totvert + i].co,
- lvl->prev->verts[lvl->prev->edges[i].v[0]].co,
- lvl->prev->verts[lvl->prev->edges[i].v[1]].co);
+ VecMidf(me->mr->verts[lvl->prev->totvert + i].co,
+ oldverts[lvl->prev->edges[i].v[0]].co,
+ oldverts[lvl->prev->edges[i].v[1]].co);
lvl->prev->edges[i].mid= lvl->prev->totvert + i;
}
/* Create new face verts */
@@ -937,38 +942,42 @@ void multires_add_level(void *ob, void *me_v)
=============== */
for(i=0; i<lvl->prev->totface; ++i) {
const MultiresFace *f= &lvl->prev->faces[i];
- data.corner1= lvl->prev->verts[f->v[0]].co;
- data.corner2= lvl->prev->verts[f->v[1]].co;
- data.corner3= lvl->prev->verts[f->v[2]].co;
- data.corner4= lvl->prev->verts[f->v[3]].co;
+ data.corner1= oldverts[f->v[0]].co;
+ data.corner2= oldverts[f->v[1]].co;
+ data.corner3= oldverts[f->v[2]].co;
+ data.corner4= oldverts[f->v[3]].co;
data.quad= f->v[3] ? 1 : 0;
- multi_apply(lvl->verts[f->mid].co, &data, 3, catmullclark_smooth_face);
+ multi_apply(me->mr->verts[f->mid].co, &data, 3, catmullclark_smooth_face);
}
if(G.scene->toolsettings->multires_subdiv_type == 0) {
for(i=0; i<lvl->prev->totedge; ++i) {
const MultiresEdge *e= &lvl->prev->edges[i];
data.boundary= multires_edge_is_boundary(lvl->prev,i);
- edge_face_neighbor_midpoints_accum(&data,lvl->prev,lvl->verts,sizeof(MVert),e);
- data.endpoint1= lvl->prev->verts[e->v[0]].co;
- data.endpoint2= lvl->prev->verts[e->v[1]].co;
- multi_apply(lvl->verts[e->mid].co, &data, 3, catmullclark_smooth_edge);
+ edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e);
+ data.endpoint1= oldverts[e->v[0]].co;
+ data.endpoint2= oldverts[e->v[1]].co;
+ multi_apply(me->mr->verts[e->mid].co, &data, 3, catmullclark_smooth_edge);
}
for(i=0; i<lvl->prev->totvert; ++i) {
data.boundary= multires_vert_is_boundary(lvl->prev,i);
- data.original= lvl->verts[i].co;
+ data.original= oldverts[i].co;
data.edge_count= BLI_countlist(&lvl->prev->vert_edge_map[i]);
if(data.boundary)
- boundary_edges_average(&data,lvl->prev,lvl->prev->verts,sizeof(MVert),i);
+ boundary_edges_average(&data,lvl->prev, oldverts, sizeof(MVert),i);
else {
- vert_face_neighbor_midpoints_average(&data,lvl->prev,lvl->verts,sizeof(MVert),i);
- vert_edge_neighbor_midpoints_average(&data,lvl->prev,lvl->prev->verts,sizeof(MVert),i);
+ vert_face_neighbor_midpoints_average(&data,lvl->prev, me->mr->verts,
+ sizeof(MVert),i);
+ vert_edge_neighbor_midpoints_average(&data,lvl->prev, oldverts,
+ sizeof(MVert),i);
}
- multi_apply(lvl->verts[i].co, &data, 3, catmullclark_smooth_vert);
+ multi_apply(me->mr->verts[i].co, &data, 3, catmullclark_smooth_vert);
}
}
+ MEM_freeN(oldverts);
+
/* Vertex Colors
============= */
curf= 0;
@@ -1094,13 +1103,13 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
for(i=0; i<lvl->totvert; ++i) {
if(em) {
- eves[i]= addvertlist(lvl->verts[i].co, NULL); /* TODO */
- if(lvl->verts[i].flag & 1) eves[i]->f |= SELECT;
- if(lvl->verts[i].flag & ME_HIDE) eves[i]->h= 1;
+ eves[i]= addvertlist(me->mr->verts[i].co, NULL);
+ if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
+ if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
eves[i]->data= NULL;
}
else
- me->mvert[i]= lvl->verts[i];
+ me->mvert[i]= me->mr->verts[i];
}
for(i=0; i<lvl->totedge; ++i) {
if(em) {
@@ -1115,9 +1124,12 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
if(em) {
EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
- eves[lvl->faces[i].v[2]], eve4, NULL, NULL); /* TODO */
- efa->flag= lvl->faces[i].flag;
+ eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
+ efa->flag= lvl->faces[i].flag & ~ME_HIDE;
efa->mat_nr= lvl->faces[i].mat_nr;
+ if(lvl->faces[i].flag & ME_FACE_SEL)
+ efa->f |= SELECT;
+ if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
efa->data= NULL;
}
else {
@@ -1160,6 +1172,14 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
}
}
}
+
+ if(em) {
+ eed= em->edges.first;
+ for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
+ eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
+ me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
+ }
+ }
EM_select_flush();
@@ -1313,108 +1333,65 @@ void multires_update_colors(Mesh *me)
}
}
-void multires_update_edge_flags(Multires *mr, Mesh *me, EditMesh *em)
-{
- MultiresLevel *lvl= current_level(mr);
- EditEdge *eed= NULL;
- int i;
-
- if(em) eed= em->edges.first;
- for(i=0; i<lvl->totedge; ++i) {
- if(em) {
- mr->edge_flags[i]= 0;
- eed_to_medge_flag(eed, &mr->edge_flags[i], &mr->edge_creases[i]);
- eed= eed->next;
- }
- else {
- mr->edge_flags[i]= me->medge[i].flag;
- mr->edge_creases[i]= me->medge[i].crease;
- }
- }
-}
-
-void multires_update_levels(Mesh *me, const int render)
+/* Update vertex locations and vertex flags */
+void multires_update_vertices(Mesh *me, EditMesh *em)
{
- /* cr=current, pr=previous, or=original */
- MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl;
- MultiresLevel *or_lvl= cr_lvl;
- vec3f *pr_deltas= NULL, *cr_deltas= NULL;
- char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *pr_mat_damaged= NULL, *cr_mat_damaged= NULL;
- char *or_flag_damaged= NULL, *or_mat_damaged= NULL;
- EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
+ MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
+ *last_lvl= me->mr->levels.last;
+ vec3f *pr_deltas= NULL, *cr_deltas= NULL, *swap_deltas= NULL;
EditVert *eve= NULL;
- EditFace *efa= NULL;
MultiApplyData data;
- unsigned i,j,curf;
-
- /* Update special first-level data */
- if(cr_lvl==me->mr->levels.first) {
- multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata,
- &me->mr->vdata, CD_MDEFORMVERT);
- multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata,
- &me->mr->fdata, CD_MTFACE);
- multires_update_edge_flags(me->mr, me, em);
- }
+ int i, j;
/* Prepare deltas */
- cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"initial deltas");
+ pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1");
+ cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2");
/* Calculate initial deltas -- current mesh subtracted from current level*/
if(em) eve= em->verts.first;
for(i=0; i<cr_lvl->totvert; ++i) {
if(em) {
- VecSubf(&cr_deltas[i].x, eve->co, cr_lvl->verts[i].co);
+ VecSubf(&cr_deltas[i].x, eve->co, me->mr->verts[i].co);
eve= eve->next;
} else
- VecSubf(&cr_deltas[i].x, me->mvert[i].co, cr_lvl->verts[i].co);
- }
-
- /* Faces -- find whether flag/mat has changed */
- cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface, "flag_damaged 1");
- cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface, "mat_damaged 1");
- if(em) efa= em->faces.first;
- for(i=0; i<cr_lvl->totface; ++i) {
- if(cr_lvl->faces[i].flag != (em ? efa->flag : me->mface[i].flag))
- cr_flag_damaged[i]= 1;
- if(cr_lvl->faces[i].mat_nr != (em ? efa->mat_nr : me->mface[i].mat_nr))
- cr_mat_damaged[i]= 1;
- if(em) efa= efa->next;
+ VecSubf(&cr_deltas[i].x, me->mvert[i].co, me->mr->verts[i].co);
}
- or_flag_damaged= MEM_dupallocN(cr_flag_damaged);
- or_mat_damaged= MEM_dupallocN(cr_mat_damaged);
- /* Update current level -- copy current mesh into current level */
- if(em) {
- eve= em->verts.first;
- efa= em->faces.first;
- }
- for(i=0; i<cr_lvl->totvert; ++i) {
- multires_get_vert(&cr_lvl->verts[i], eve, &me->mvert[i], i);
- if(em) eve= eve->next;
+
+ /* Copy current level's vertex flags and clear the rest */
+ if(em) eve= em->verts.first;
+ for(i=0; i < last_lvl->totvert; ++i) {
+ if(i < cr_lvl->totvert) {
+ MVert mvflag;
+ multires_get_vert(&mvflag, eve, &me->mvert[i], i);
+ if(em) eve= eve->next;
+ me->mr->verts[i].flag= mvflag.flag;
+ }
+ else
+ me->mr->verts[i].flag= 0;
}
- for(i=0; i<cr_lvl->totface; ++i) {
- cr_lvl->faces[i].flag= em ? efa->flag : me->mface[i].flag;
- cr_lvl->faces[i].mat_nr= em ? efa->mat_nr : me->mface[i].mat_nr;
- if(em) efa= efa->next;
+
+ /* If already on the highest level, copy current verts (including flags) into current level */
+ if(cr_lvl == last_lvl) {
+ if(em)
+ eve= em->verts.first;
+ for(i=0; i<cr_lvl->totvert; ++i) {
+ multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
+ if(em) eve= eve->next;
+ }
}
/* Update higher levels */
pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
cr_lvl= pr_lvl->next;
while(cr_lvl) {
- /* Set up new deltas, but keep the ones from the previous level */
- if(pr_deltas) MEM_freeN(pr_deltas);
+ /* Swap the old/new deltas */
+ swap_deltas= pr_deltas;
pr_deltas= cr_deltas;
- cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"deltas");
- if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
- pr_flag_damaged= cr_flag_damaged;
- cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"flag_damaged 2");
- if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
- pr_mat_damaged= cr_mat_damaged;
- cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"mat_damaged 2");
+ cr_deltas= swap_deltas;
/* Calculate and add new deltas
- ============================*/
+ ============================ */
for(i=0; i<pr_lvl->totface; ++i) {
const MultiresFace *f= &pr_lvl->faces[i];
data.corner1= &pr_deltas[f->v[0]].x;
@@ -1423,18 +1400,9 @@ void multires_update_levels(Mesh *me, const int render)
data.corner4= &pr_deltas[f->v[3]].x;
data.quad= f->v[3] ? 1 : 0;
multi_apply(&cr_deltas[f->mid].x, &data, 3, catmullclark_smooth_face);
-
- VecAddf(cr_lvl->verts[f->mid].co,
- cr_lvl->verts[f->mid].co,
- &cr_deltas[f->mid].x);
- cr_lvl->verts[f->mid].flag= 0;
- for(j=0; j<(data.quad?4:3); ++j) {
- if(pr_lvl->verts[f->v[j]].flag & 1)
- cr_lvl->verts[f->mid].flag |= 1;
- if(pr_lvl->verts[f->v[j]].flag & ME_HIDE)
- cr_lvl->verts[f->mid].flag |= ME_HIDE;
- }
+ for(j=0; j<(data.quad?4:3); ++j)
+ me->mr->verts[f->mid].flag |= me->mr->verts[f->v[j]].flag;
}
for(i=0; i<pr_lvl->totedge; ++i) {
@@ -1444,20 +1412,9 @@ void multires_update_levels(Mesh *me, const int render)
data.endpoint1= &pr_deltas[e->v[0]].x;
data.endpoint2= &pr_deltas[e->v[1]].x;
multi_apply(&cr_deltas[e->mid].x, &data, 3, catmullclark_smooth_edge);
-
- cr_lvl->verts[e->mid].flag= 0;
- for(j=0; j<2; ++j) {
- if(pr_lvl->verts[e->v[j]].flag & 1)
- cr_lvl->verts[e->mid].flag |= 1;
- if(pr_lvl->verts[e->v[j]].flag & ME_HIDE)
- cr_lvl->verts[e->mid].flag |= ME_HIDE;
- }
- }
- for(i=0; i<pr_lvl->totedge; ++i) {
- const unsigned ndx= pr_lvl->edges[i].mid;
- VecAddf(cr_lvl->verts[ndx].co,
- cr_lvl->verts[ndx].co,
- &cr_deltas[ndx].x);
+
+ for(j=0; j<2; ++j)
+ me->mr->verts[e->mid].flag |= me->mr->verts[e->v[j]].flag;
}
for(i=0; i<pr_lvl->totvert; ++i) {
@@ -1471,31 +1428,13 @@ void multires_update_levels(Mesh *me, const int render)
vert_edge_neighbor_midpoints_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i);
}
multi_apply(&cr_deltas[i].x, &data, 3, catmullclark_smooth_vert);
- cr_lvl->verts[i].flag= 0;
- if(pr_lvl->verts[i].flag & 1) cr_lvl->verts[i].flag |= 1;
- if(pr_lvl->verts[i].flag & ME_HIDE) cr_lvl->verts[i].flag |= ME_HIDE;
- }
- for(i=0; i<pr_lvl->totvert; ++i) {
- VecAddf(cr_lvl->verts[i].co,
- cr_lvl->verts[i].co,
- &cr_deltas[i].x);
}
- /* Update faces */
- curf= 0;
- for(i=0; i<pr_lvl->totface; ++i) {
- const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
- for(j=0; j<sides; ++j) {
- if(pr_flag_damaged[i]) {
- cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
- cr_flag_damaged[curf]= 1;
- }
- if(pr_mat_damaged[i]) {
- cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
- cr_mat_damaged[curf]= 1;
- }
- ++curf;
- }
+ /* Apply deltas to vertex locations */
+ for(i=0; (cr_lvl == last_lvl) && (i < cr_lvl->totvert); ++i) {
+ VecAddf(me->mr->verts[i].co,
+ me->mr->verts[i].co,
+ &cr_deltas[i].x);
}
pr_lvl= pr_lvl->next;
@@ -1504,34 +1443,51 @@ void multires_update_levels(Mesh *me, const int render)
if(pr_deltas) MEM_freeN(pr_deltas);
if(cr_deltas) MEM_freeN(cr_deltas);
+}
+
+void multires_update_faces(Mesh *me, EditMesh *em)
+{
+ MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
+ *last_lvl= me->mr->levels.last;
+ char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL,
+ *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL;
+ EditFace *efa= NULL;
+ unsigned i,j,curf;
+
+ /* Find for each face whether flag/mat has changed */
+ pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
+ cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
+ pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
+ cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
+ if(em) efa= em->faces.first;
+ for(i=0; i<cr_lvl->totface; ++i) {
+ MultiresFace mftmp;
+ multires_get_face(&mftmp, efa, &me->mface[i]);
+ if(cr_lvl->faces[i].flag != mftmp.flag)
+ cr_flag_damaged[i]= 1;
+ if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr)
+ cr_mat_damaged[i]= 1;
+
+ /* Update current level */
+ cr_lvl->faces[i].flag= mftmp.flag;
+ cr_lvl->faces[i].mat_nr= mftmp.mat_nr;
+
+ if(em) efa= efa->next;
+ }
+ or_flag_damaged= MEM_dupallocN(cr_flag_damaged);
+ or_mat_damaged= MEM_dupallocN(cr_mat_damaged);
+
/* Update lower levels */
- cr_lvl= me->mr->levels.last;
cr_lvl= cr_lvl->prev;
- /* Update Verts */
- while(cr_lvl) {
- for(i=0; i<cr_lvl->totvert; ++i)
- cr_lvl->verts[i]= cr_lvl->next->verts[i];
- cr_lvl= cr_lvl->prev;
- }
-
- /* Update Faces */
-
- /* Clear to original damages */
- if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
- if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
- cr_flag_damaged= or_flag_damaged;
- cr_mat_damaged= or_mat_damaged;
-
- cr_lvl= or_lvl->prev;
while(cr_lvl) {
- if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
+ swap= pr_flag_damaged;
pr_flag_damaged= cr_flag_damaged;
- cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"flag_damaged 3");
- if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
+ cr_flag_damaged= swap;
+
+ swap= pr_mat_damaged;
pr_mat_damaged= cr_mat_damaged;
- cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"mat_damaged 3");
+ cr_mat_damaged= swap;
- /* Update faces */
curf= 0;
for(i=0; i<cr_lvl->totface; ++i) {
const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
@@ -1551,14 +1507,58 @@ void multires_update_levels(Mesh *me, const int render)
cr_lvl= cr_lvl->prev;
}
+
+ /* Clear to original damages */
+ if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
+ if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
+ cr_flag_damaged= or_flag_damaged;
+ cr_mat_damaged= or_mat_damaged;
+
+ /* Update higher levels */
+ pr_lvl= current_level(me->mr);
+ cr_lvl= pr_lvl->next;
+ while(cr_lvl) {
+ swap= pr_flag_damaged;
+ pr_flag_damaged= cr_flag_damaged;
+ cr_flag_damaged= swap;
+
+ swap= pr_mat_damaged;
+ pr_mat_damaged= cr_mat_damaged;
+ cr_mat_damaged= swap;
+
+ /* Update faces */
+ for(i=0, curf= 0; i<pr_lvl->totface; ++i) {
+ const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
+ for(j=0; j<sides; ++j, ++curf) {
+ if(pr_flag_damaged[i]) {
+ cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
+ cr_flag_damaged[curf]= 1;
+ }
+ if(pr_mat_damaged[i]) {
+ cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
+ cr_mat_damaged[curf]= 1;
+ }
+ }
+ }
+
+ pr_lvl= pr_lvl->next;
+ cr_lvl= cr_lvl->next;
+ }
if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
+}
- multires_update_colors(me);
+void multires_update_levels(Mesh *me, const int render)
+{
+ EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
+ multires_update_first_level(me, em);
+ multires_update_vertices(me, em);
+ multires_update_faces(me, em);
+ multires_update_colors(me);
}
void multires_calc_level_maps(MultiresLevel *lvl)