diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2007-01-22 02:46:00 +0300 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2007-01-22 02:46:00 +0300 |
commit | a9cd5b808cea7c906146a2ebafc3d0be00076ebd (patch) | |
tree | b8145604bff8a7f79e4d47f7ecb96eff4b362f77 /source/blender/blenkernel | |
parent | e64afa6c177c20ced38abe609ea5b0b21a02b8e6 (diff) |
= Multires =
Fixed bug #5756, Rendering artifacts when MRM is not set to maximum
Several changes were made:
* Added function multires_level_n to get the nth level from a multires mesh
* Removed the changes I made some time ago to init_render_mesh for multires meshes. Previously it was making a full copy of the mesh object in order to be able to apply deformations to the Pin level and propagate them to the Render level.
* Added two functions to DerivedMesh.c, multires_render_pin and multires_render_final. These two functions work together in the mesh_create_derived_*_render functions to apply all modifiers to the Pin level, then create the DerivedMesh from the Render level, and lastly restore the mesh to its original (undeformed) state.
* Added a check in multires_del_lower and multires_del_higher to ensure that level indices are properly clipped to the actual range of available levels.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_bad_level_calls.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/bad_level_call_stubs/stubs.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 92 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 22 |
4 files changed, 93 insertions, 23 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]; |