svn merge ^/trunk/blender -r42416:42422
authorCampbell Barton <ideasman42@gmail.com>
Sun, 4 Dec 2011 20:05:50 +0000 (20:05 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 4 Dec 2011 20:05:50 +0000 (20:05 +0000)
1  2 
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/mesh.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_modifier.c
source/blender/makesdna/DNA_mesh_types.h
source/blender/makesdna/DNA_meshdata_types.h

Simple merge
@@@ -387,24 -113,11 +387,12 @@@ void unlink_mesh(Mesh *me
        if(me->texcomesh) me->texcomesh= NULL;
  }
  
  /* do not free mesh itself */
 -void free_mesh(Mesh *me)
 +void free_mesh(Mesh *me, int unlink)
  {
 -      unlink_mesh(me);
 +      if (unlink)
 +              unlink_mesh(me);
  
-       if(me->pv) {
-               if(me->pv->vert_map) MEM_freeN(me->pv->vert_map);
-               if(me->pv->edge_map) MEM_freeN(me->pv->edge_map);
-               if(me->pv->old_faces) MEM_freeN(me->pv->old_faces);
-               if(me->pv->old_edges) MEM_freeN(me->pv->old_edges);
-               me->totvert= me->pv->totvert;
-               me->totedge= me->pv->totedge;
-               me->totface= me->pv->totface;
-               MEM_freeN(me->pv);
-       }
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
        CustomData_free(&me->fdata, me->totface);
@@@ -508,19 -216,8 +496,18 @@@ Mesh *copy_mesh(Mesh *me
                }
        }
        
 +      for(i=0; i<me->pdata.totlayer; i++) {
 +              if(me->pdata.layers[i].type == CD_MTEXPOLY) {
 +                      txface= (MTexPoly*)me->pdata.layers[i].data;
 +
 +                      for(a=0; a<me->totpoly; a++, txface++)
 +                              if(txface->tpage)
 +                                      id_lib_extern((ID*)txface->tpage);
 +              }
 +      }
 +
        men->mselect= NULL;
 -      men->edit_mesh= NULL;
 +      men->edit_btmesh= NULL;
-       men->pv= NULL; /* looks like this is no-longer supported but NULL just incase */
  
        men->bb= MEM_dupallocN(men->bb);
        
@@@ -2109,480 -1443,6 +2096,414 @@@ void create_vert_edge_map(ListBase **ma
        }
  }
  
- /* Partial Mesh Visibility */
- PartialVisibility *mesh_pmv_copy(PartialVisibility *pmv)
- {
-       PartialVisibility *n= MEM_dupallocN(pmv);
-       n->vert_map= MEM_dupallocN(pmv->vert_map);
-       n->edge_map= MEM_dupallocN(pmv->edge_map);
-       n->old_edges= MEM_dupallocN(pmv->old_edges);
-       n->old_faces= MEM_dupallocN(pmv->old_faces);
-       return n;
- }
- void mesh_pmv_free(PartialVisibility *pv)
- {
-       MEM_freeN(pv->vert_map);
-       MEM_freeN(pv->edge_map);
-       MEM_freeN(pv->old_faces);
-       MEM_freeN(pv->old_edges);
-       MEM_freeN(pv);
- }
- void mesh_pmv_revert(Mesh *me)
- {
-       if(me->pv) {
-               unsigned i;
-               MVert *nve, *old_verts;
-               
-               /* Reorder vertices */
-               nve= me->mvert;
-               old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts");
-               for(i=0; i<me->pv->totvert; ++i)
-                       old_verts[i]= nve[me->pv->vert_map[i]];
-               /* Restore verts, edges and faces */
-               CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
-               CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
-               CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
-               CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert);
-               CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge);
-               CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->pv->old_faces, me->pv->totface);
-               mesh_update_customdata_pointers(me);
-               me->totvert= me->pv->totvert;
-               me->totedge= me->pv->totedge;
-               me->totface= me->pv->totface;
-               me->pv->old_edges= NULL;
-               me->pv->old_faces= NULL;
-               /* Free maps */
-               MEM_freeN(me->pv->edge_map);
-               me->pv->edge_map= NULL;
-               MEM_freeN(me->pv->vert_map);
-               me->pv->vert_map= NULL;
-       }
- }
- void mesh_pmv_off(Mesh *me)
- {
-       if(me->pv) {
-               mesh_pmv_revert(me);
-               MEM_freeN(me->pv);
-               me->pv= NULL;
-       }
- }
 +void mesh_loops_to_tri_corners(CustomData *fdata, CustomData *ldata, 
 +                         CustomData *pdata, int lindex[3], int findex, 
 +                         int polyindex) 
 +{
 +      MTFace *texface;
 +      MTexPoly *texpoly;
 +      MCol *mcol;
 +      MLoopCol *mloopcol;
 +      MLoopUV *mloopuv;
 +      int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
 +      int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
 +      int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
 +      
 +      for(i=0; i < numTex; i++){
 +              texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
 +              texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
 +              
 +              texface->tpage = texpoly->tpage;
 +              texface->flag = texpoly->flag;
 +              texface->transp = texpoly->transp;
 +              texface->mode = texpoly->mode;
 +              texface->tile = texpoly->tile;
 +              texface->unwrap = texpoly->unwrap;
 +
 +              for (j=0; j<3; j++) {
 +                      mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i);
 +                      texface->uv[j][0] = mloopuv->uv[0];
 +                      texface->uv[j][1] = mloopuv->uv[1];
 +              }
 +      }
 +
 +      for(i=0; i < numCol; i++){
 +              mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
 +
 +              for (j=0; j<3; j++) {
 +                      mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i);
 +                      mcol[j].r = mloopcol->r;
 +                      mcol[j].g = mloopcol->g;
 +                      mcol[j].b = mloopcol->b;
 +                      mcol[j].a = mloopcol->a;
 +              }
 +      }
 +
 +      if (hasWCol) {
 +              mcol = CustomData_get(fdata,  findex, CD_WEIGHT_MCOL);
 +
 +              for (j=0; j<3; j++) {
 +                      mloopcol = CustomData_get(ldata, lindex[j], CD_WEIGHT_MLOOPCOL);
 +                      mcol[j].r = mloopcol->r;
 +                      mcol[j].g = mloopcol->g;
 +                      mcol[j].b = mloopcol->b;
 +                      mcol[j].a = mloopcol->a;
 +              }
 +      }
 +}
 +
 +/*
 +  this function recreates a tesselation.
 +  returns number of tesselation faces.
 + */
 +int mesh_recalcTesselation(CustomData *fdata, 
 +                           CustomData *ldata, CustomData *pdata,
 +                           MVert *mvert, int totface, int UNUSED(totloop),
 +                           int totpoly)
 +{
 +
 +      /* use this to avoid locking pthread for _every_ polygon
 +       * and calling the fill function */
 +
 +#define USE_TESSFACE_SPEEDUP
 +
 +      MPoly *mp, *mpoly;
 +      MLoop *ml, *mloop;
 +      MFace *mface = NULL, *mf;
 +      BLI_array_declare(mface);
 +      EditVert *v, *lastv, *firstv;
 +      EditFace *f;
 +      int *origIndex = NULL;
 +      BLI_array_declare(origIndex);
 +      int *polyIndex = NULL;
 +      BLI_array_declare(polyIndex);
 +      int i, j, k, lindex[4], *polyorigIndex;
 +      int numTex, numCol;
 +
 +      mpoly = CustomData_get_layer(pdata, CD_MPOLY);
 +      mloop = CustomData_get_layer(ldata, CD_MLOOP);
 +
 +      numTex = CustomData_number_of_layers(ldata, CD_MLOOPUV);
 +      numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
 +      
 +      k = 0;
 +      mp = mpoly;
 +      polyorigIndex = CustomData_get_layer(pdata, CD_ORIGINDEX);
 +      for (i=0; i<totpoly; i++, mp++) {
 +              if (mp->totloop < 3) {
 +                      /* do nothing */
 +              }
 +
 +#ifdef USE_TESSFACE_SPEEDUP
 +
 +#define ML_TO_MF(i1, i2, i3)                                                  \
 +              BLI_array_growone(mface);                                             \
 +              BLI_array_append(polyIndex, i);                                       \
 +              mf= &mface[k];                                                        \
 +              /* set loop indices, transformed to vert indices later */             \
 +              mf->v1 = mp->loopstart + i1;                                          \
 +              mf->v2 = mp->loopstart + i2;                                          \
 +              mf->v3 = mp->loopstart + i3;                                          \
 +              mf->v4 = 0;                                                           \
 +              mf->mat_nr = mp->mat_nr;                                              \
 +              mf->flag = mp->flag;                                                  \
 +              if (polyorigIndex) {                                                  \
 +                      BLI_array_append(origIndex, polyorigIndex[polyIndex[k]]);         \
 +              }                                                                     \
 +
 +              else if (mp->totloop == 3) {
 +                      ml = mloop + mp->loopstart;
 +                      ML_TO_MF(0, 1, 2)
 +                      k++;
 +              }
 +              else if (mp->totloop == 4) {
 +                      ml = mloop + mp->loopstart;
 +                      ML_TO_MF(0, 1, 2)
 +                      k++;
 +                      ML_TO_MF(0, 2, 3)
 +                      k++;
 +              }
 +#endif /* USE_TESSFACE_SPEEDUP */
 +              else {
 +                      ml = mloop + mp->loopstart;
 +                      
 +                      BLI_begin_edgefill();
 +                      firstv = NULL;
 +                      lastv = NULL;
 +                      for (j=0; j<mp->totloop; j++, ml++) {
 +                              v = BLI_addfillvert(mvert[ml->v].co);
 +      
 +                              v->keyindex = mp->loopstart + j;
 +      
 +                              if (lastv)
 +                                      BLI_addfilledge(lastv, v);
 +      
 +                              if (!firstv)
 +                                      firstv = v;
 +                              lastv = v;
 +                      }
 +                      BLI_addfilledge(lastv, firstv);
 +                      
 +                      BLI_edgefill(2);
 +                      for (f=fillfacebase.first; f; f=f->next) {
 +                              BLI_array_growone(mface);
 +                              BLI_array_append(polyIndex, i);
 +                              mf= &mface[k];
 +
 +                              /* set loop indices, transformed to vert indices later */
 +                              mf->v1 = f->v1->keyindex;
 +                              mf->v2 = f->v2->keyindex;
 +                              mf->v3 = f->v3->keyindex;
 +                              mf->v4 = 0;
 +                              
 +                              mf->mat_nr = mp->mat_nr;
 +                              mf->flag = mp->flag;
 +
 +                              if (polyorigIndex) {
 +                                      BLI_array_append(origIndex, polyorigIndex[polyIndex[k]]);
 +                              }
 +      
 +                              k++;
 +                      }
 +      
 +                      BLI_end_edgefill();
 +              }
 +      }
 +
 +      CustomData_free(fdata, totface);
 +      memset(fdata, 0, sizeof(CustomData));
 +      totface = k;
 +      
 +      CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
 +
 +      /* CD_POLYINDEX will contain an array of indices from tessfaces to the polygons
 +         they are directly tesselated from */
 +      CustomData_add_layer(fdata, CD_POLYINDEX, CD_ASSIGN, polyIndex, totface);
 +      if (origIndex) {
 +              /* If polys had a CD_ORIGINDEX layer, then the tesselated faces will get this
 +                 layer as well, pointing to polys from the original mesh (not the polys
 +                 that just got tesselated) */
 +              CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, origIndex, totface);
 +      }
 +
 +      CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
 +
 +      /* If polys have a normals layer, copying that to faces can help
 +         avoid the need to recalculate normals later */
 +      if (CustomData_has_layer(pdata, CD_NORMAL)) {
 +              float *pnors = CustomData_get_layer(pdata, CD_NORMAL);
 +              float *fnors = CustomData_add_layer(fdata, CD_NORMAL, CD_CALLOC, NULL, totface);
 +              for (i=0; i<totface; i++, fnors++) {
 +                      copy_v3_v3(fnors, &pnors[polyIndex[i]]);
 +              }
 +      }
 +
 +      mf = mface;
 +      for (i=0; i < totface; i++, mf++) {
 +              /*sort loop indices to ensure winding is correct*/
 +              if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
 +              if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3);
 +              if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
 +
 +              if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
 +              if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3);
 +              if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
 +      
 +              lindex[0] = mf->v1;
 +              lindex[1] = mf->v2;
 +              lindex[2] = mf->v3;
 +
 +              /*transform loop indices to vert indices*/
 +              mf->v1 = mloop[mf->v1].v;
 +              mf->v2 = mloop[mf->v2].v;
 +              mf->v3 = mloop[mf->v3].v;
 +
 +              mesh_loops_to_tri_corners(fdata, ldata, pdata,
 +                      lindex, i, polyIndex[i]);
 +      }
 +
 +      return totface;
 +
 +#undef USE_TESSFACE_SPEEDUP
 +
 +}
 +
 +/*
 + * COMPUTE POLY NORMAL
 + *
 + * Computes the normal of a planar 
 + * polygon See Graphics Gems for 
 + * computing newell normal.
 + *
 +*/
 +static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart, 
 +                                  MVert *mvert, float normal[3])
 +{
 +
 +      MVert *v1, *v2, *v3;
 +      double u[3], v[3], w[3];
 +      double n[3] = {0.0, 0.0, 0.0}, l;
 +      int i;
 +
 +      for(i = 0; i < mpoly->totloop; i++){
 +              v1 = mvert + loopstart[i].v;
 +              v2 = mvert + loopstart[(i+1)%mpoly->totloop].v;
 +              v3 = mvert + loopstart[(i+2)%mpoly->totloop].v;
 +              
 +              VECCOPY(u, v1->co);
 +              VECCOPY(v, v2->co);
 +              VECCOPY(w, v3->co);
 +
 +              /*this fixes some weird numerical error*/
 +              if (i==0) {
 +                      u[0] += 0.0001f;
 +                      u[1] += 0.0001f;
 +                      u[2] += 0.0001f;
 +              }
 +              
 +              /* newell's method
 +              
 +              so thats?:
 +              (a[1] - b[1]) * (a[2] + b[2]);
 +              a[1]*b[2] - b[1]*a[2] - b[1]*b[2] + a[1]*a[2]
 +
 +              odd.  half of that is the cross product. . .what's the
 +              other half?
 +
 +              also could be like a[1]*(b[2] + a[2]) - b[1]*(a[2] - b[2])
 +              */
 +
 +              n[0] += (u[1] - v[1]) * (u[2] + v[2]);
 +              n[1] += (u[2] - v[2]) * (u[0] + v[0]);
 +              n[2] += (u[0] - v[0]) * (u[1] + v[1]);
 +      }
 +      
 +      l = n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
 +      l = sqrt(l);
 +
 +      if (l == 0.0) {
 +              normal[0] = 0.0f;
 +              normal[1] = 0.0f;
 +              normal[2] = 1.0f;
 +
 +              return;
 +      } else l = 1.0f / l;
 +
 +      n[0] *= l;
 +      n[1] *= l;
 +      n[2] *= l;
 +      
 +      normal[0] = (float) n[0];
 +      normal[1] = (float) n[1];
 +      normal[2] = (float) n[2];
 +}
 +
 +void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, 
 +                           MVert *mvarray, float no[3])
 +{
 +      if (mpoly->totloop > 4) {
 +              mesh_calc_ngon_normal(mpoly, loopstart, mvarray, no);
 +      }
 +      else if (mpoly->totloop == 3){
 +              normal_tri_v3(no,
 +                            mvarray[loopstart[0].v].co,
 +                            mvarray[loopstart[1].v].co,
 +                            mvarray[loopstart[2].v].co
 +                            );
 +      }
 +      else if (mpoly->totloop == 4) {
 +              normal_quad_v3(no,
 +                             mvarray[loopstart[0].v].co,
 +                             mvarray[loopstart[1].v].co,
 +                             mvarray[loopstart[2].v].co,
 +                             mvarray[loopstart[3].v].co
 +                             );
 +      }
 +      else { /* horrible, two sided face! */
 +              no[0] = 0.0;
 +              no[1] = 0.0;
 +              no[2] = 1.0;
 +      }
 +}
 +
 +static void mesh_calc_ngon_center(MPoly *mpoly, MLoop *loopstart,
 +                                  MVert *mvert, float cent[3])
 +{
 +      const float w= 1.0f / (float)mpoly->totloop;
 +      int i;
 +
 +      zero_v3(cent);
 +
 +      for (i = 0; i < mpoly->totloop; i++) {
 +              madd_v3_v3fl(cent, mvert[(loopstart++)->v].co, w);
 +      }
 +}
 +
 +void mesh_calc_poly_center(MPoly *mpoly, MLoop *loopstart,
 +                           MVert *mvarray, float cent[3])
 +{
 +      if (mpoly->totloop == 3) {
 +              cent_tri_v3(cent,
 +                          mvarray[loopstart[0].v].co,
 +                          mvarray[loopstart[1].v].co,
 +                          mvarray[loopstart[2].v].co
 +                          );
 +      }
 +      else if (mpoly->totloop == 4) {
 +              cent_quad_v3(cent,
 +                           mvarray[loopstart[0].v].co,
 +                           mvarray[loopstart[1].v].co,
 +                           mvarray[loopstart[2].v].co,
 +                           mvarray[loopstart[3].v].co
 +                           );
 +      }
 +      else {
 +              mesh_calc_ngon_center(mpoly, loopstart, mvarray, cent);
 +      }
 +}
 +
 +/* note, passing polynormal is only a speedup so we can skip calculating it */
 +float mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
 +                          MVert *mvarray, float polynormal[3])
 +{
 +      if (mpoly->totloop == 3) {
 +              return area_tri_v3(mvarray[loopstart[0].v].co,
 +                                 mvarray[loopstart[1].v].co,
 +                                 mvarray[loopstart[2].v].co
 +                                 );
 +      }
 +      else if (mpoly->totloop == 4) {
 +              return area_quad_v3(mvarray[loopstart[0].v].co,
 +                                  mvarray[loopstart[1].v].co,
 +                                  mvarray[loopstart[2].v].co,
 +                                  mvarray[loopstart[3].v].co
 +                                  );
 +      }
 +      else {
 +              int i;
 +              float area, polynorm_local[3], (*vertexcos)[3];
 +              float *no= polynormal ? polynormal : polynorm_local;
 +              BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
 +
 +              /* pack vertex cos into an array for area_poly_v3 */
 +              for (i = 0; i < mpoly->totloop; i++) {
 +                      copy_v3_v3(vertexcos[i], mvarray[(loopstart++)->v].co);
 +              }
 +
 +              /* need normal for area_poly_v3 as well */
 +              if (polynormal == NULL) {
 +                      mesh_calc_poly_normal(mpoly, loopstart, mvarray, no);
 +              }
 +
 +              /* finally calculate the area */
 +              area = area_poly_v3(mpoly->totloop, vertexcos, no);
 +
 +              BLI_array_fixedstack_free(vertexcos);
 +
 +              return area;
 +      }
 +}
 +
  /* basic vertex data functions */
  int minmax_mesh(Mesh *me, float min[3], float max[3])
  {
@@@ -3798,28 -3718,17 +3798,19 @@@ static void direct_link_mesh(FileData *
        mesh->adt= newdataadr(fd, mesh->adt);
        direct_link_animdata(fd, mesh->adt);
  
-       /* Partial-mesh visibility (do this before using totvert, totface, or totedge!) */
-       mesh->pv= newdataadr(fd, mesh->pv);
-       if(mesh->pv) {
-               mesh->pv->vert_map= newdataadr(fd, mesh->pv->vert_map);
-               mesh->pv->edge_map= newdataadr(fd, mesh->pv->edge_map);
-               mesh->pv->old_faces= newdataadr(fd, mesh->pv->old_faces);
-               mesh->pv->old_edges= newdataadr(fd, mesh->pv->old_edges);
-       }
        /* normally direct_link_dverts should be called in direct_link_customdata,
           but for backwards compat in do_versions to work we do it here */
-       direct_link_dverts(fd, mesh->pv ? mesh->pv->totvert : mesh->totvert, mesh->dvert);
+       direct_link_dverts(fd, mesh->totvert, mesh->dvert);
  
-       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->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);
 +      
        mesh->bb= NULL;
        mesh->mselect = NULL;
 -      mesh->edit_mesh= NULL;
 +      mesh->edit_btmesh= NULL;
        
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
@@@ -1691,30 -1691,9 +1691,11 @@@ static void write_meshs(WriteData *wd, 
  
                        writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat);
  
-                       if(mesh->pv) {
-                               write_customdata(wd, &mesh->id, mesh->pv->totvert, &mesh->vdata, -1, 0);
-                               write_customdata(wd, &mesh->id, mesh->pv->totedge, &mesh->edata,
-                                       CD_MEDGE, mesh->totedge);
-                               /* BMESH_TODO: probably need to deal with polys here */
-                               write_customdata(wd, &mesh->id, mesh->pv->totface, &mesh->fdata,
-                                       CD_MFACE, mesh->totface);
-                       }
-                       else {
-                               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);
-                               write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0);
-                               write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0);
-                       }
-                       /* PMV data */
-                       if(mesh->pv) {
-                               writestruct(wd, DATA, "PartialVisibility", 1, mesh->pv);
-                               writedata(wd, DATA, sizeof(unsigned int)*mesh->pv->totvert, mesh->pv->vert_map);
-                               writedata(wd, DATA, sizeof(int)*mesh->pv->totedge, mesh->pv->edge_map);
-                               writestruct(wd, DATA, "MFace", mesh->pv->totface, mesh->pv->old_faces);
-                               writestruct(wd, DATA, "MEdge", mesh->pv->totedge, mesh->pv->old_edges);
-                       }
+                       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);
++                      write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0);
++                      write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0);
                }
                mesh= mesh->id.next;
        }
@@@ -468,9 -456,8 +468,8 @@@ static int modifier_apply_shape(ReportL
                        BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
                        return 0;
                }
-               mesh_pmv_off(me);
                
 -              dm = mesh_create_derived_for_modifier(scene, ob, md);
 +              dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
                if (!dm) {
                        BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
                        return 0;
@@@ -47,13 -47,7 +47,12 @@@ struct MCol
  struct MSticky;
  struct Mesh;
  struct OcInfo;
 +struct MPoly;
 +struct MTexPoly;
 +struct MLoop;
 +struct MLoopUV;
 +struct MLoopCol;
  struct Multires;
- struct PartialVisibility;
  struct EditMesh;
  struct AnimData;