Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/cdderivedmesh.c')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c897
1 files changed, 813 insertions, 84 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 1e38f666da7..62a23da2230 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1,4 +1,4 @@
-/*
+ /*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -36,11 +36,23 @@
#include "GL/glew.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_paint.h"
+#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
+
+#include "BLI_editVert.h"
+#include "BLI_scanfill.h"
+#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_pbvh.h"
+#include "BLI_array.h"
+#include "BLI_smallhash.h"
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
@@ -72,6 +84,8 @@ typedef struct {
MVert *mvert;
MEdge *medge;
MFace *mface;
+ MLoop *mloop;
+ MPoly *mpoly;
/* Cached */
struct PBVH *pbvh;
@@ -93,11 +107,16 @@ static int cdDM_getNumEdges(DerivedMesh *dm)
return dm->numEdgeData;
}
-static int cdDM_getNumFaces(DerivedMesh *dm)
+static int cdDM_getNumTessFaces(DerivedMesh *dm)
{
return dm->numFaceData;
}
+static int cdDM_getNumFaces(DerivedMesh *dm)
+{
+ return dm->numPolyData;
+}
+
static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
@@ -134,6 +153,18 @@ static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
}
+static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+ memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
+}
+
+static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+ memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
+}
+
static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
@@ -203,7 +234,7 @@ static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
if(deformed)
return 0;
- return (cddm->mvert == me->mvert) || ob->sculpt->kb;
+ return cddm->mvert == me->mvert || ob->sculpt->kb;
}
static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
@@ -292,7 +323,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MFace *mf = cddm->mface;
- MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+ MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
int i;
if(mf) {
@@ -463,7 +494,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
- float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
+ float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
#define PASSVERT(index) { \
@@ -651,15 +682,15 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
{
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;
- 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);
@@ -751,8 +782,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
if( col != 0 ) {*/
- unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
- for( i=0; i < dm->getNumFaces(dm); i++ ) {
+ unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
+ for( i=0; i < dm->getNumTessFaces(dm); i++ ) {
for( j=0; j < 4; j++ ) {
/* bgr -> rgb is intentional (and stupid), but how its stored internally */
colors[i*12+j*3] = col[i*4+j].b;
@@ -846,14 +877,14 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
MVert *mv = cddm->mvert;
MFace *mf = cddm->mface;
MCol *mc;
- float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
- int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
+ int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
- mc = DM_get_face_data_layer(dm, CD_ID_MCOL);
+ mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
if(!mc)
- mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
+ mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
if(!mc)
- mc = DM_get_face_data_layer(dm, CD_MCOL);
+ mc = DM_get_tessface_data_layer(dm, CD_MCOL);
cdDM_update_normals_from_pbvh(dm);
@@ -862,15 +893,17 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
for(i = 0; i < dm->numFaceData; i++, mf++) {
- int drawSmooth = (mf->flag & ME_SMOOTH);
- int draw= 1;
+ int drawSmooth = (mf->flag & ME_SMOOTH) != 0;
+ int draw = (mf->flag & ME_HIDE) == 0;
orig= (index==NULL) ? i : *index++;
-
- if(orig == ORIGINDEX_NONE)
- draw= setMaterial(mf->mat_nr + 1, NULL);
- else if (setDrawOptions != NULL)
- draw= setDrawOptions(userData, orig, &drawSmooth);
+
+ if (orig == ORIGINDEX_NONE) {
+ draw = draw && setMaterial(mf->mat_nr + 1, NULL);
+ }
+ else if (setDrawOptions != NULL) {
+ draw = draw && setDrawOptions(userData, orig, &drawSmooth);
+ }
if(draw) {
unsigned char *cp = NULL;
@@ -925,7 +958,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
glEnd();
- }
+ } /*else {
+ printf("eek in cddm draw mapped faces!\n");
+ }*/
if (nors) nors += 3;
}
@@ -956,7 +991,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
int actualFace = next_actualFace;
MFace *mface= mf + actualFace;
int drawSmooth= (mface->flag & ME_SMOOTH);
- int draw = 1;
+ int draw = (mf->flag & ME_HIDE) == 0;
int flush = 0;
if(i != tottri-1)
@@ -964,10 +999,12 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
orig= (index==NULL) ? actualFace : index[actualFace];
- if(orig == ORIGINDEX_NONE)
- draw= setMaterial(mface->mat_nr + 1, NULL);
- else if (setDrawOptions != NULL)
- draw= setDrawOptions(userData, orig, &drawSmooth);
+ if (orig == ORIGINDEX_NONE) {
+ draw = draw && setMaterial(mface->mat_nr + 1, NULL);
+ }
+ else if (setDrawOptions != NULL) {
+ draw = draw && setDrawOptions(userData, orig, &drawSmooth);
+ }
/* Goal is to draw as long of a contiguous triangle
array as possible, so draw when we hit either an
@@ -1065,10 +1102,10 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
DMVertexAttribs attribs;
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
- /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
- float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
+ /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
+ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
int a, b, dodraw, matnr, new_matnr;
- int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
cdDM_update_normals_from_pbvh(dm);
@@ -1362,9 +1399,9 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
DMVertexAttribs attribs;
MVert *mvert = cddm->mvert;
MFace *mf = cddm->mface;
- float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
+ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
int a, matnr, new_matnr;
- int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
cdDM_update_normals_from_pbvh(dm);
@@ -1506,10 +1543,13 @@ static void cdDM_foreachMappedFaceCenter(
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
MVert *mv = cddm->mvert;
- MFace *mf = cddm->mface;
- int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ MPoly *mf = cddm->mpoly;
+ MLoop *ml = cddm->mloop;
+ int i, j, orig, *index;
- for(i = 0; i < dm->numFaceData; i++, mf++) {
+ index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
+ mf = cddm->mpoly;
+ for(i = 0; i < dm->numPolyData; i++, mf++) {
float cent[3];
float no[3];
@@ -1519,22 +1559,36 @@ static void cdDM_foreachMappedFaceCenter(
}
else
orig = i;
+
+ ml = &cddm->mloop[mf->loopstart];
+ cent[0] = cent[1] = cent[2] = 0.0f;
+ for (j=0; j<mf->totloop; j++, ml++) {
+ add_v3_v3v3(cent, cent, mv[ml->v].co);
+ }
+ mul_v3_fl(cent, 1.0f / (float)j);
- copy_v3_v3(cent, mv[mf->v1].co);
- add_v3_v3(cent, mv[mf->v2].co);
- add_v3_v3(cent, mv[mf->v3].co);
-
- if (mf->v4) {
- normal_quad_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
- add_v3_v3(cent, mv[mf->v4].co);
- mul_v3_fl(cent, 0.25f);
+ ml = &cddm->mloop[mf->loopstart];
+ if (j > 3) {
+ normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
+ mv[(ml+2)->v].co, mv[(ml+3)->v].co);
} else {
- normal_tri_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
- mul_v3_fl(cent, 0.33333333333f);
+ normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co, mv[(ml+2)->v].co);
}
func(userData, orig, cent, no);
}
+
+}
+
+void CDDM_recalc_tesselation(DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+
+ dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData,
+ &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData,
+ dm->numPolyData);
+
+ cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
}
static void cdDM_free_internal(CDDerivedMesh *cddm)
@@ -1553,6 +1607,11 @@ static void cdDM_release(DerivedMesh *dm)
}
}
+int CDDM_Check(DerivedMesh *dm)
+{
+ return dm && dm->getMinMax == cdDM_getMinMax;
+}
+
/**************** CDDM interface functions ****************/
static CDDerivedMesh *cdDM_create(const char *desc)
{
@@ -1565,21 +1624,28 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getMinMax = cdDM_getMinMax;
dm->getNumVerts = cdDM_getNumVerts;
- dm->getNumFaces = cdDM_getNumFaces;
dm->getNumEdges = cdDM_getNumEdges;
+ dm->getNumTessFaces = cdDM_getNumTessFaces;
+ dm->getNumFaces = cdDM_getNumFaces;
dm->getVert = cdDM_getVert;
dm->getEdge = cdDM_getEdge;
- dm->getFace = cdDM_getFace;
+ dm->getTessFace = cdDM_getFace;
dm->copyVertArray = cdDM_copyVertArray;
dm->copyEdgeArray = cdDM_copyEdgeArray;
- dm->copyFaceArray = cdDM_copyFaceArray;
+ dm->copyTessFaceArray = cdDM_copyFaceArray;
+ dm->copyLoopArray = cdDM_copyLoopArray;
+ dm->copyPolyArray = cdDM_copyPolyArray;
dm->getVertData = DM_get_vert_data;
dm->getEdgeData = DM_get_edge_data;
- dm->getFaceData = DM_get_face_data;
+ dm->getTessFaceData = DM_get_face_data;
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
- dm->getFaceDataArray = DM_get_face_data_layer;
+ dm->getTessFaceDataArray = DM_get_tessface_data_layer;
+
+ dm->calcNormals = CDDM_calc_normals;
+ //doesn't work yet for all cases
+ //dm->recalcTesselation = CDDM_recalc_tesselation;
dm->getVertCos = cdDM_getVertCos;
dm->getVertCo = cdDM_getVertCo;
@@ -1613,24 +1679,30 @@ static CDDerivedMesh *cdDM_create(const char *desc)
return cddm;
}
-DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
+DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces, int numLoops, int numPolys)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
DerivedMesh *dm = &cddm->dm;
- DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
+ DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
+ CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
+ CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
+ CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
+ CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
+ cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+ cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
return dm;
}
@@ -1641,10 +1713,12 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *dm = &cddm->dm;
CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
int alloctype;
+ int *polyindex = NULL;
/* this does a referenced copy, with an exception for fluidsim */
- DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface);
+ DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
+ mesh->totloop, mesh->totpoly);
dm->deformedOnly = 1;
@@ -1654,21 +1728,34 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
mesh->totedge);
- CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
+ CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
mesh->totface);
+ CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
+ mesh->totloop);
+ CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
+ mesh->totpoly);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
+ cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+ cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
+ BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
+
+ polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
+ if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
+ CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
+ }
+
return dm;
}
-DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
+static DerivedMesh *disabled__CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
{
DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
- BLI_countlist(&em->edges),
- BLI_countlist(&em->faces));
+ BLI_countlist(&em->edges),
+ BLI_countlist(&em->faces), 0, 0);
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
EditVert *eve;
EditEdge *eed;
@@ -1686,6 +1773,8 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
CD_CALLOC, dm->numEdgeData); */
CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
CD_CALLOC, dm->numFaceData);
+ CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, dm->numFaceData);
/* set eve->hash to vert index */
for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
@@ -1739,7 +1828,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
/* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
}
- index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ index = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
for(i = 0, efa = em->faces.first; i < dm->numFaceData;
i++, efa = efa->next, index++) {
MFace *mf = &mface[i];
@@ -1772,15 +1861,17 @@ DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
MVert *allvert;
MEdge *alledge;
MFace *allface;
- int totvert, totedge, totface;
+ MLoop *allloop;
+ MPoly *allpoly;
+ int totvert, totedge, totface, totloop, totpoly;
if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
- &totedge, &allface, &totface) != 0) {
+ &totedge, &allface, &allloop, &allpoly, &totface, &totloop, &totpoly) != 0) {
/* Error initializing mdata. This often happens when curve is empty */
- return CDDM_new(0, 0, 0);
+ return CDDM_new(0, 0, 0, 0, 0);
}
- dm = CDDM_new(totvert, totedge, totface);
+ dm = CDDM_new(totvert, totedge, totface, totloop, totpoly);
dm->deformedOnly = 1;
cddm = (CDDerivedMesh*)dm;
@@ -1788,29 +1879,245 @@ DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
memcpy(cddm->mface, allface, totface*sizeof(MFace));
+ memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
+ memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
MEM_freeN(allvert);
MEM_freeN(alledge);
MEM_freeN(allface);
+ MEM_freeN(allloop);
+ MEM_freeN(allpoly);
return dm;
}
-DerivedMesh *CDDM_copy(DerivedMesh *source)
+static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
+ int cdindex, BMLoop *l3[3],
+ int numCol, int numTex)
+{
+ BMLoop *l;
+ BMFace *f = l3[0]->f;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+ int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, 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++) {
+ l = l3[j];
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, 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(facedata, CD_MCOL, cdindex, i);
+
+ for (j=0; j<3; j++) {
+ l = l3[j];
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, 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(facedata, cdindex, CD_WEIGHT_MCOL);
+
+ for (j=0; j<3; j++) {
+ l = l3[j];
+ mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
+ mcol[j].r = mloopcol->r;
+ mcol[j].g = mloopcol->g;
+ mcol[j].b = mloopcol->b;
+ mcol[j].a = mloopcol->a;
+ }
+ }
+}
+
+DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps)
+{
+ DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge,
+ em->tottri, em->bm->totloop, em->bm->totface);
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+ BMesh *bm = em->bm;
+ BMIter iter, liter;
+ BMVert *eve;
+ BMEdge *eed;
+ BMFace *efa;
+ MVert *mvert = cddm->mvert;
+ MEdge *medge = cddm->medge;
+ MFace *mface = cddm->mface;
+ MLoop *mloop = cddm->mloop;
+ MPoly *mpoly = cddm->mpoly;
+ int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
+ int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
+ int i, j, *index, *polyindex, add_orig;
+ int has_crease, has_edge_bweight, has_vert_bweight;
+ int flag;
+
+ has_edge_bweight = CustomData_has_layer(&em->bm->edata, CD_BWEIGHT);
+ has_vert_bweight = CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT);
+ has_crease = CustomData_has_layer(&em->bm->edata, CD_CREASE);
+
+ dm->deformedOnly = 1;
+
+ /*don't add origindex layer if one already exists*/
+ add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX);
+
+ flag = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
+
+ /*don't process shapekeys, we only feed them through the modifier stack as needed,
+ e.g. for applying modifiers or the like*/
+ flag &= ~CD_SHAPEKEY;
+ CustomData_merge(&em->bm->vdata, &dm->vertData, flag,
+ CD_CALLOC, dm->numVertData);
+ CustomData_merge(&em->bm->edata, &dm->edgeData, flag,
+ CD_CALLOC, dm->numEdgeData);
+ CustomData_merge(&em->bm->ldata, &dm->loopData, flag,
+ CD_CALLOC, dm->numLoopData);
+ CustomData_merge(&em->bm->pdata, &dm->polyData, flag,
+ CD_CALLOC, dm->numPolyData);
+
+ /*add tesselation mface layers*/
+ CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
+
+ /* set vert index */
+ eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+ for (i=0; eve; eve=BMIter_Step(&iter), i++)
+ BM_SetIndex(eve, i);
+
+ index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+
+ eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+ for (i=0; eve; eve=BMIter_Step(&iter), i++, index++) {
+ MVert *mv = &mvert[i];
+
+ copy_v3_v3(mv->co, eve->co);
+
+ BM_SetIndex(eve, i);
+
+ normal_float_to_short_v3(mv->no, eve->no);
+
+ mv->flag = BMFlags_To_MEFlags(eve);
+
+ if (has_vert_bweight)
+ mv->bweight = (unsigned char)(BM_GetCDf(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
+
+ if (add_orig) *index = i;
+
+ CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
+ }
+
+ index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+ eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
+ for (i=0; eed; eed=BMIter_Step(&iter), i++, index++) {
+ MEdge *med = &medge[i];
+
+ BM_SetIndex(eed, i);
+
+ med->v1 = BM_GetIndex(eed->v1);
+ med->v2 = BM_GetIndex(eed->v2);
+
+ if (has_crease)
+ med->crease = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_CREASE)*255.0f);
+ if (has_edge_bweight)
+ med->bweight = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_BWEIGHT)*255.0f);
+
+ med->flag = BMFlags_To_MEFlags(eed);
+
+ CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
+ if (add_orig) *index = i;
+ }
+
+ efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+ for (i=0; efa; i++, efa=BMIter_Step(&iter)) {
+ BM_SetIndex(efa, i);
+ }
+
+ polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
+ index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ for(i = 0; i < dm->numFaceData; i++, index++) {
+ MFace *mf = &mface[i];
+ BMLoop **l = em->looptris[i];
+ efa = l[0]->f;
+
+ mf->v1 = BM_GetIndex(l[0]->v);
+ mf->v2 = BM_GetIndex(l[1]->v);
+ mf->v3 = BM_GetIndex(l[2]->v);
+ mf->v4 = 0;
+ mf->mat_nr = efa->mat_nr;
+ mf->flag = BMFlags_To_MEFlags(efa);
+
+ *index = add_orig ? BM_GetIndex(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
+ *polyindex = BM_GetIndex(efa);
+
+ loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
+ test_index_face(mf, &dm->faceData, i, 3);
+ }
+
+ index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
+ j = 0;
+ efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+ for (i=0; efa; i++, efa=BMIter_Step(&iter), index++) {
+ BMLoop *l;
+ MPoly *mp = &mpoly[i];
+
+ mp->totloop = efa->len;
+ mp->flag = BMFlags_To_MEFlags(efa);
+ mp->loopstart = j;
+ mp->mat_nr = efa->mat_nr;
+
+ BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
+ mloop->v = BM_GetIndex(l->v);
+ mloop->e = BM_GetIndex(l->e);
+ CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
+
+ j++;
+ mloop++;
+ }
+
+ CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
+
+ if (add_orig) *index = i;
+ }
+
+ return dm;
+}
+
+DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
DerivedMesh *dm = &cddm->dm;
int numVerts = source->numVertData;
int numEdges = source->numEdgeData;
int numFaces = source->numFaceData;
+ int numLoops = source->numLoopData;
+ int numPolys = source->numPolyData;
/* ensure these are created if they are made on demand */
source->getVertDataArray(source, CD_ORIGINDEX);
source->getEdgeDataArray(source, CD_ORIGINDEX);
- source->getFaceDataArray(source, CD_ORIGINDEX);
+ source->getTessFaceDataArray(source, CD_ORIGINDEX);
/* this initializes dm, and copies all non mvert/medge/mface layers */
- DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
+ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces,
+ numLoops, numPolys);
dm->deformedOnly = source->deformedOnly;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
@@ -1820,19 +2127,32 @@ DerivedMesh *CDDM_copy(DerivedMesh *source)
/* now add mvert/medge/mface layers */
cddm->mvert = source->dupVertArray(source);
cddm->medge = source->dupEdgeArray(source);
- cddm->mface = source->dupFaceArray(source);
+ cddm->mface = source->dupTessFaceArray(source);
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
+
+ if (!faces_from_tessfaces)
+ DM_DupPolys(source, dm);
+ else
+ CDDM_tessfaces_to_faces(dm);
+ cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+ cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+
+ /* BMESH_TODO: Find out why this is necessary (or else find a way to remove
+ it). If it is necessary, add a comment explaining why. */
+ CDDM_recalc_tesselation((DerivedMesh *)cddm);
+
return dm;
}
/* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
* relationship betwen mesh data this needs to be set by the caller. */
DerivedMesh *CDDM_from_template(DerivedMesh *source,
- int numVerts, int numEdges, int numFaces)
+ int numVerts, int numEdges, int numFaces,
+ int numLoops, int numPolys)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
DerivedMesh *dm = &cddm->dm;
@@ -1840,15 +2160,17 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
/* ensure these are created if they are made on demand */
source->getVertDataArray(source, CD_ORIGINDEX);
source->getEdgeDataArray(source, CD_ORIGINDEX);
- source->getFaceDataArray(source, CD_ORIGINDEX);
+ source->getTessFaceDataArray(source, CD_ORIGINDEX);
/* this does a copy of all non mvert/medge/mface layers */
- DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
+ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
/* now add mvert/medge/mface layers */
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
+ CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
+ CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
@@ -1856,10 +2178,14 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
+ if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
+ CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
+ cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+ cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
return dm;
}
@@ -1895,23 +2221,232 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
void CDDM_calc_normals(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
- float (*face_nors)[3];
-
+ float (*face_nors)[3] = NULL;
+
if(dm->numVertData == 0) return;
/* we don't want to overwrite any referenced layers */
cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
- /* 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->numFaceData == 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->numFaceData);
+ }
+ face_nors = MEM_mallocN(sizeof(float)*3*dm->numFaceData, "face_nors");
+
/* calculate face normals */
- mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_faces(dm), dm->numFaceData, face_nors);
+ mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
+ dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numFaceData,
+ CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors);
+
+ CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
+ face_nors, dm->numFaceData);
}
+#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(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;
@@ -1968,6 +2503,83 @@ void CDDM_calc_edges(DerivedMesh *dm)
BLI_edgehash_free(eh, NULL);
}
+
+void CDDM_calc_edges_poly(DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+ CustomData edgeData;
+ EdgeHashIterator *ehi;
+ MPoly *mp = cddm->mpoly;
+ MLoop *ml;
+ MEdge *med;
+ EdgeHash *eh = BLI_edgehash_new();
+ int v1, v2;
+ int *eindex;
+ int i, j, k, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
+
+ eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
+
+ med = cddm->medge;
+ if (med) {
+ for (i=0; i < numEdges; i++, med++) {
+ BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
+ }
+ }
+
+ for (i=0; i < maxFaces; i++, mp++) {
+ ml = cddm->mloop + mp->loopstart;
+ for (j=0; j<mp->totloop; j++, ml++) {
+ v1 = ml->v;
+ v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
+ if (!BLI_edgehash_haskey(eh, v1, v2)) {
+ BLI_edgehash_insert(eh, v1, v2, NULL);
+ }
+ }
+ }
+
+ k = numEdges;
+ numEdges = BLI_edgehash_size(eh);
+
+ /* write new edges into a temporary CustomData */
+ memset(&edgeData, 0, sizeof(edgeData));
+ CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
+ CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
+
+ ehi = BLI_edgehashIterator_new(eh);
+ med = CustomData_get_layer(&edgeData, CD_MEDGE);
+ index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
+ for(i = 0; !BLI_edgehashIterator_isDone(ehi);
+ BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+ BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
+ j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
+
+ med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+ *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
+
+ BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /* free old CustomData and assign new one */
+ CustomData_free(&dm->edgeData, dm->numEdgeData);
+ dm->edgeData = edgeData;
+ dm->numEdgeData = numEdges;
+
+ cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
+
+ mp = cddm->mpoly;
+ for (i=0; i < maxFaces; i++, mp++) {
+ ml = cddm->mloop + mp->loopstart;
+ for (j=0; j<mp->totloop; j++, ml++) {
+ v1 = ml->v;
+ v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
+ ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
+ }
+ }
+
+ BLI_edgehash_free(eh, NULL);
+}
+
void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
{
if (numVerts < dm->numVertData)
@@ -2002,7 +2614,7 @@ MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
return &((CDDerivedMesh*)dm)->medge[index];
}
-MFace *CDDM_get_face(DerivedMesh *dm, int index)
+MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
{
return &((CDDerivedMesh*)dm)->mface[index];
}
@@ -2017,8 +2629,125 @@ MEdge *CDDM_get_edges(DerivedMesh *dm)
return ((CDDerivedMesh*)dm)->medge;
}
-MFace *CDDM_get_faces(DerivedMesh *dm)
+MFace *CDDM_get_tessfaces(DerivedMesh *dm)
{
return ((CDDerivedMesh*)dm)->mface;
}
+MLoop *CDDM_get_loops(DerivedMesh *dm)
+{
+ return ((CDDerivedMesh*)dm)->mloop;
+}
+
+MPoly *CDDM_get_polys(DerivedMesh *dm)
+{
+ return ((CDDerivedMesh*)dm)->mpoly;
+}
+
+void CDDM_tessfaces_to_faces(DerivedMesh *dm)
+{
+ /*converts mfaces to mpolys/mloops*/
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+ MFace *mf;
+ MEdge *me;
+ MLoop *ml;
+ MPoly *mp;
+ EdgeHash *eh = BLI_edgehash_new();
+ int i, l, totloop, *polyindex;
+
+ /*ensure we have all the edges we need*/
+ CDDM_calc_edges(dm);
+
+ /*build edge hash*/
+ me = cddm->medge;
+ for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
+ BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
+ }
+
+ mf = cddm->mface;
+ totloop = 0;
+ for (i=0; i<cddm->dm.numFaceData; i++, mf++) {
+ totloop += mf->v4 ? 4 : 3;
+ }
+
+ CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
+ CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
+
+ cddm->dm.numLoopData = totloop;
+ cddm->dm.numPolyData = cddm->dm.numFaceData;
+
+ if (!totloop) return;
+
+ cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
+ cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
+
+ CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
+ CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
+ CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
+ CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numFaceData);
+
+ polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
+
+ mf = cddm->mface;
+ mp = cddm->mpoly;
+ ml = cddm->mloop;
+ l = 0;
+ for (i=0; i<cddm->dm.numFaceData; i++, mf++, mp++) {
+ mp->flag = mf->flag;
+ mp->loopstart = l;
+ mp->mat_nr = mf->mat_nr;
+ mp->totloop = mf->v4 ? 4 : 3;
+
+ ml->v = mf->v1;
+ ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
+ ml++, l++;
+
+ ml->v = mf->v2;
+ ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
+ ml++, l++;
+
+ ml->v = mf->v3;
+ ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
+ ml++, l++;
+
+ if (mf->v4) {
+ ml->v = mf->v4;
+ ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
+ ml++, l++;
+ }
+
+ *polyindex = i;
+ }
+
+ BLI_edgehash_free(eh, NULL);
+}
+
+void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+
+ if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
+ CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
+
+ cddm->mvert = mvert;
+}
+
+void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+
+ if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
+ CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
+
+ cddm->medge = medge;
+}
+
+void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+
+ if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
+ CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numFaceData);
+
+ cddm->mface = mface;
+}