diff options
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/SConscript | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 99 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 129 |
3 files changed, 211 insertions, 19 deletions
diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 0333eab7e1f..20b560744b3 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' -incs += ' ../render/extern/include ../makesrna ../nodes ../imbuf' +incs += ' ../render/extern/include ../makesrna ../nodes ../bmesh ../imbuf' incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1c9cbc6b1ee..0328be060cc 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -97,9 +97,11 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" +#include "BLI_cellalloc.h" +#include "BLI_edgehash.h" #include "BKE_anim.h" #include "BKE_action.h" @@ -2702,6 +2704,16 @@ static void lib_link_key(FileData *fd, Main *main) key= main->key.first; while(key) { + /*check if we need to generate unique ids for the shapekeys*/ + if (!key->uidgen) { + KeyBlock *block; + + key->uidgen = 1; + for (block=key->block.first; block; block=block->next) { + block->uid = key->uidgen++; + } + } + if(key->id.flag & LIB_NEEDLINK) { if(key->adt) lib_link_animdata(fd, &key->id, key->adt); @@ -3624,6 +3636,26 @@ static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata } +static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface) +{ + int i; + + for(i=0; i<pdata->totlayer; i++) { + CustomDataLayer *layer = &pdata->layers[i]; + + if(layer->type == CD_MTEXPOLY) { + MTexPoly *tf= layer->data; + int i; + + for (i=0; i<totface; i++, tf++) { + tf->tpage= newlibadr(fd, me->id.lib, tf->tpage); + if(tf->tpage && tf->tpage->id.us==0) + tf->tpage->id.us= 1; + } + } + } +} + static void lib_link_mesh(FileData *fd, Main *main) { Mesh *me; @@ -3651,10 +3683,32 @@ static void lib_link_mesh(FileData *fd, Main *main) me->texcomesh= newlibadr_us(fd, me->id.lib, me->texcomesh); lib_link_customdata_mtface(fd, me, &me->fdata, me->totface); + lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly); if(me->mr && me->mr->levels.first) lib_link_customdata_mtface(fd, me, &me->mr->fdata, ((MultiresLevel*)me->mr->levels.first)->totface); + /*check if we need to convert mfaces to mpolys*/ + if (me->totface && !me->totpoly) { + convert_mfaces_to_mpolys(me); + } + + /* + * Re-tesselate, even if the polys were just created from tessfaces, this + * is important because it: + * - fill the CD_POLYINDEX layer + * - gives consistency of tessface between loading from a file and + * converting an edited BMesh back into a mesh (i.e. it replaces + * quad tessfaces in a loaded mesh immediately, instead of lazily + * waiting until edit mode has been entered/exited, making it easier + * to recognize problems that would otherwise only show up after edits). + */ + me->totface = mesh_recalcTesselation( + &me->fdata, &me->ldata, &me->pdata, + me->mvert, me->totface, me->totloop, me->totpoly); + + mesh_update_customdata_pointers(me, TRUE); + me->id.flag -= LIB_NEEDLINK; } me= me->id.next; @@ -3673,10 +3727,17 @@ static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts) } for (i= count; i > 0; i--, mdverts++) { - if(mdverts->dw) { - mdverts->dw= newdataadr(fd, mdverts->dw); + /*convert to vgroup allocation system*/ + MDeformWeight *dw; + if(mdverts->dw && (dw= newdataadr(fd, mdverts->dw))) { + const ssize_t dw_len= mdverts->totweight * sizeof(MDeformWeight); + void *dw_tmp= BLI_cellalloc_malloc(dw_len, "direct_link_dverts"); + memcpy(dw_tmp, dw, dw_len); + mdverts->dw= dw_tmp; + MEM_freeN(dw); } - if (mdverts->dw == NULL) { + else { + mdverts->dw= NULL; mdverts->totweight= 0; } } @@ -3689,7 +3750,18 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int exte for(i = 0; i < count; ++i) { mdisps[i].disps = newdataadr(fd, mdisps[i].disps); - + + /*put .disps into cellalloc system*/ + if (mdisps[i].disps) { + float *disp2; + + disp2 = BLI_cellalloc_malloc(MEM_allocN_len(mdisps[i].disps), "cellalloc .disps copy"); + memcpy(disp2, mdisps[i].disps, MEM_allocN_len(mdisps[i].disps)); + + MEM_freeN(mdisps[i].disps); + mdisps[i].disps = (float (*)[3])disp2; + } + if( (fd->flags & FD_FLAGS_SWITCH_ENDIAN) && (mdisps[i].disps) ) { /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */ /* this does swap for data written at write_mdisps() - readfile.c */ @@ -3739,12 +3811,17 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->mvert= newdataadr(fd, mesh->mvert); mesh->medge= newdataadr(fd, mesh->medge); mesh->mface= newdataadr(fd, mesh->mface); + mesh->mloop= newdataadr(fd, mesh->mloop); + mesh->mpoly= newdataadr(fd, mesh->mpoly); mesh->tface= newdataadr(fd, mesh->tface); mesh->mtface= newdataadr(fd, mesh->mtface); mesh->mcol= newdataadr(fd, mesh->mcol); mesh->msticky= newdataadr(fd, mesh->msticky); mesh->dvert= newdataadr(fd, mesh->dvert); - + mesh->mloopcol= newdataadr(fd, mesh->mloopcol); + mesh->mloopuv= newdataadr(fd, mesh->mloopuv); + mesh->mtpoly= newdataadr(fd, mesh->mtpoly); + /* animdata */ mesh->adt= newdataadr(fd, mesh->adt); direct_link_animdata(fd, mesh->adt); @@ -3756,7 +3833,9 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) direct_link_customdata(fd, &mesh->vdata, mesh->totvert); direct_link_customdata(fd, &mesh->edata, mesh->totedge); direct_link_customdata(fd, &mesh->fdata, mesh->totface); - + direct_link_customdata(fd, &mesh->ldata, mesh->totloop); + direct_link_customdata(fd, &mesh->pdata, mesh->totpoly); + #ifdef USE_BMESH_FORWARD_COMPAT /* NEVER ENABLE THIS CODE INTO BMESH! @@ -3789,7 +3868,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->bb= NULL; mesh->mselect = NULL; - mesh->edit_mesh= NULL; + mesh->edit_btmesh= NULL; /* Multires data */ mesh->mr= newdataadr(fd, mesh->mr); @@ -6573,7 +6652,7 @@ static void customdata_version_242(Mesh *me) } } - mesh_update_customdata_pointers(me); + mesh_update_customdata_pointers(me, TRUE); } /*only copy render texface layer from active*/ @@ -12275,7 +12354,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Mesh *me; for(me= main->mesh.first; me; me= me->id.next) - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + mesh_calc_normals_tessface(me->mvert, me->totvert, me->mface, me->totface, NULL); } if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)){ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 7cde4c8a1e2..b621a740b66 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -152,6 +152,7 @@ Any case: direct data is ALWAYS after the lib block #include "BKE_modifier.h" #include "BKE_fcurve.h" #include "BKE_pointcache.h" +#include "BKE_mesh.h" #include "BLO_writefile.h" #include "BLO_readfile.h" @@ -1682,22 +1683,134 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, static void write_meshs(WriteData *wd, ListBase *idbase) { Mesh *mesh; + int save_for_old_blender= 0; + +#ifdef USE_BMESH_SAVE_AS_COMPAT + save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */ +#endif mesh= idbase->first; while(mesh) { if(mesh->id.us>0 || wd->current) { /* write LibData */ - writestruct(wd, ID_ME, "Mesh", 1, mesh); + if (!save_for_old_blender) { + +#ifdef USE_BMESH_SAVE_WITHOUT_MFACE + Mesh backup_mesh = {{0}}; + /* cache only - dont write */ + backup_mesh.mface = mesh->mface; + mesh->mface = NULL; + /* -- */ + backup_mesh.totface = mesh->totface; + mesh->totface = 0; + /* -- */ +#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ + + writestruct(wd, ID_ME, "Mesh", 1, mesh); + + /* direct data */ + if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd); + if (mesh->adt) write_animdata(wd, mesh->adt); + + writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat); + + write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0); + /* fdata is really a dummy - written so slots align */ + write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0); + +#ifdef USE_BMESH_SAVE_WITHOUT_MFACE + /* cache only - dont write */ + mesh->mface = backup_mesh.mface; + /* -- */ + mesh->totface = backup_mesh.totface; +#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ - /* direct data */ - if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd); - if (mesh->adt) write_animdata(wd, mesh->adt); + } + else { - writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat); +#ifdef USE_BMESH_SAVE_AS_COMPAT - write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, -1, 0); - write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0); - write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0); + Mesh backup_mesh = {{0}}; + + /* backup */ + backup_mesh.mpoly = mesh->mpoly; + mesh->mpoly = NULL; + /* -- */ + backup_mesh.mface = mesh->mface; + mesh->mface = NULL; + /* -- */ + backup_mesh.totface = mesh->totface; + mesh->totface = 0; + /* -- */ + backup_mesh.totpoly = mesh->totpoly; + mesh->totpoly = 0; + /* -- */ + backup_mesh.totloop = mesh->totloop; + mesh->totloop = 0; + /* -- */ + backup_mesh.fdata = mesh->fdata; + memset(&mesh->fdata, 0, sizeof(CustomData)); + /* -- */ + backup_mesh.pdata = mesh->pdata; + memset(&mesh->pdata, 0, sizeof(CustomData)); + /* -- */ + backup_mesh.ldata = mesh->ldata; + memset(&mesh->ldata, 0, sizeof(CustomData)); + /* -- */ + backup_mesh.edit_btmesh = mesh->edit_btmesh; + mesh->edit_btmesh = NULL; + /* backup */ + + + /* now fill in polys to mfaces*/ + mesh->totface= mesh_mpoly_to_mface(&mesh->fdata, &backup_mesh.ldata, &backup_mesh.pdata, + mesh->totface, backup_mesh.totloop, backup_mesh.totpoly); + + mesh_update_customdata_pointers(mesh, FALSE); + + writestruct(wd, ID_ME, "Mesh", 1, mesh); + + /* direct data */ + if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd); + if (mesh->adt) write_animdata(wd, mesh->adt); + + writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat); + + write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0); + /* harmless for older blender versioins but _not_ writing these keeps file size down */ + /* + write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0); + write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0); + */ + + /* restore */ + mesh->mpoly = backup_mesh.mpoly; + mesh->totface = backup_mesh.totface; + mesh->totpoly = backup_mesh.totpoly; + mesh->totloop = backup_mesh.totloop; + /* -- */ + mesh->mface = backup_mesh.mface; + /* -- */ + CustomData_free(&mesh->fdata, mesh->totface); + /* -- */ + mesh->fdata= backup_mesh.fdata; + /* -- */ + mesh->pdata= backup_mesh.pdata; + /* -- */ + mesh->ldata= backup_mesh.ldata; + /* -- */ + mesh_update_customdata_pointers(mesh, FALSE); + /* --*/ + mesh->edit_btmesh = backup_mesh.edit_btmesh; /* keep this after updating custom pointers */ + /* restore */ + +#endif /* USE_BMESH_SAVE_AS_COMPAT */ + } } mesh= mesh->id.next; } |