merge with trunk at r31523
[blender.git] / source / blender / blenloader / intern / readfile.c
index c37585faed9b8e46d2a21838c1119beb75e9ed36..44cc6b5c1d921f3ca5f0b1fdc115e79b27308c58 100644 (file)
@@ -89,6 +89,8 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
+#include "BLI_cellalloc.h"
+#include "BLI_edgehash.h"
 
 #include "BKE_anim.h"
 #include "BKE_action.h"
@@ -2373,6 +2375,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);
                        
@@ -3183,6 +3195,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;
@@ -3210,6 +3242,7 @@ 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);
@@ -3228,7 +3261,19 @@ static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
                return;
 
        for (i=0; i<count; i++) {
+               void *tmp;
+
                mdverts[i].dw=newdataadr(fd, mdverts[i].dw);
+               
+               /*convert to vgroup allocation system*/
+               if (mdverts[i].dw) {
+                       tmp = BLI_cellalloc_malloc(MEM_allocN_len(mdverts[i].dw), "vgroups from readfile.c");
+                       memcpy(tmp, mdverts[i].dw, MEM_allocN_len(mdverts[i].dw));
+
+                       MEM_freeN(mdverts[i].dw);
+                       mdverts[i].dw = tmp;
+               }
+
                if (!mdverts[i].dw)
                        mdverts[i].totweight=0;
        }
@@ -3247,6 +3292,8 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int exte
        }       
 }
 
+/*this isn't really a public api function, so prototyped here*/
+void customData_update_typemap(CustomData *data);
 static void direct_link_customdata(FileData *fd, CustomData *data, int count)
 {
        int i = 0;
@@ -3267,6 +3314,126 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
                        i++;
                }
        }
+
+       customData_update_typemap(data);
+}
+
+
+void bmesh_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, int numCol) 
+{
+       MTFace *texface;
+       MTexPoly *texpoly;
+       MCol *mcol;
+       MLoopCol *mloopcol;
+       MLoopUV *mloopuv;
+       MFace *mf;
+       int i;
+
+       for(i=0; i < numTex; i++){
+               texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
+               texpoly = CustomData_get_n(&me->pdata, CD_MTEXPOLY, findex, i); 
+               mf = me->mface + findex;
+               
+               texpoly->tpage = texface->tpage;
+               texpoly->flag = texface->flag;
+               texpoly->transp = texface->transp;
+               texpoly->mode = texface->mode;
+               texpoly->tile = texface->tile;
+               texpoly->unwrap = texface->unwrap;
+       
+               mloopuv = CustomData_get_n(&me->ldata, CD_MLOOPUV, loopstart, i);
+               mloopuv->uv[0] = texface->uv[0][0]; mloopuv->uv[1] = texface->uv[0][1]; mloopuv++;
+               mloopuv->uv[0] = texface->uv[1][0]; mloopuv->uv[1] = texface->uv[1][1]; mloopuv++;
+               mloopuv->uv[0] = texface->uv[2][0]; mloopuv->uv[1] = texface->uv[2][1]; mloopuv++;
+
+               if (mf->v4) {
+                       mloopuv->uv[0] = texface->uv[3][0]; mloopuv->uv[1] = texface->uv[3][1]; mloopuv++;
+               }
+       }
+
+       for(i=0; i < numCol; i++){
+               mf = me->mface + findex;
+               mloopcol = CustomData_get_n(&me->ldata, CD_MLOOPCOL, loopstart, i);
+               mcol = CustomData_get_n(&me->fdata, CD_MCOL, findex, i);
+
+               mloopcol->r = mcol[0].r; mloopcol->g = mcol[0].g; mloopcol->b = mcol[0].b; mloopcol->a = mcol[0].a; mloopcol++;
+               mloopcol->r = mcol[1].r; mloopcol->g = mcol[1].g; mloopcol->b = mcol[1].b; mloopcol->a = mcol[1].a; mloopcol++;
+               mloopcol->r = mcol[2].r; mloopcol->g = mcol[2].g; mloopcol->b = mcol[2].b; mloopcol->a = mcol[2].a; mloopcol++;
+               if (mf->v4) {
+                       mloopcol->r = mcol[3].r; mloopcol->g = mcol[3].g; mloopcol->b = mcol[3].b; mloopcol->a = mcol[3].a; mloopcol++;
+               }
+       }
+}
+
+static void convert_mfaces_to_mpolys(Mesh *mesh)
+{
+       MFace *mf;
+       MLoop *ml;
+       MPoly *mp;
+       MEdge *me;
+       EdgeHash *eh;
+       int numTex, numCol;
+       int i, j, totloop;
+
+       mesh->totpoly = mesh->totface;
+       mesh->mpoly = MEM_callocN(sizeof(MPoly)*mesh->totpoly, "mpoly converted");
+       CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_ASSIGN, mesh->mpoly, mesh->totpoly);
+
+       numTex = CustomData_number_of_layers(&mesh->fdata, CD_MTFACE);
+       numCol = CustomData_number_of_layers(&mesh->fdata, CD_MCOL);
+       
+       totloop = 0;
+       mf = mesh->mface;
+       for (i=0; i<mesh->totface; i++, mf++) {
+               totloop += mf->v4 ? 4 : 3;
+       }
+       
+       mesh->totloop = totloop;
+       mesh->mloop = MEM_callocN(sizeof(MLoop)*mesh->totloop, "mloop converted");
+
+       CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_ASSIGN, mesh->mloop, totloop);
+       CustomData_to_bmeshpoly(&mesh->fdata, &mesh->pdata, &mesh->ldata,
+               mesh->totloop, mesh->totpoly);
+
+       eh = BLI_edgehash_new();
+
+       /*build edge hash*/
+       me = mesh->medge;
+       for (i=0; i<mesh->totedge; i++, me++) {
+               BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
+       }
+
+       j = 0; /*current loop index*/
+       ml = mesh->mloop;
+       mf = mesh->mface;
+       mp = mesh->mpoly;
+       for (i=0; i<mesh->totface; i++, mf++, mp++) {
+               mp->loopstart = j;
+               
+               mp->totloop = mf->v4 ? 4 : 3;
+
+               mp->mat_nr = mf->mat_nr;
+               mp->flag = mf->flag;
+               
+               #define ML(v1, v2) {ml->v = mf->v1; ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2)); ml++; j++;}
+               
+               ML(v1, v2);
+               ML(v2, v3);
+               if (mf->v4) {
+                       ML(v3, v4);
+                       ML(v4, v1);
+               } else {
+                       ML(v3, v1);
+               }
+               
+               #undef ML
+
+               bmesh_corners_to_loops(mesh, i, mp->loopstart, numTex, numCol);
+       }
+
+       /*BMESH_TODO now to deal with fgons*/
+
+       BLI_edgehash_free(eh, NULL);
 }
 
 static void direct_link_mesh(FileData *fd, Mesh *mesh)
@@ -3277,12 +3444,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);
@@ -3303,10 +3475,12 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        direct_link_customdata(fd, &mesh->vdata, mesh->pv ? mesh->pv->totvert : mesh->totvert);
        direct_link_customdata(fd, &mesh->edata, mesh->pv ? mesh->pv->totedge : mesh->totedge);
        direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
-
+       direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
+       direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
+       
        mesh->bb= NULL;
        mesh->mselect = NULL;
-       mesh->edit_mesh= NULL;
+       mesh->edit_btmesh= NULL;
        
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
@@ -3356,6 +3530,11 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
                        SWITCH_INT(tf->col[3]);
                }
        }
+
+       /*check if we need to convert mfaces to mpolys*/
+       if (mesh->totface && !mesh->totpoly) {
+               convert_mfaces_to_mpolys(mesh);
+       }
 }
 
 /* ************ READ LATTICE ***************** */