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:
-rw-r--r--source/blender/blenkernel/BKE_bad_level_calls.h1
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/stubs.c1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c92
-rw-r--r--source/blender/blenkernel/intern/mesh.c22
-rw-r--r--source/blender/include/multires.h2
-rw-r--r--source/blender/render/intern/source/convertblender.c20
-rw-r--r--source/blender/src/multires.c30
7 files changed, 126 insertions, 42 deletions
diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h
index 90ae0c10766..5c71fb6cf31 100644
--- a/source/blender/blenkernel/BKE_bad_level_calls.h
+++ b/source/blender/blenkernel/BKE_bad_level_calls.h
@@ -199,6 +199,7 @@ void post_server_add(void);
/* multires.c */
struct Multires;
struct MultiresLevel;
+struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
void multires_free(struct Multires *mr);
void multires_set_level(void *ob, void *me_v);
void multires_calc_level_maps(struct MultiresLevel *lvl);
diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
index 63b904c57cc..fc01086a48c 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c
+++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
@@ -292,6 +292,7 @@ void post_layer_create(struct VLayer *vlayer) {}
void post_layer_destroy(struct VLayer *vlayer) {}
void post_server_add(void) {}
/* Multires/sculpt stubs */
+struct MultiresLevel *multires_level_n(struct Multires *mr, int n) {return NULL;}
void multires_free(struct Multires *mr) {}
void multires_set_level(void *ob, void *me_v) {}
void multires_calc_level_maps(struct MultiresLevel *lvl) {}
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b6ba816698b..62c1a5f613f 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2213,31 +2213,80 @@ DerivedMesh *mesh_get_derived_deform(Object *ob, CustomDataMask dataMask)
return ob->derivedDeform;
}
-DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
+/* Move to multires Pin level, returns a copy of the original vertex coords. */
+float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
{
- DerivedMesh *final;
- Mesh *m= get_mesh(ob);
+ float *vert_copy= NULL;
- /* Goto the pin level for multires */
- if(m->mr) {
- m->mr->newlvl= m->mr->pinlvl;
- multires_set_level(ob,m);
+ if(me->mr) {
+ MultiresLevel *lvl= NULL;
+ int i;
+
+ /* Copy the highest level of multires verts */
+ *orig_lvl= me->mr->current;
+ 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);
+
+ /* Goto the pin level for multires */
+ me->mr->newlvl= me->mr->pinlvl;
+ multires_set_level(ob, me);
}
+
+ return vert_copy;
+}
- mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask);
+/* Propagate the changes to render level - fails if mesh topology changed */
+void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy, const int orig_lvl)
+{
+ if(me->mr) {
+ if((*dm)->getNumVerts(*dm) == me->totvert &&
+ (*dm)->getNumFaces(*dm) == me->totface) {
+ MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
+ DerivedMesh *old= NULL;
+ int i;
- /* Propagate the changes to render level - fails if mesh topology changed */
- if(m->mr) {
- if(final->getNumVerts(final) == m->totvert &&
- final->getNumFaces(final) == m->totface) {
- final->copyVertArray(final, m->mvert);
- final->release(final);
-
- m->mr->newlvl= m->mr->renderlvl;
- multires_set_level(ob,m);
- final= getMeshDerivedMesh(m,ob,NULL);
+ (*dm)->copyVertArray(*dm, me->mvert);
+ (*dm)->release(*dm);
+
+ me->mr->newlvl= me->mr->renderlvl;
+ multires_set_level(ob, me);
+ (*dm)= getMeshDerivedMesh(me, ob, NULL);
+
+ /* Some of the data in dm is referenced externally, so make a copy */
+ old= *dm;
+ (*dm)= CDDM_copy(old);
+ old->release(old);
+
+ /* Restore the original verts */
+ me->mr->newlvl= BLI_countlist(&me->mr->levels);
+ multires_set_level(ob, me);
+ for(i=0; i<lvl->totvert; ++i)
+ VecCopyf(me->mvert[i].co, &vert_copy[i*3]);
}
+
+ if(vert_copy)
+ MEM_freeN(vert_copy);
+
+ me->mr->newlvl= orig_lvl;
+ multires_set_level(ob, me);
}
+}
+
+/* Multires note - if mesh has multires enabled, mesh is first set to the Pin level,
+ where all modifiers are applied, then if the topology hasn't changed, the changes
+ from modifiers are propagated up to the Render level. */
+DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
+{
+ DerivedMesh *final;
+ Mesh *me= get_mesh(ob);
+ float *vert_copy= NULL;
+ int orig_lvl= 0;
+
+ vert_copy= multires_render_pin(ob, me, &orig_lvl);
+ mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask);
+ multires_render_final(ob, me, &final, vert_copy, orig_lvl);
return final;
}
@@ -2255,7 +2304,7 @@ DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3],
CustomDataMask dataMask)
{
DerivedMesh *final;
-
+
mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0, dataMask);
return final;
@@ -2266,8 +2315,13 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
CustomDataMask dataMask)
{
DerivedMesh *final;
+ Mesh *me= get_mesh(ob);
+ float *vert_copy= NULL;
+ int orig_lvl= 0;
+ vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask);
+ multires_render_final(ob, me, &final, vert_copy, orig_lvl);
return final;
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index cfdb79c2257..9f9e39cbd8a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -481,11 +481,13 @@ static float *make_orco_mesh_internal(Object *ob, int render)
int a, totvert;
float loc[3], size[3];
DerivedMesh *dm;
- float (*vcos)[3] = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
+ float (*vcos)[3] = NULL;
/* Get appropriate vertex coordinates */
if(me->key && me->texcomesh==0 && me->key->refkey) {
+ vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
+
KeyBlock *kb= me->key->refkey;
float *fp= kb->data;
totvert= MIN2(kb->totelem, me->totvert);
@@ -497,9 +499,21 @@ static float *make_orco_mesh_internal(Object *ob, int render)
}
}
else {
- Mesh *tme = me->texcomesh?me->texcomesh:me;
- MVert *mvert = tme->mvert;
- totvert = MIN2(tme->totvert, me->totvert);
+ MultiresLevel *lvl = NULL;
+ MVert *mvert = NULL;
+
+ 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;
+ totvert = lvl->totvert;
+ }
+ else {
+ vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
+ Mesh *tme = me->texcomesh?me->texcomesh:me;
+ mvert = tme->mvert;
+ totvert = MIN2(tme->totvert, me->totvert);
+ }
for(a=0; a<totvert; a++, mvert++) {
vcos[a][0]= mvert->co[0];
diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h
index cf96ea58869..48a5b4554a9 100644
--- a/source/blender/include/multires.h
+++ b/source/blender/include/multires.h
@@ -42,6 +42,8 @@ struct uiBlock;
int multires_test();
int multires_level1_test();
+struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
+
void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned short cy);
void multires_disp_map(void *, void*);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 21cada785a7..d98d570803d 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1766,7 +1766,7 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak
static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts)
{
- Mesh *me, *me_store= NULL;
+ Mesh *me;
MVert *mvert = NULL;
MFace *mface;
VlakRen *vlr; //, *vlr1;
@@ -1834,23 +1834,8 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
if(!only_verts)
if(need_orco) orco = get_object_orco(re, ob);
- /* If multires is enabled, a copy is made of the mesh
- to allow multires to be applied with modifiers. */
- if(me->mr) {
- me_store= me;
- me= copy_mesh(me);
- ob->data= me;
- }
-
dm = mesh_create_derived_render(ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
-
- /* (Multires) Now switch the meshes back around */
- if(me->mr) {
- ob->data= me_store;
- me_store= me;
- me= ob->data;
- }
if(dm==NULL) return; /* in case duplicated object fails? */
@@ -2087,9 +2072,6 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
}
dm->release(dm);
- if(me_store) {
- free_libblock(&G.main->mesh, &me_store->id);
- }
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c
index acf53e08ccd..554cdf3e9e8 100644
--- a/source/blender/src/multires.c
+++ b/source/blender/src/multires.c
@@ -124,6 +124,14 @@ MultiresLevel *current_level(Multires *mr)
return BLI_findlink(&mr->levels, mr->current - 1);
}
+MultiresLevel *multires_level_n(Multires *mr, int n)
+{
+ if(mr)
+ return BLI_findlink(&mr->levels, n - 1);
+ else
+ return NULL;
+}
+
void Vec3fAvg3(float *out, float *v1, float *v2, float *v3)
{
out[0]= (v1[0]+v2[0]+v3[0])/3;
@@ -693,6 +701,24 @@ void multires_free_level(MultiresLevel *lvl)
}
}
+/* Make sure that all level indices are clipped to [1, mr->level_count] */
+void multires_clip_levels(Multires *mr)
+{
+ if(mr) {
+ const int cnt = mr->level_count;
+
+ if(mr->current < 1) mr->current = 1;
+ if(mr->edgelvl < 1) mr->edgelvl = 1;
+ if(mr->pinlvl < 1) mr->pinlvl = 1;
+ if(mr->renderlvl < 1) mr->renderlvl = 1;
+
+ if(mr->current > cnt) mr->current = cnt;
+ if(mr->edgelvl > cnt) mr->edgelvl = cnt;
+ if(mr->pinlvl > cnt) mr->pinlvl = cnt;
+ if(mr->renderlvl > cnt) mr->renderlvl = cnt;
+ }
+}
+
/* Delete all multires levels beneath current level. Subdivide special
first-level data up to the new lowest level. */
void multires_del_lower(void *ob, void *me)
@@ -730,6 +756,8 @@ void multires_del_lower(void *ob, void *me)
lvl= lvlprev;
}
mr->newlvl= mr->current;
+
+ multires_clip_levels(mr);
allqueue(REDRAWBUTSEDIT, 0);
@@ -755,6 +783,8 @@ void multires_del_higher(void *ob, void *me)
lvl= lvlnext;
}
+
+ multires_clip_levels(mr);
allqueue(REDRAWBUTSEDIT, 0);