svn merge ^/trunk/blender -r42680:42722
authorCampbell Barton <ideasman42@gmail.com>
Mon, 19 Dec 2011 10:40:48 +0000 (10:40 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 19 Dec 2011 10:40:48 +0000 (10:40 +0000)
19 files changed:
1  2 
CMakeLists.txt
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_vector.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/modifiers/intern/MOD_solidify.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/modifiers/intern/MOD_weightvgproximity.c
source/blender/windowmanager/intern/wm_init_exit.c

diff --cc CMakeLists.txt
Simple merge
index 99c421c0c24aadb939e97bb345e136d08b351811,1d344c6e81091e7a2daa88d63c26ce7a2bcfd24d..72e803011325b4d412f9f359b078942f51d5faa2
@@@ -153,10 -121,9 +153,10 @@@ int CustomData_number_of_layers(const s
  
  /* duplicate data of a layer with flag NOFREE, and remove that flag.
   * returns the layer data */
- void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type);
+ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
  void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
-                                                                                                 int type, const char *name);
+                                                                                                 const int type, const char *name, const int totelem);
 +int CustomData_is_referenced_layer(struct CustomData *data, int type);
  
  /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
   * zero for the layer type, so only layer types specified by the mask
index 768e18b98719cda746ba5ad6643122ea04bf22f2,3bc2ee61e7bd9ea4054cbf0938d08bf44474f3f3..98465dafecbc01e18acc29e159eaa658a0a80727
@@@ -956,139 -719,44 +960,154 @@@ void vDM_ColorBand_store(ColorBand *cob
  
  static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
  {
-       // Mesh *me = ob->data; // UNUSED
+       Mesh *me = ob->data;
 +      MFace *mf = dm->getTessFaceArray(dm);
 +      MLoop *mloop = dm->getLoopArray(dm), *ml;
 +      MPoly *mp = dm->getPolyArray(dm);
        ColorBand *coba= stored_cb;     /* warning, not a local var */
-       char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__);
-       int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot);
-       int unselected = defbase_tot - selected;
 +      unsigned char *wtcol;
 +      unsigned char(*wlcol)[4] = NULL;
 +      BLI_array_declare(wlcol);
 +      int i, j, totface=dm->getNumTessFaces(dm), totloop;
 +      int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
 +
 +      int defbase_tot = BLI_countlist(&ob->defbase);
++      const int defbase_act = ob->actdef-1;
++      char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
++      int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
  
 -      unsigned char *wtcol = MEM_mallocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
 +      wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
-       
-       /*first add colors to the tesselation faces*/
-       memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
-       for (i=0; i<totface; i++, mf++) {
-               /*origindex being NULL means we're operating on original mesh data*/
-               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
-               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
-               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag);
-               if (mf->v4)
-                       calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
+       if (me->dvert) {
+               MDeformVert *dvert= me->dvert;
 -              MFace *mf = me->mface;
 -
 -              const int defbase_tot = BLI_countlist(&ob->defbase);
 -              const int defbase_act = ob->actdef-1;
 -              char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
 -              const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
 -              /* const int unselected = defbase_tot - selected; */ /* UNUSED */
 -
 -              int i;
 -
 -              memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
 -              for (i=0; i<me->totface; i++, mf++) {
++              /*first add colors to the tesselation faces*/
++              memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
++              for (i=0; i<totface; i++, mf++) {
++                      /*origindex being NULL means we're operating on original mesh data*/
+                       unsigned int fidx= mf->v4 ? 3:2;
+                       do {
+                               calc_weightpaint_vert_color(&wtcol[(i*4 + fidx)*4],
+                                                           &dvert[*(&mf->v1 + fidx)], coba,
+                                                           defbase_tot, defbase_act,
+                                                           dg_flags, selected, draw_flag);
+                       } while (fidx--);
+               }
 -
 -              MEM_freeN(dg_flags);
+       }
+       else {
+               /* no weights, fill in zero */
+               int col_i;
+               weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
 -              fill_vn_i((int *)wtcol, me->totface*4, col_i);
++              fill_vn_i((int *)wtcol, totface*4, col_i);
 +      }
 +      
 +      CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
 +
 +      /*now add to loops, so the data can be passed through the modifier stack*/
 +      totloop = 0;
 +      for (i=0; i<dm->numPolyData; i++, mp++) {
++              MDeformVert *dvert= me->dvert;
++
 +              ml = mloop + mp->loopstart;
 +
 +              for (j=0; j<mp->totloop; j++, ml++, totloop++) {
 +                      BLI_array_growone(wlcol);
 +
-                       calc_weightpaint_vert_color(ob, defbase_tot, coba, origIndex ? origIndex[ml->v] : ml->v,
-                                                                               (unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag);
++                      calc_weightpaint_vert_color((unsigned char *)&wlcol[totloop],
++                                                  &dvert[origIndex ? origIndex[ml->v] : ml->v], coba,
++                                                  defbase_tot, defbase_act,
++                                                                              dg_flags, selected, draw_flag);
 +              }
 +      }
 +
-       MEM_freeN(defbase_sel);
++      MEM_freeN(dg_flags);
 +
 +      CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
 +}
 +
 +
 +static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
 +{
 +      KeyBlock *kb;
 +      int i, j, tot;
 +      
 +      if (!me->key)
 +              return; 
 +      
 +      tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY);
 +      for (i=0; i<tot; i++) {
 +              CustomDataLayer *layer = &dm->vertData.layers[CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i)];
 +              float (*cos)[3], (*kbcos)[3];
 +              
 +              for (kb=me->key->block.first; kb; kb=kb->next) {
 +                      if (kb->uid == layer->uid)
 +                              break;
 +              }
 +              
 +              if (!kb) {
 +                      kb = add_keyblock(me->key, layer->name);
 +                      kb->uid = layer->uid;
 +              }
 +              
 +              if (kb->data)
 +                      MEM_freeN(kb->data);
 +              
 +              cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
 +              kb->totelem = dm->numVertData;
 +
 +              kb->data = kbcos = MEM_mallocN(sizeof(float)*3*kb->totelem, "kbcos DerivedMesh.c");
 +              if (kb->uid == actshape_uid) {
 +                      MVert *mvert = dm->getVertArray(dm);
 +                      
 +                      for (j=0; j<dm->numVertData; j++, kbcos++, mvert++) {
 +                              copy_v3_v3(*kbcos, mvert->co);
 +                      }
 +              } else {
 +                      for (j=0; j<kb->totelem; j++, cos++, kbcos++) {
 +                              copy_v3_v3(*kbcos, *cos);
 +                      }
 +              }
 +      }
 +      
 +      for (kb=me->key->block.first; kb; kb=kb->next) {
 +              if (kb->totelem != dm->numVertData) {
 +                      if (kb->data)
 +                              MEM_freeN(kb->data);
 +                      
 +                      kb->totelem = dm->numVertData;
 +                      kb->data = MEM_callocN(sizeof(float)*3*kb->totelem, "kb->data derivedmesh.c");
 +                      fprintf(stderr, "%s: lost a shapekey layer! (bmesh internal error)\n", __func__);
 +              }
        }
 +}
  
 -      CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
 +static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
 +{
 +      KeyBlock *kb;
 +      Key *key = me->key;
 +      int a, b;
 +      
 +      if (!me->key)
 +              return;
 +      
 +      if (dm->numVertData != me->totvert) {
 +              printf("error in add_shapekey_layers: dm isn't the same size as me\n");
 +              return;
 +      }
 +              
 +      for (a=0, kb=key->block.first; kb; kb=kb->next, a++) {
 +              float (*cos)[3] = CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_CALLOC, NULL, dm->numVertData, kb->name);
 +              int ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, a);
 +              
 +              dm->vertData.layers[ci].uid = kb->uid;
 +              if (kb->totelem != dm->numVertData) {
 +                      printf("error in add_shapekey_layers: totelem and totvert don't match");
 +                      continue;
 +              }
 +              
 +              for (b=0; b<kb->totelem; b++, cos++) {
 +                      copy_v3_v3((float *)cos, ((float*)kb->data)+b*3);
 +              }
 +      }
  }
  
  /* new value for useDeform -1  (hack for the gameengine):
index 69758ad66a77f6d2e617fe51939561a8d70f568c,6f088b8abf75aaa93f3c5df08e85043792640319..f765be4bf17a181b53118335f653e3fc1ed496a5
@@@ -688,15 -652,15 +688,15 @@@ static void cdDM_drawFacesTex_common(De
  {
        CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
        MVert *mv = cddm->mvert;
 -      MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
 -      MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
 -      float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
 -      MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
 -      int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
 +      MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
 +      MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
 +      float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
 +      MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
 +      int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
-       int startFace = 0, lastFlag = 0xdeadbeef;
+       int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
 -      MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
 +      MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
        if(!mcol)
 -              mcol = dm->getFaceDataArray(dm, CD_MCOL);
 +              mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
  
        cdDM_update_normals_from_pbvh(dm);
  
@@@ -2228,242 -1894,23 +2228,242 @@@ void CDDM_apply_vert_normals(DerivedMes
  void CDDM_calc_normals(DerivedMesh *dm)
  {
        CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
 -      float (*face_nors)[3];
 +      float (*face_nors)[3] = NULL;
  
 +      /* use this to skip calculating normals on original vert's, this may need to be changed */
 +      const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
 +      
        if(dm->numVertData == 0) return;
  
 +      /* now we skip calculating vertex normals for referenced layer,
 +       * no need to duplicate verts.
 +       * WATCH THIS, bmesh only change!,
 +       * need to take care of the side effects here - campbell */
 +#if 0
        /* we don't want to overwrite any referenced layers */
-       cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+       cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
 +#endif
  
 -      /* make a face normal layer if not present */
 -      face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
 -      if(!face_nors)
 -              face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
 -                                                                               NULL, dm->numFaceData);
 +      if (dm->numTessFaceData == 0) {
 +              /* No tesselation on this mesh yet, need to calculate one */
 +              CDDM_recalc_tesselation(dm);
 +      }
 +      else {
 +              /* A tesselation already exists, it should always have a CD_POLYINDEX */
 +              BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
 +              CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
 +      }
  
 +      face_nors = MEM_mallocN(sizeof(float)*3*dm->numTessFaceData, "face_nors");
 +      
        /* calculate face normals */
 -      mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_faces(dm), dm->numFaceData, face_nors);
 +      mesh_calc_normals_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
 +                           dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
 +                           CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
 +                           only_face_normals);
 +      
 +      CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
 +              face_nors, dm->numTessFaceData);
  }
  
 +#if 1
 +/*merge verts
 + 
 +  vtargetmap is a table that maps vertices to target vertices.  a value of -1
 +  indicates a vertex is a target, and is to be kept.
 +  
 +  this frees dm, and returns a new one.
 +  
 +  this is a really horribly written function.  ger. - joeedh
 +
 + */
 +DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap)
 +{
 +      CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
 +      CDDerivedMesh *cddm2 = NULL;
 +      MVert *mv, *mvert = NULL;
 +      BLI_array_declare(mvert);
 +      MEdge *me, *medge = NULL;
 +      BLI_array_declare(medge);
 +      MPoly *mp, *mpoly = NULL;
 +      BLI_array_declare(mpoly);
 +      MLoop *ml, *mloop = NULL;
 +      BLI_array_declare(mloop);
 +      EdgeHash *ehash = BLI_edgehash_new();
 +      int *newv = NULL, *newe = NULL, *newl = NULL;
 +      int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
 +      BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
 +      int i, j, c, totloop, totpoly;
 +      
 +      totloop = dm->numLoopData;
 +      totpoly = dm->numPolyData;
 +      
 +      newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
 +      newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
 +      newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
 +      
 +      /*fill newl with destination vertex indices*/
 +      mv = cddm->mvert;
 +      c = 0;
 +      for (i=0; i<dm->numVertData; i++, mv++) {
 +              if (vtargetmap[i] == -1) {
 +                      BLI_array_append(oldv, i);
 +                      newv[i] = c++;
 +                      BLI_array_append(mvert, *mv);
 +              }
 +      }
 +      
 +      /*now link target vertices to destination indices*/
 +      for (i=0; i<dm->numVertData; i++) {
 +              if (vtargetmap[i] != -1) {
 +                      newv[i] = newv[vtargetmap[i]];
 +              }
 +      }
 +      
 +      /*find-replace merged vertices with target vertices*/   
 +      ml = cddm->mloop;
 +      c = 0;
 +      for (i=0; i<totloop; i++, ml++) {
 +              if (ml->v == -1)
 +                      continue;
 +              
 +              if (vtargetmap[ml->v] != -1)
 +                      ml->v = vtargetmap[ml->v];
 +      }
 +      
 +      /*now go through and fix edges and faces*/
 +      me = cddm->medge;
 +      c = 0;
 +      for (i=0; i<dm->numEdgeData; i++, me++) {
 +              int v1, v2;
 +              
 +              if (me->v1 == me->v2) {
 +                      newe[i] = -1;
 +                      continue;
 +              }
 +              
 +              if (vtargetmap[me->v1] != -1)
 +                      v1 = vtargetmap[me->v1];
 +              else
 +                      v1 = me->v1;
 +              
 +              if (vtargetmap[me->v2] != -1)
 +                      v2 = vtargetmap[me->v2];
 +              else
 +                      v2 = me->v2;
 +              
 +              if (BLI_edgehash_haskey(ehash, v1, v2)) {
 +                      newe[i] = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ehash, v1, v2));
 +              } else {
 +                      BLI_array_append(olde, i);
 +                      newe[i] = c;
 +                      BLI_array_append(medge, *me);
 +                      BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
 +                      c++;
 +              }
 +      }
 +      
 +      mp = cddm->mpoly;
 +      for (i=0; i<totpoly; i++, mp++) {
 +              MPoly *mp2;
 +              
 +              ml = cddm->mloop + mp->loopstart;
 +              
 +              c = 0;
 +              for (j=0; j<mp->totloop; j++, ml++) {
 +                      if (ml->v == -1)
 +                              continue;
 +                      
 +                      me = cddm->medge + ml->e;
 +                      if (me->v1 != me->v2) {
 +                              BLI_array_append(oldl, j+mp->loopstart);
 +                              BLI_array_append(mloop, *ml);
 +                              newl[j+mp->loopstart] = BLI_array_count(mloop)-1;
 +                              c++;
 +                      }
 +              }
 +              
 +              if (!c)
 +                      continue;
 +              
 +              mp2 = BLI_array_append_r(mpoly, *mp);
 +              mp2->totloop = c;
 +              mp2->loopstart = BLI_array_count(mloop) - c;
 +              
 +              BLI_array_append(oldp, i);
 +      }
 +      
 +      /*create new cddm*/     
 +      cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
 +      
 +      /*update edge indices and copy customdata*/
 +      me = medge;
 +      for (i=0; i<cddm2->dm.numEdgeData; i++, me++) {
 +              if (newv[me->v1] != -1)
 +                      me->v1 = newv[me->v1];
 +              if (newv[me->v2] != -1)
 +                      me->v2 = newv[me->v2];
 +              
 +              CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
 +      }
 +      
 +      /*update loop indices and copy customdata*/
 +      ml = mloop;
 +      for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
 +              if (newe[ml->e] != -1)
 +                      ml->e = newe[ml->e];
 +              if (newv[ml->v] != -1)
 +                      ml->v = newv[ml->v];
 +                      
 +              CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
 +      }
 +      
 +      /*copy vertex customdata*/      
 +      mv = mvert;
 +      for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
 +              CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
 +      }
 +      
 +      /*copy poly customdata*/
 +      mp = mpoly;
 +      for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
 +              CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
 +      }
 +      
 +      /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
 +      memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
 +      memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
 +      memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
 +      memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
 +      BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
 +
 +      CDDM_recalc_tesselation((DerivedMesh*)cddm2);
 +      
 +      if (newv) 
 +              MEM_freeN(newv); 
 +      if (newe)
 +              MEM_freeN(newe); 
 +      if (newl)
 +              MEM_freeN(newl);
 +      if (oldv) 
 +              MEM_freeN(oldv); 
 +      if (olde) 
 +              MEM_freeN(olde); 
 +      if (oldl) 
 +              MEM_freeN(oldl); 
 +      if (oldp) 
 +              MEM_freeN(oldp);
 +      if (ehash)
 +              BLI_edgehash_free(ehash, NULL);
 +
 +      /*free old derivedmesh*/
 +      dm->needsFree = 1;
 +      dm->release(dm);
 +      
 +      return (DerivedMesh*)cddm2;
 +}
 +#endif
 +
  void CDDM_calc_edges(DerivedMesh *dm)
  {
        CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
index cedb13907995b5cd76aa4602c8835639f246f657,374ef3512e81e8253222cb0d44bc1122943cd1fe..421764f719140efe9790a81912a4c71936a83a2d
@@@ -227,13 -222,13 +227,14 @@@ static int ss_sync_from_uv(CCGSubSurf *
        UvMapVert *v;
        UvVertMap *vmap;
        float limit[2];
 -      CCGVertHDL fverts[4];
 +      CCGVertHDL *fverts= NULL;
 +      BLI_array_declare(fverts);
        EdgeHash *ehash;
        float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
+       float uv[3]= {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
  
        limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
 -      vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
 +      vmap= make_uv_vert_map(mpoly, mloop, mloopuv, totface, totvert, 0, limit);
        if (!vmap)
                return 0;
        
                        if (v->separate) {
                                CCGVert *ssv;
                                CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
-                               float uv[3];
  
-                               uv[0]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[0];
-                               uv[1]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[1];
-                               uv[2]= 0.0f;
 -                              copy_v2_v2(uv, (tface+v->f)->uv[v->tfindex]);
++                              copy_v2_v2(uv, mloopuv[mpoly[v->f].loopstart + v->tfindex].uv);
  
                                ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
                        }
index a151275e109a1068a535957689509dbb4d145f24,1f71cd8a4c60f24ddd1fb56de7a377adf48f3534..18e61f7300ef25b2f216042b2764325c1266aa89
@@@ -709,33 -580,28 +709,32 @@@ static void find_nearest_uv_face(Scene 
  
        mindist= 1e10f;
        memset(hit, 0, sizeof(*hit));
 -      
 -      for(efa= em->faces.first; efa; efa= efa->next) {
 -              tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
  
 -              if(uvedit_face_visible(scene, ima, efa, tf)) {
 -                      nverts= efa->v4? 4: 3;
 -                      cent[0]= cent[1]= 0.0f;
 +      /*this will fill in hit.vert1 and hit.vert2*/
 +      find_nearest_uv_edge(scene, ima, em, co, hit);
 +      hit->l = hit->nextl = NULL;
 +      hit->luv = hit->nextluv = NULL;
  
 -                      for(i=0; i<nverts; i++) {
 -                              add_v2_v2(cent, tf->uv[i]);
 -                      }
 +      BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +              tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +              if(!uvedit_face_visible(scene, ima, efa, tf))
 +                      continue;
 +              
 +              cent[0]= cent[1]= 0.0f;
 +              BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 +                      luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
  
-                       cent[0] += luv->uv[0];
-                       cent[1] += luv->uv[1];
 -                      cent[0] /= nverts;
 -                      cent[1] /= nverts;
 -                      dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]);
++                      add_v2_v2(cent, luv->uv);
 +              }
  
 -                      if(dist < mindist) {
 -                              hit->tf= tf;
 -                              hit->efa= efa;
 -                              mindist= dist;
 -                      }
 +              cent[0] /= efa->len;
 +              cent[1] /= efa->len;
 +              dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]);
 +
 +              if(dist < mindist) {
 +                      hit->tf= tf;
 +                      hit->efa= efa;
 +                      mindist= dist;
                }
        }
  }
index bd82001dd1bbddd14cd6ccc0d7feb50b86affca0,3146d1c9d5dd83e5a9ba53abd80932dc8cd464bb..8f2d248b956996458a4e52f920958a5ebc1b1c08
@@@ -259,11 -259,12 +259,12 @@@ static DerivedMesh *uvprojectModifier_d
                mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
        }
  
 -      numFaces = dm->getNumFaces(dm);
++      numFaces = dm->getNumTessFaces(dm);
        /* make sure we are not modifying the original UV map */
        tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-                       CD_MTFACE, uvname);
+                       CD_MTFACE, uvname, numFaces);
  
-       
        numVerts = dm->getNumVerts(dm);
  
        coords = MEM_callocN(sizeof(*coords) * numVerts,