struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob);
/*
- this function recreates a tesselation.
- returns number of tesselation faces.
-
- use_poly_origindex sets whether or not the tesselation faces' origindex
- layer should point to original poly indices or real poly indices.
-
- use_face_origindex sets the tesselation faces' origindex layer
- to point to the tesselation faces themselves, not the polys.
-
- if both of the above are 0, it'll use the indices of the mpolys of the MPoly
- data in pdata, and ignore the origindex layer altogether.
+ * this function recreates a tesselation.
+ * returns number of tesselation faces.
+ *
+ * use_poly_origindex sets whether or not the tesselation faces' origindex
+ * layer should point to original poly indices or real poly indices.
+ *
+ * use_face_origindex sets the tesselation faces' origindex layer
+ * to point to the tesselation faces themselves, not the polys.
+ *
+ * if both of the above are 0, it'll use the indices of the mpolys of the MPoly
+ * data in pdata, and ignore the origindex layer altogether.
*/
int mesh_recalcTesselation(struct CustomData *fdata, struct CustomData *ldata,
struct CustomData *pdata, struct MVert *mvert, int totface,
int totloop, int totpoly);
+/* for forwards compat only quad->tri polys to mface, skip ngons.
+ */
+int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int totface, int totloop, int totpoly);
+
/*calculates a face normal.*/
void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart,
struct MVert *mvarray, float no[3]);
void BKE_mesh_ensure_navmesh(struct Mesh *me);
/*convert a triangle of loop facedata to mface facedata*/
-void mesh_loops_to_tri_corners(struct CustomData *fdata, struct CustomData *ldata,
- struct CustomData *pdata, int lindex[3], int findex,
- int polyindex);
+void mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int lindex[4], int findex,
+ const int polyindex, const int mf_len);
#ifdef __cplusplus
}
}
}
-void mesh_loops_to_tri_corners(CustomData *fdata, CustomData *ldata,
- CustomData *pdata, int lindex[3], int findex,
- int polyindex)
+void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
+ CustomData *pdata, int lindex[4], int findex,
+ const int polyindex,
+ const int mf_len /* 3 or 4 */
+ )
{
MTFace *texface;
MTexPoly *texpoly;
texface->tile = texpoly->tile;
texface->unwrap = texpoly->unwrap;
- for (j=0; j<3; j++) {
+ for (j=0; j < mf_len; 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++) {
+ for (j=0; j < mf_len; j++) {
mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i);
mcol[j].r = mloopcol->r;
mcol[j].g = mloopcol->g;
if (hasWCol) {
mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
- for (j=0; j<3; j++) {
+ for (j=0; j < mf_len; j++) {
mloopcol = CustomData_get(ldata, lindex[j], CD_WEIGHT_MLOOPCOL);
mcol[j].r = mloopcol->r;
mcol[j].g = mloopcol->g;
BLI_array_declare(origIndex);
int *polyIndex = NULL;
BLI_array_declare(polyIndex);
- int i, j, k, lindex[4], *polyorigIndex;
+ int lindex[4]; /* only ever use 3 in this case */
+ int *polyorigIndex;
+ int i, j, k;
int numTex, numCol;
mpoly = CustomData_get_layer(pdata, CD_MPOLY);
mf->v2 = mloop[mf->v2].v;
mf->v3 = mloop[mf->v3].v;
- mesh_loops_to_tri_corners(fdata, ldata, pdata,
- lindex, i, polyIndex[i]);
+ mesh_loops_to_mface_corners(fdata, ldata, pdata,
+ lindex, i, polyIndex[i], 3);
}
return totface;
}
+
+#ifdef USE_MESH_FORWARDS_COMAT
+
+/*
+ * this function recreates a tesselation.
+ * returns number of tesselation faces.
+ */
+int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int totface, int UNUSED(totloop), int totpoly)
+{
+ MLoop *mloop;
+
+ int lindex[4];
+ int i;
+ int k;
+
+ MPoly *mp, *mpoly;
+ MFace *mface = NULL, *mf;
+ BLI_array_declare(mface);
+
+ mpoly = CustomData_get_layer(pdata, CD_MPOLY);
+ mloop = CustomData_get_layer(ldata, CD_MLOOP);
+
+ mp = mpoly;
+ k = 0;
+ for (i = 0; i<totpoly; i++, mp++) {
+ if (ELEM(mp->totloop, 3, 4)) {
+ BLI_array_growone(mface);
+ mf = &mface[k];
+
+ mf->mat_nr = mp->mat_nr;
+ mf->flag = mp->flag;
+
+ mf->v1 = mp->loopstart + 0;
+ mf->v2 = mp->loopstart + 1;
+ mf->v3 = mp->loopstart + 2;
+ mf->v4 = (mp->totloop == 4) ? (mp->loopstart + 3) : 0;
+
+ /* abuse edcode for temp storage and clear next loop */
+ mf->edcode = (char)mp->totloop; /* only ever 3 or 4 */
+
+ k++;
+ }
+ }
+
+ CustomData_free(fdata, totface);
+ memset(fdata, 0, sizeof(CustomData));
+
+ totface= k;
+
+ CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
+
+ CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+
+ mp = mpoly;
+ k = 0;
+ for (i = 0; i<totpoly; i++, mp++) {
+ if (ELEM(mp->totloop, 3, 4)) {
+ mf = &mface[k];
+
+ if (mf->edcode == 3) {
+ /*sort loop indices to ensure winding is correct*/
+ /* NO SORT - looks like we can skip this */
+
+ lindex[0] = mf->v1;
+ lindex[1] = mf->v2;
+ lindex[2] = mf->v3;
+ lindex[3] = 0; /* unused */
+
+ /*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_mface_corners(fdata, ldata, pdata,
+ lindex, k, i, 3);
+ test_index_face(mf, fdata, totface, 3);
+ }
+ else {
+ /*sort loop indices to ensure winding is correct*/
+ /* NO SORT - looks like we can skip this */
+
+ lindex[0] = mf->v1;
+ lindex[1] = mf->v2;
+ lindex[2] = mf->v3;
+ lindex[3] = mf->v4;
+
+ /*transform loop indices to vert indices*/
+ mf->v1 = mloop[mf->v1].v;
+ mf->v2 = mloop[mf->v2].v;
+ mf->v3 = mloop[mf->v3].v;
+ mf->v4 = mloop[mf->v4].v;
+
+ mesh_loops_to_mface_corners(fdata, ldata, pdata,
+ lindex, k, i, 4);
+ test_index_face(mf, fdata, totface, 4);
+ }
+
+ mf->edcode= 0;
+
+ k++;
+ }
+ }
+
+ return k;
+}
+#endif /* USE_MESH_FORWARDS_COMAT */
+
/*
* COMPUTE POLY NORMAL
*
#include "BKE_modifier.h"
#include "BKE_fcurve.h"
#include "BKE_pointcache.h"
+#include "BKE_mesh.h"
#include "BLO_writefile.h"
#include "BLO_readfile.h"
static void write_meshs(WriteData *wd, ListBase *idbase)
{
Mesh *mesh;
+ int save_for_old_blender= 0;
+
+#ifdef USE_MESH_FORWARDS_COMAT
+ /* TODO, add UI option to allow bmesh to save for pre-bmesh blender versions */
+#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) {
+ 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);
+ /* 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);
+ 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);
- write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0);
- write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0);
+ 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);
+ }
+ else {
+
+#ifdef USE_MESH_FORWARDS_COMAT
+
+ 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_MESH_FORWARDS_COMAT */
+ }
}
mesh= mesh->id.next;
}
#define MESH_MAX_VERTS 2000000000L
+/* this is so we can save bmesh files that load in trunk, ignoring NGons
+ * will eventually be removed */
+#define USE_MESH_FORWARDS_COMAT
+
#endif
MPoly *mp = mpoly + *of;
MLoop *ml;
float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
- int j, lindex[3] = {0, 1, 2};
+ int j, lindex[4] = {0, 1, 2}; /* only ever use 3 in this case */
BLI_array_empty(w);
BLI_array_empty(cos);
interp_weights_poly_v3(w, cos, mp->totloop, co);
CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2);
- mesh_loops_to_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]);
+ mesh_loops_to_mface_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i], 3);
}
CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData);