svn merge ^/trunk/blender -r43685:43693
authorCampbell Barton <ideasman42@gmail.com>
Wed, 25 Jan 2012 18:13:58 +0000 (18:13 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 25 Jan 2012 18:13:58 +0000 (18:13 +0000)
1  2 
source/blender/blenkernel/intern/mesh.c
source/blender/editors/armature/reeb.c
source/blender/makesrna/intern/rna_scene.c

@@@ -2207,276 -1510,6 +2207,276 @@@ void mesh_loops_to_mface_corners(Custom
        }
  }
  
-               test_index_face(mf, fdata, mface_index, 4);
 +/*
 +  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,
 +                           /* when teseelating to recalcilate normals after
 +                            * we can skip copying here */
 +                           const int do_face_nor_cpy)
 +{
 +
 +      /* use this to avoid locking pthread for _every_ polygon
 +       * and calling the fill function */
 +
 +#define USE_TESSFACE_SPEEDUP
 +// #define USE_TESSFACE_QUADS // NEEDS FURTHER TESTING
 +
 +#define TESSFACE_SCANFILL (1<<0)
 +#define TESSFACE_IS_QUAD  (1<<1)
 +
 +      MPoly *mp, *mpoly;
 +      MLoop *ml, *mloop;
 +      MFace *mface = NULL, *mf;
 +      BLI_array_declare(mface);
 +      EditVert *v, *lastv, *firstv;
 +      EditFace *f;
 +      int *mface_orig_index = NULL;
 +      BLI_array_declare(mface_orig_index);
 +      int *mface_to_poly_map = NULL;
 +      BLI_array_declare(mface_to_poly_map);
 +      int lindex[4]; /* only ever use 3 in this case */
 +      int *poly_orig_index;
 +      int poly_index, j, mface_index;
 +
 +      const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
 +      const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
 +      const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
 +
 +      mpoly = CustomData_get_layer(pdata, CD_MPOLY);
 +      mloop = CustomData_get_layer(ldata, CD_MLOOP);
 +
 +      /* allocate the length of totfaces, avoid many small reallocs,
 +       * if all faces are tri's it will be correct, quads == 2x allocs */
 +      BLI_array_reserve(mface_to_poly_map, totface);
 +      BLI_array_reserve(mface, totface);
 +
 +      mface_index = 0;
 +      mp = mpoly;
 +      poly_orig_index = CustomData_get_layer(pdata, CD_ORIGINDEX);
 +      for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) {
 +              if (mp->totloop < 3) {
 +                      /* do nothing */
 +              }
 +
 +#ifdef USE_TESSFACE_SPEEDUP
 +
 +#define ML_TO_MF(i1, i2, i3)                                                  \
 +              BLI_array_growone(mface_to_poly_map);                                 \
 +              BLI_array_growone(mface);                                             \
 +              mface_to_poly_map[mface_index] = poly_index;                          \
 +              mf= &mface[mface_index];                                              \
 +              /* 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 (poly_orig_index) {                                                \
 +                      BLI_array_append(mface_orig_index,                                \
 +                                   poly_orig_index[poly_index]);                    \
 +              }                                                                     \
 +
 +/* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */
 +#define ML_TO_MF_QUAD()                                                       \
 +              BLI_array_growone(mface_to_poly_map);                                 \
 +              BLI_array_growone(mface);                                             \
 +              mface_to_poly_map[mface_index] = poly_index;                          \
 +              mf= &mface[mface_index];                                              \
 +              /* set loop indices, transformed to vert indices later */             \
 +              mf->v1 = mp->loopstart + 0; /* EXCEPTION */                           \
 +              mf->v2 = mp->loopstart + 1; /* EXCEPTION */                           \
 +              mf->v3 = mp->loopstart + 2; /* EXCEPTION */                           \
 +              mf->v4 = mp->loopstart + 3; /* EXCEPTION */                           \
 +              mf->mat_nr = mp->mat_nr;                                              \
 +              mf->flag = mp->flag;                                                  \
 +              if (poly_orig_index) {                                                \
 +                      BLI_array_append(mface_orig_index,                                \
 +                                   poly_orig_index[poly_index]);                    \
 +              }                                                                     \
 +              mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */                       \
 +
 +
 +              else if (mp->totloop == 3) {
 +                      ml = mloop + mp->loopstart;
 +                      ML_TO_MF(0, 1, 2)
 +                      mface_index++;
 +              }
 +              else if (mp->totloop == 4) {
 +#ifdef USE_TESSFACE_QUADS
 +                      ml = mloop + mp->loopstart;
 +                      ML_TO_MF_QUAD()
 +                      mface_index++;
 +#else
 +                      ml = mloop + mp->loopstart;
 +                      ML_TO_MF(0, 1, 2)
 +                      mface_index++;
 +                      ML_TO_MF(0, 2, 3)
 +                      mface_index++;
 +#endif
 +              }
 +#endif /* USE_TESSFACE_SPEEDUP */
 +              else {
 +                      int totfilltri;
 +
 +                      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);
 +                      
 +                      totfilltri = BLI_edgefill(2);
 +                      if (totfilltri) {
 +                              BLI_array_growitems(mface_to_poly_map, totfilltri);
 +                              BLI_array_growitems(mface, totfilltri);
 +                              if (poly_orig_index) {
 +                                      BLI_array_growitems(mface_orig_index, totfilltri);
 +                              }
 +
 +                              for (f = fillfacebase.first; f; f = f->next, mf++) {
 +                                      mface_to_poly_map[mface_index] = poly_index;
 +                                      mf= &mface[mface_index];
 +
 +                                      /* 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;
 +
 +#ifdef USE_TESSFACE_SPEEDUP
 +                                      mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indicies */
 +#endif
 +
 +                                      if (poly_orig_index) {
 +                                              mface_orig_index[mface_index] = poly_orig_index[poly_index];
 +                                      }
 +
 +                                      mface_index++;
 +                              }
 +                      }
 +      
 +                      BLI_end_edgefill();
 +              }
 +      }
 +
 +      CustomData_free(fdata, totface);
 +      memset(fdata, 0, sizeof(CustomData));
 +      totface = mface_index;
 +      
 +      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, mface_to_poly_map, totface);
 +      if (mface_orig_index) {
 +              /* 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, mface_orig_index, totface);
 +      }
 +
 +      CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
 +
 +      if (do_face_nor_cpy) {
 +              /* 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)[3] = CustomData_get_layer(pdata, CD_NORMAL);
 +                      float (*fnors)[3] = CustomData_add_layer(fdata, CD_NORMAL, CD_CALLOC, NULL, totface);
 +                      for (mface_index = 0; mface_index < totface; mface_index++) {
 +                              copy_v3_v3(fnors[mface_index], pnors[mface_to_poly_map[mface_index]]);
 +                      }
 +              }
 +      }
 +
 +      mf = mface;
 +      for (mface_index=0; mface_index < totface; mface_index++, mf++) {
 +
 +#ifdef USE_TESSFACE_QUADS
 +              const int mf_len = mf->edcode & TESSFACE_IS_QUAD ? 4 : 3;
 +#endif
 +
 +#ifdef USE_TESSFACE_SPEEDUP
 +              /* skip sorting when not using ngons */
 +              if (UNLIKELY(mf->edcode & TESSFACE_SCANFILL))
 +#endif
 +              {
 +                      /* 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);
 +              }
 +
 +              /* end abusing the edcode */
 +#if defined(USE_TESSFACE_QUADS) || defined(USE_TESSFACE_SPEEDUP)
 +              mf->edcode = 0;
 +#endif
 +
 +
 +              lindex[0] = mf->v1;
 +              lindex[1] = mf->v2;
 +              lindex[2] = mf->v3;
 +#ifdef USE_TESSFACE_QUADS
 +              if (mf_len == 4) lindex[2] = mf->v3;
 +#endif
 +
 +              /*transform loop indices to vert indices*/
 +              mf->v1 = mloop[mf->v1].v;
 +              mf->v2 = mloop[mf->v2].v;
 +              mf->v3 = mloop[mf->v3].v;
 +#ifdef USE_TESSFACE_QUADS
 +              if (mf_len == 4) mf->v4 = mloop[mf->v4].v;
 +#endif
 +
 +              mesh_loops_to_mface_corners(fdata, ldata, pdata,
 +                                          lindex, mface_index, mface_to_poly_map[mface_index],
 +#ifdef USE_TESSFACE_QUADS
 +                                          mf_len,
 +#else
 +                                          3,
 +#endif
 +                                          numTex, numCol, hasWCol);
 +
 +
 +#ifdef USE_TESSFACE_QUADS
++              test_index_face(mf, fdata, mface_index, mf_len);
 +#endif
 +
 +      }
 +
 +      return totface;
 +
 +#undef USE_TESSFACE_SPEEDUP
 +
 +}
 +
 +
 +#ifdef USE_BMESH_SAVE_AS_COMPAT
  
  /*
   * this function recreates a tesselation.