diff options
Diffstat (limited to 'source/blender/blenkernel/intern/DerivedMesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 1673 |
1 files changed, 506 insertions, 1167 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 0c99735f73e..769f6b04cf4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -31,7 +31,7 @@ #include <string.h> - +#include "limits.h" #include "MEM_guardedalloc.h" @@ -46,6 +46,7 @@ #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_memarena.h" +#include "BLI_array.h" #include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" @@ -60,6 +61,9 @@ #include "BKE_texture.h" #include "BKE_multires.h" #include "BKE_armature.h" +#include "BKE_particle.h" +#include "BKE_tessmesh.h" +#include "BKE_bvhutils.h" #ifdef WITH_GAMEENGINE #include "BKE_navmesh_conversion.h" @@ -77,6 +81,9 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm); extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ +static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob); +static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid); + /////////////////////////////////// /////////////////////////////////// @@ -114,14 +121,42 @@ static MFace *dm_getFaceArray(DerivedMesh *dm) if (!mface) { mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, - dm->getNumFaces(dm)); + dm->getNumTessFaces(dm)); CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY); - dm->copyFaceArray(dm, mface); + dm->copyTessFaceArray(dm, mface); } return mface; } +static MLoop *dm_getLoopArray(DerivedMesh *dm) +{ + MLoop *mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP); + + if (!mloop) { + mloop = CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, + dm->numLoopData); + CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY); + dm->copyLoopArray(dm, mloop); + } + + return mloop; +} + +static MPoly *dm_getPolyArray(DerivedMesh *dm) +{ + MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); + + if (!mpoly) { + mpoly = CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, + dm->getNumFaces(dm)); + CustomData_set_layer_flag(&dm->polyData, CD_MPOLY, CD_FLAG_TEMPORARY); + dm->copyPolyArray(dm, mpoly); + } + + return mpoly; +} + static MVert *dm_dupVertArray(DerivedMesh *dm) { MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm), @@ -144,41 +179,98 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm) static MFace *dm_dupFaceArray(DerivedMesh *dm) { - MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm), + MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm), "dm_dupFaceArray tmp"); - if(tmp) dm->copyFaceArray(dm, tmp); + if(tmp) dm->copyTessFaceArray(dm, tmp); + + return tmp; +} + +static MLoop *dm_dupLoopArray(DerivedMesh *dm) +{ + MLoop *tmp = MEM_callocN(sizeof(*tmp) * dm->numLoopData, + "dm_dupLoopArray tmp"); + + if(tmp) dm->copyLoopArray(dm, tmp); return tmp; } +static MPoly *dm_dupPolyArray(DerivedMesh *dm) +{ + MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->numFaceData, + "dm_dupPolyArray tmp"); + + if(tmp) dm->copyPolyArray(dm, tmp); + + return tmp; +} + +static CustomData *dm_getVertCData(DerivedMesh *dm) +{ + return &dm->vertData; +} + +static CustomData *dm_getEdgeCData(DerivedMesh *dm) +{ + return &dm->edgeData; +} + +static CustomData *dm_getFaceCData(DerivedMesh *dm) +{ + return &dm->faceData; +} + +static CustomData *dm_getLoopCData(DerivedMesh *dm) +{ + return &dm->loopData; +} + +static CustomData *dm_getPolyCData(DerivedMesh *dm) +{ + return &dm->polyData; +} + void DM_init_funcs(DerivedMesh *dm) { /* default function implementations */ dm->getVertArray = dm_getVertArray; dm->getEdgeArray = dm_getEdgeArray; - dm->getFaceArray = dm_getFaceArray; + dm->getTessFaceArray = dm_getFaceArray; + dm->getLoopArray = dm_getLoopArray; + dm->getPolyArray = dm_getPolyArray; dm->dupVertArray = dm_dupVertArray; dm->dupEdgeArray = dm_dupEdgeArray; - dm->dupFaceArray = dm_dupFaceArray; + dm->dupTessFaceArray = dm_dupFaceArray; + dm->dupLoopArray = dm_dupLoopArray; + dm->dupPolyArray = dm_dupPolyArray; + + dm->getVertDataLayout = dm_getVertCData; + dm->getEdgeDataLayout = dm_getEdgeCData; + dm->getTessFaceDataLayout = dm_getFaceCData; + dm->getLoopDataLayout = dm_getLoopCData; + dm->getFaceDataLayout = dm_getPolyCData; 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; bvhcache_init(&dm->bvhCache); } -void DM_init(DerivedMesh *dm, DerivedMeshType type, - int numVerts, int numEdges, int numFaces) +void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, + int numFaces, int numLoops, int numPoly) { dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; + dm->numLoopData = numLoops; + dm->numPolyData = numPoly; DM_init_funcs(dm); @@ -186,7 +278,8 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, } void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, - int numVerts, int numEdges, int numFaces) + int numVerts, int numEdges, int numFaces, + int numLoops, int numPolys) { CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, CD_CALLOC, numVerts); @@ -194,11 +287,17 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type CD_CALLOC, numEdges); CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, CD_CALLOC, numFaces); + CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH, + CD_CALLOC, numLoops); + CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH, + CD_CALLOC, numPolys); dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; + dm->numLoopData = numLoops; + dm->numPolyData = numPolys; DM_init_funcs(dm); @@ -213,6 +312,8 @@ int DM_release(DerivedMesh *dm) CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numFaceData); + CustomData_free(&dm->loopData, dm->numLoopData); + CustomData_free(&dm->polyData, dm->numPolyData); return 1; } @@ -220,29 +321,82 @@ int DM_release(DerivedMesh *dm) CustomData_free_temporary(&dm->vertData, dm->numVertData); CustomData_free_temporary(&dm->edgeData, dm->numEdgeData); CustomData_free_temporary(&dm->faceData, dm->numFaceData); + CustomData_free_temporary(&dm->loopData, dm->numLoopData); + CustomData_free_temporary(&dm->polyData, dm->numPolyData); return 0; } } -void DM_to_mesh(DerivedMesh *dm, Mesh *me) +void DM_DupPolys(DerivedMesh *source, DerivedMesh *target) +{ + CustomData_copy(&source->loopData, &target->loopData, CD_MASK_DERIVEDMESH, CD_CALLOC, source->numLoopData); + CustomData_copy(&source->polyData, &target->polyData, CD_MASK_DERIVEDMESH, CD_CALLOC, source->numPolyData); + + target->numLoopData = source->numLoopData; + target->numPolyData = source->numPolyData; + + if (!CustomData_has_layer(&target->polyData, CD_MPOLY)) { + MPoly *mpoly; + MLoop *mloop; + + mloop = source->dupLoopArray(source); + mpoly = source->dupPolyArray(source); + CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData); + CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->numPolyData); + } +} + +void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) { /* dm might depend on me, so we need to do everything with a local copy */ Mesh tmp = *me; - int totvert, totedge, totface; - + int totvert, totedge, totface, totloop, totpoly; + int did_shapekeys=0; + memset(&tmp.vdata, 0, sizeof(tmp.vdata)); memset(&tmp.edata, 0, sizeof(tmp.edata)); memset(&tmp.fdata, 0, sizeof(tmp.fdata)); + memset(&tmp.ldata, 0, sizeof(tmp.ldata)); + memset(&tmp.pdata, 0, sizeof(tmp.pdata)); totvert = tmp.totvert = dm->getNumVerts(dm); totedge = tmp.totedge = dm->getNumEdges(dm); - totface = tmp.totface = dm->getNumFaces(dm); + totface = tmp.totface = dm->getNumTessFaces(dm); + totpoly = tmp.totpoly = dm->getNumFaces(dm); + totloop = tmp.totloop = dm->numLoopData; CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface); + CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop); + CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly); + if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { + KeyBlock *kb; + int i=0; + + if (ob) { + for (kb=me->key->block.first; kb; kb=kb->next, i++) { + if (i == ob->shapenr-1) { + i = kb->uid; + break; + } + } + + if (!kb) { + printf("error in DM_to_mesh: could not find active shapekey! eek!!\n"); + i = INT_MAX; + } + } else { + /*if no object, set to INT_MAX so we don't mess up any shapekey layers*/ + i = INT_MAX; + } + + shapekey_layers_to_keyblocks(dm, me, i); + did_shapekeys = 1; + } + /* not all DerivedMeshes store their verts/edges/faces in CustomData, so we set them here in case they are missing */ if(!CustomData_has_layer(&tmp.vdata, CD_MVERT)) @@ -250,14 +404,21 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me) if(!CustomData_has_layer(&tmp.edata, CD_MEDGE)) CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge); if(!CustomData_has_layer(&tmp.fdata, CD_MFACE)) - CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface); + CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupTessFaceArray(dm), totface); + if(!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) { + tmp.mloop = dm->dupLoopArray(dm); + tmp.mpoly = dm->dupPolyArray(dm); + + CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop); + CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly); + } /* object had got displacement layer, should copy this layer to save sculpted data */ /* NOTE: maybe some other layers should be copied? nazgul */ - if(CustomData_has_layer(&me->fdata, CD_MDISPS)) { - if (totface == me->totface) { - MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); - CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface); + if(CustomData_has_layer(&me->ldata, CD_MDISPS)) { + if (totloop == me->totloop) { + MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); + CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop); } } @@ -266,9 +427,14 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me) CustomData_free(&me->vdata, me->totvert); CustomData_free(&me->edata, me->totedge); CustomData_free(&me->fdata, me->totface); - - /* if the number of verts has changed, remove invalid data */ - if(tmp.totvert != me->totvert) { + CustomData_free(&me->ldata, me->totloop); + CustomData_free(&me->pdata, me->totpoly); + + /* ok, this should now use new CD shapekey data, + which shouuld be fed through the modifier + stack*/ + if(tmp.totvert != me->totvert && !did_shapekeys && me->key) { + printf("YEEK! this should be recoded! Shape key loss!!!\n"); if(tmp.key) tmp.key->id.us--; tmp.key = NULL; } @@ -313,11 +479,21 @@ void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer) CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData); } -void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer) +void DM_add_tessface_layer(DerivedMesh *dm, int type, int alloctype, void *layer) { CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData); } +static void DM_add_loop_layer(DerivedMesh *dm, int type, int alloctype, void *layer) +{ + CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData); +} + +void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer) +{ + CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData); +} + void *DM_get_vert_data(DerivedMesh *dm, int index, int type) { return CustomData_get(&dm->vertData, index, type); @@ -349,14 +525,19 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type) return CustomData_get_layer(&dm->edgeData, type); } -void *DM_get_face_data_layer(DerivedMesh *dm, int type) +void *DM_get_tessface_data_layer(DerivedMesh *dm, int type) { if(type == CD_MFACE) - return dm->getFaceArray(dm); + return dm->getTessFaceArray(dm); return CustomData_get_layer(&dm->faceData, type); } +void *DM_get_face_data_layer(DerivedMesh *dm, int type) +{ + return CustomData_get_layer(&dm->polyData, type); +} + void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data) { CustomData_set(&dm->vertData, index, type, data); @@ -386,13 +567,27 @@ void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest, source_index, dest_index, count); } -void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest, +void DM_copy_tessface_data(DerivedMesh *source, DerivedMesh *dest, int source_index, int dest_index, int count) { CustomData_copy_data(&source->faceData, &dest->faceData, source_index, dest_index, count); } +void DM_copy_loop_data(DerivedMesh *source, DerivedMesh *dest, + int source_index, int dest_index, int count) +{ + CustomData_copy_data(&source->loopData, &dest->loopData, + source_index, dest_index, count); +} + +void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest, + int source_index, int dest_index, int count) +{ + CustomData_copy_data(&source->polyData, &dest->polyData, + source_index, dest_index, count); +} + void DM_free_vert_data(struct DerivedMesh *dm, int index, int count) { CustomData_free_elem(&dm->vertData, index, count); @@ -403,11 +598,21 @@ void DM_free_edge_data(struct DerivedMesh *dm, int index, int count) CustomData_free_elem(&dm->edgeData, index, count); } -void DM_free_face_data(struct DerivedMesh *dm, int index, int count) +void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count) { CustomData_free_elem(&dm->faceData, index, count); } +void DM_free_loop_data(struct DerivedMesh *dm, int index, int count) +{ + CustomData_free_elem(&dm->loopData, index, count); +} + +void DM_free_face_data(struct DerivedMesh *dm, int index, int count) +{ + CustomData_free_elem(&dm->polyData, index, count); +} + void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest, int *src_indices, float *weights, int count, int dest_index) @@ -425,7 +630,7 @@ void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest, weights, (float*)vert_weights, count, dest_index); } -void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest, +void DM_interp_tessface_data(DerivedMesh *source, DerivedMesh *dest, int *src_indices, float *weights, FaceVertWeight *vert_weights, int count, int dest_index) @@ -434,13 +639,28 @@ void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest, weights, (float*)vert_weights, count, dest_index); } -void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices) +void DM_swap_tessface_data(DerivedMesh *dm, int index, const int *corner_indices) { CustomData_swap(&dm->faceData, index, corner_indices); } -/// +void DM_interp_loop_data(DerivedMesh *source, DerivedMesh *dest, + int *src_indices, + float *weights, int count, int dest_index) +{ + CustomData_interp(&source->loopData, &dest->loopData, src_indices, + weights, NULL, count, dest_index); +} + +void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest, + int *src_indices, + float *weights, int count, int dest_index) +{ + CustomData_interp(&source->polyData, &dest->polyData, src_indices, + weights, NULL, count, dest_index); +} +/// DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) { DerivedMesh *dm = CDDM_from_mesh(me, ob); @@ -456,1046 +676,10 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) return dm; } -/// - -typedef struct { - DerivedMesh dm; - - EditMesh *em; - float (*vertexCos)[3]; - float (*vertexNos)[3]; - float (*faceNos)[3]; -} EditMeshDerivedMesh; - -static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditVert *eve; - int i; - - for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { - if (emdm->vertexCos) { - func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL); - } else { - func(userData, i, eve->co, eve->no, NULL); - } - } -} -static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditEdge *eed; - int i; - - if (emdm->vertexCos) { - EditVert *eve; - - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) - func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]); - } else { - for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) - func(userData, i, eed->v1->co, eed->v2->co); - } -} -static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditEdge *eed; - int i; - - if (emdm->vertexCos) { - EditVert *eve; - - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - - glBegin(GL_LINES); - for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, i)) { - glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]); - } - } - glEnd(); - } else { - glBegin(GL_LINES); - for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, i)) { - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); - } - } - glEnd(); - } -} -static void emDM_drawEdges(DerivedMesh *dm, int UNUSED(drawLooseEdges), int UNUSED(drawAllEdges)) -{ - emDM_drawMappedEdges(dm, NULL, NULL); -} -static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditEdge *eed; - int i; - - if (emdm->vertexCos) { - EditVert *eve; - - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - - glBegin(GL_LINES); - for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, i)) { - setDrawInterpOptions(userData, i, 0.0); - glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]); - setDrawInterpOptions(userData, i, 1.0); - glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]); - } - } - glEnd(); - } else { - glBegin(GL_LINES); - for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, i)) { - setDrawInterpOptions(userData, i, 0.0); - glVertex3fv(eed->v1->co); - setDrawInterpOptions(userData, i, 1.0); - glVertex3fv(eed->v2->co); - } - } - glEnd(); - } -} - -static void emDM_drawUVEdges(DerivedMesh *dm) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditFace *efa; - MTFace *tf; - - glBegin(GL_LINES); - for(efa= emdm->em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE); - - if(tf && !(efa->h)) { - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - - if (!efa->v4) { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[0]); - } else { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[0]); - } - } - } - glEnd(); -} - -static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3]) -{ - if (vertexCos) { - VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]); - add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]); - add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]); - if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]); - } else { - VECCOPY(cent, efa->v1->co); - add_v3_v3(cent, efa->v2->co); - add_v3_v3(cent, efa->v3->co); - if (efa->v4) add_v3_v3(cent, efa->v4->co); - } - - if (efa->v4) { - mul_v3_fl(cent, 0.25f); - } else { - mul_v3_fl(cent, 0.33333333333f); - } -} -static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditVert *eve; - EditFace *efa; - float cent[3]; - int i; - - if (emdm->vertexCos) { - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - } - - for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - emDM__calcFaceCent(efa, cent, emdm->vertexCos); - func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n); - } -} - -/* note, material function is ignored for now. */ -static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs), - int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditFace *efa; - int i, draw; - const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ - - /* GL_ZERO is used to detect if drawing has started or not */ - GLenum poly_prev= GL_ZERO; - GLenum shade_prev= GL_ZERO; - - (void)setMaterial; /* unused */ - - /* currently unused -- each original face is handled separately */ - (void)compareDrawOptions; - - if (emdm->vertexCos) { - /* add direct access */ - float (*vertexCos)[3]= emdm->vertexCos; - float (*vertexNos)[3]= emdm->vertexNos; - float (*faceNos)[3]= emdm->faceNos; - EditVert *eve; - - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - - for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - int drawSmooth = (efa->flag & ME_SMOOTH); - draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); - if(draw) { - const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; - if (draw==2) { /* enabled with stipple */ - - if(poly_prev != GL_ZERO) glEnd(); - poly_prev= GL_ZERO; /* force glBegin */ - - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); - } - - if(skip_normals) { - if(poly_type != poly_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev= poly_type)); - } - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } - else { - const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; - if (shade_type != shade_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */ - glBegin((poly_prev= poly_type)); - } - else if(poly_type != poly_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev= poly_type)); - } - - if (!drawSmooth) { - glNormal3fv(faceNos[i]); - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } else { - glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - if(poly_type == GL_QUADS) { - glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } - } - } - - - if (draw==2) { - glEnd(); - poly_prev= GL_ZERO; /* force glBegin */ - - glDisable(GL_POLYGON_STIPPLE); - } - } - } - } - else { - for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - int drawSmooth = (efa->flag & ME_SMOOTH); - draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); - if(draw) { - const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; - if (draw==2) { /* enabled with stipple */ - - if(poly_prev != GL_ZERO) glEnd(); - poly_prev= GL_ZERO; /* force glBegin */ - - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); - } - - if(skip_normals) { - if(poly_type != poly_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev= poly_type)); - } - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); - } - else { - const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; - if (shade_type != shade_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */ - glBegin((poly_prev= poly_type)); - } - else if(poly_type != poly_prev) { - if(poly_prev != GL_ZERO) glEnd(); - glBegin((poly_prev= poly_type)); - } - - if (!drawSmooth) { - glNormal3fv(efa->n); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); - } else { - glNormal3fv(efa->v1->no); - glVertex3fv(efa->v1->co); - glNormal3fv(efa->v2->no); - glVertex3fv(efa->v2->co); - glNormal3fv(efa->v3->no); - glVertex3fv(efa->v3->co); - if(poly_type == GL_QUADS) { - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); - } - } - } - - - if (draw==2) { - glEnd(); - poly_prev= GL_ZERO; - - glDisable(GL_POLYGON_STIPPLE); - } - } - } - } - - /* if non zero we know a face was rendered */ - if(poly_prev != GL_ZERO) glEnd(); -} - -static void emDM_drawFacesTex_common(DerivedMesh *dm, - int (*drawParams)(MTFace *tface, int has_mcol, int matnr), - int (*drawParamsMapped)(void *userData, int index), - void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditMesh *em= emdm->em; - float (*vertexCos)[3]= emdm->vertexCos; - float (*vertexNos)[3]= emdm->vertexNos; - EditFace *efa; - int i; - - /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ - glShadeModel(GL_SMOOTH); - - if (vertexCos) { - EditVert *eve; - - for (i=0,eve=em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - - for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { - MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); - unsigned char *cp= NULL; - int drawSmooth= (efa->flag & ME_SMOOTH); - int flag; - - if(drawParams) - flag= drawParams(tf, (mcol != NULL), efa->mat_nr); - else if(drawParamsMapped) - flag= drawParamsMapped(userData, i); - else - flag= 1; - - if(flag != 0) { /* flag 0 == the face is hidden or invisible */ - - /* we always want smooth here since otherwise vertex colors dont interpolate */ - if (mcol) { - if (flag==1) { - cp= (unsigned char*)mcol; - } - } else { - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - } - - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(emdm->faceNos[i]); - - if(tf) glTexCoord2fv(tf->uv[0]); - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - - if(tf) glTexCoord2fv(tf->uv[1]); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - - if(tf) glTexCoord2fv(tf->uv[2]); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - - if(efa->v4) { - if(tf) glTexCoord2fv(tf->uv[3]); - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } - } else { - if(tf) glTexCoord2fv(tf->uv[0]); - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - - if(tf) glTexCoord2fv(tf->uv[1]); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - - if(tf) glTexCoord2fv(tf->uv[2]); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - - if(efa->v4) { - if(tf) glTexCoord2fv(tf->uv[3]); - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } - } - glEnd(); - } - } - } else { - for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { - MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); - unsigned char *cp= NULL; - int drawSmooth= (efa->flag & ME_SMOOTH); - int flag; - - if(drawParams) - flag= drawParams(tf, (mcol != NULL), efa->mat_nr); - else if(drawParamsMapped) - flag= drawParamsMapped(userData, i); - else - flag= 1; - - if(flag != 0) { /* flag 0 == the face is hidden or invisible */ - /* we always want smooth here since otherwise vertex colors dont interpolate */ - if (mcol) { - if (flag==1) { - cp= (unsigned char*)mcol; - } - } else { - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - } - - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(efa->n); - - if(tf) glTexCoord2fv(tf->uv[0]); - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(efa->v1->co); - - if(tf) glTexCoord2fv(tf->uv[1]); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glVertex3fv(efa->v2->co); - - if(tf) glTexCoord2fv(tf->uv[2]); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glVertex3fv(efa->v3->co); - - if(efa->v4) { - if(tf) glTexCoord2fv(tf->uv[3]); - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glVertex3fv(efa->v4->co); - } - } else { - if(tf) glTexCoord2fv(tf->uv[0]); - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3fv(efa->v1->no); - glVertex3fv(efa->v1->co); - - if(tf) glTexCoord2fv(tf->uv[1]); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3fv(efa->v2->no); - glVertex3fv(efa->v2->co); - - if(tf) glTexCoord2fv(tf->uv[2]); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3fv(efa->v3->no); - glVertex3fv(efa->v3->co); - - if(efa->v4) { - if(tf) glTexCoord2fv(tf->uv[3]); - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); - } - } - glEnd(); - } - } - } -} - -static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr)) -{ - emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); -} - -static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) -{ - emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); -} - -static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, - int (*setMaterial)(int, void *attribs), - int (*setDrawOptions)(void *userData, int index), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditMesh *em= emdm->em; - float (*vertexCos)[3]= emdm->vertexCos; - float (*vertexNos)[3]= emdm->vertexNos; - EditVert *eve; - EditFace *efa; - DMVertexAttribs attribs= {{{0}}}; - GPUVertexAttribs gattribs; - /* int tfoffset; */ /* UNUSED */ - int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */; - - dodraw = 0; - matnr = -1; - - /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */ - /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */ - - /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ - glShadeModel(GL_SMOOTH); - - for (i=0,eve=em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - -#define PASSATTRIB(efa, eve, vert) { \ - if(attribs.totorco) { \ - float *orco = attribs.orco.array[eve->tmp.l]; \ - glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \ - } \ - for(b = 0; b < attribs.tottface; b++) { \ - MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \ - glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \ - } \ - for(b = 0; b < attribs.totmcol; b++) { \ - MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \ - GLubyte col[4]; \ - col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ - glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ - } \ - if(attribs.tottang) { \ - float *tang = attribs.tang.array[i*4 + vert]; \ - glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ - } \ -} - - for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { - int drawSmooth= (efa->flag & ME_SMOOTH); - - if(setDrawOptions && !setDrawOptions(userData, i)) - continue; - - new_matnr = efa->mat_nr + 1; - if(new_matnr != matnr) { - dodraw = setMaterial(matnr = new_matnr, &gattribs); - if(dodraw) - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } - - if(dodraw) { - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - if(vertexCos) glNormal3fv(emdm->faceNos[i]); - else glNormal3fv(efa->n); - - PASSATTRIB(efa, efa->v1, 0); - if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - else glVertex3fv(efa->v1->co); - - PASSATTRIB(efa, efa->v2, 1); - if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - else glVertex3fv(efa->v2->co); - - PASSATTRIB(efa, efa->v3, 2); - if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - else glVertex3fv(efa->v3->co); - - if(efa->v4) { - PASSATTRIB(efa, efa->v4, 3); - if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - else glVertex3fv(efa->v4->co); - } - } else { - PASSATTRIB(efa, efa->v1, 0); - if(vertexCos) { - glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); - } - else { - glNormal3fv(efa->v1->no); - glVertex3fv(efa->v1->co); - } - - PASSATTRIB(efa, efa->v2, 1); - if(vertexCos) { - glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); - } - else { - glNormal3fv(efa->v2->no); - glVertex3fv(efa->v2->co); - } - - PASSATTRIB(efa, efa->v3, 2); - if(vertexCos) { - glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); - } - else { - glNormal3fv(efa->v3->no); - glVertex3fv(efa->v3->co); - } - - if(efa->v4) { - PASSATTRIB(efa, efa->v4, 3); - if(vertexCos) { - glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); - glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); - } - else { - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); - } - } - } - glEnd(); - } - } -#undef PASSATTRIB -} - -static void emDM_drawFacesGLSL(DerivedMesh *dm, - int (*setMaterial)(int, void *attribs)) -{ - dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); -} - -static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditVert *eve; - int i; - - if (emdm->em->verts.first) { - for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) { - if (emdm->vertexCos) { - DO_MINMAX(emdm->vertexCos[i], min_r, max_r); - } else { - DO_MINMAX(eve->co, min_r, max_r); - } - } - } else { - min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; - } -} -static int emDM_getNumVerts(DerivedMesh *dm) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - - return BLI_countlist(&emdm->em->verts); -} - -static int emDM_getNumEdges(DerivedMesh *dm) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - - return BLI_countlist(&emdm->em->edges); -} - -static int emDM_getNumFaces(DerivedMesh *dm) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - - return BLI_countlist(&emdm->em->faces); -} - -static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditVert *eve; - int i; - - for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { - if (emdm->vertexCos) { - copy_v3_v3(cos_r[i], emdm->vertexCos[i]); - } else { - copy_v3_v3(cos_r[i], eve->co); - } - } -} - -static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) -{ - EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first; - int i; - - for(i = 0; i < index; ++i) ev = ev->next; - - VECCOPY(vert_r->co, ev->co); - - normal_float_to_short_v3(vert_r->no, ev->no); - - /* TODO what to do with vert_r->flag? */ - vert_r->bweight = (unsigned char) (ev->bweight*255.0f); -} - -static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) -{ - EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; - EditEdge *ee = em->edges.first; - EditVert *ev, *v1, *v2; - int i; - - for(i = 0; i < index; ++i) ee = ee->next; - - edge_r->crease = (unsigned char) (ee->crease*255.0f); - edge_r->bweight = (unsigned char) (ee->bweight*255.0f); - /* TODO what to do with edge_r->flag? */ - edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER; - if (ee->seam) edge_r->flag |= ME_SEAM; - if (ee->sharp) edge_r->flag |= ME_SHARP; -#if 0 - /* this needs setup of f2 field */ - if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE; -#endif - - /* goddamn, we have to search all verts to find indices */ - v1 = ee->v1; - v2 = ee->v2; - for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) { - if(ev == v1) { - edge_r->v1 = i; - v1 = NULL; - } - if(ev == v2) { - edge_r->v2 = i; - v2 = NULL; - } - } -} - -static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r) -{ - EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; - EditFace *ef = em->faces.first; - EditVert *ev, *v1, *v2, *v3, *v4; - int i; - - for(i = 0; i < index; ++i) ef = ef->next; - - face_r->mat_nr = ef->mat_nr; - face_r->flag = ef->flag; - - /* goddamn, we have to search all verts to find indices */ - v1 = ef->v1; - v2 = ef->v2; - v3 = ef->v3; - v4 = ef->v4; - if(!v4) face_r->v4 = 0; - - for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4; - i++, ev = ev->next) { - if(ev == v1) { - face_r->v1 = i; - v1 = NULL; - } - if(ev == v2) { - face_r->v2 = i; - v2 = NULL; - } - if(ev == v3) { - face_r->v3 = i; - v3 = NULL; - } - if(ev == v4) { - face_r->v4 = i; - v4 = NULL; - } - } - - test_index_face(face_r, NULL, 0, ef->v4?4:3); -} - -static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditVert *ev = emdm->em->verts.first; - int i; - - for(i=0; ev; ev = ev->next, ++vert_r, ++i) { - if(emdm->vertexCos) - copy_v3_v3(vert_r->co, emdm->vertexCos[i]); - else - copy_v3_v3(vert_r->co, ev->co); - - normal_float_to_short_v3(vert_r->no, ev->no); - - /* TODO what to do with vert_r->flag? */ - vert_r->flag = 0; - vert_r->bweight = (unsigned char) (ev->bweight*255.0f); - } -} - -static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) -{ - EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; - EditEdge *ee = em->edges.first; - EditVert *ev; - int i; - - /* store vertex indices in tmp union */ - for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) - ev->tmp.l = (intptr_t) i; - - for( ; ee; ee = ee->next, ++edge_r) { - edge_r->crease = (unsigned char) (ee->crease*255.0f); - edge_r->bweight = (unsigned char) (ee->bweight*255.0f); - /* TODO what to do with edge_r->flag? */ - edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER; - if (ee->seam) edge_r->flag |= ME_SEAM; - if (ee->sharp) edge_r->flag |= ME_SHARP; -#if 0 - /* this needs setup of f2 field */ - if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE; -#endif - - edge_r->v1 = (int)ee->v1->tmp.l; - edge_r->v2 = (int)ee->v2->tmp.l; - } -} - -static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r) -{ - EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; - EditFace *ef = em->faces.first; - EditVert *ev; - int i; - - /* store vertexes indices in tmp union */ - for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) - ev->tmp.l = (intptr_t) i; - - for( ; ef; ef = ef->next, ++face_r) { - face_r->mat_nr = ef->mat_nr; - face_r->flag = ef->flag; - - face_r->v1 = (int)ef->v1->tmp.l; - face_r->v2 = (int)ef->v2->tmp.l; - face_r->v3 = (int)ef->v3->tmp.l; - if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l; - else face_r->v4 = 0; - - test_index_face(face_r, NULL, 0, ef->v4?4:3); - } -} - -static void *emDM_getFaceDataArray(DerivedMesh *dm, int type) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditMesh *em= emdm->em; - EditFace *efa; - char *data, *emdata; - void *datalayer; - int index, size; - - datalayer = DM_get_face_data_layer(dm, type); - if(datalayer) - return datalayer; - - /* layers are store per face for editmesh, we convert to a temporary - * data layer array in the derivedmesh when these are requested */ - if(type == CD_MTFACE || type == CD_MCOL) { - index = CustomData_get_layer_index(&em->fdata, type); - - if(index != -1) { - /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */ - size = CustomData_sizeof(type); - - DM_add_face_layer(dm, type, CD_CALLOC, NULL); - index = CustomData_get_layer_index(&dm->faceData, type); - dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY; - - data = datalayer = DM_get_face_data_layer(dm, type); - for(efa=em->faces.first; efa; efa=efa->next, data+=size) { - emdata = CustomData_em_get(&em->fdata, efa->data, type); - memcpy(data, emdata, size); - } - } - } - - return datalayer; -} - -static void emDM_release(DerivedMesh *dm) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - - if (DM_release(dm)) { - if (emdm->vertexCos) { - MEM_freeN(emdm->vertexCos); - MEM_freeN(emdm->vertexNos); - MEM_freeN(emdm->faceNos); - } - - MEM_freeN(emdm); - } -} - -DerivedMesh *editmesh_get_derived(EditMesh *em, float (*vertexCos)[3]) -{ - EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm"); - - DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts), - BLI_countlist(&em->edges), BLI_countlist(&em->faces)); - - emdm->dm.getMinMax = emDM_getMinMax; - - emdm->dm.getNumVerts = emDM_getNumVerts; - emdm->dm.getNumEdges = emDM_getNumEdges; - emdm->dm.getNumFaces = emDM_getNumFaces; - - emdm->dm.getVertCos = emDM_getVertCos; - - emdm->dm.getVert = emDM_getVert; - emdm->dm.getEdge = emDM_getEdge; - emdm->dm.getFace = emDM_getFace; - emdm->dm.copyVertArray = emDM_copyVertArray; - emdm->dm.copyEdgeArray = emDM_copyEdgeArray; - emdm->dm.copyFaceArray = emDM_copyFaceArray; - emdm->dm.getFaceDataArray = emDM_getFaceDataArray; - - emdm->dm.foreachMappedVert = emDM_foreachMappedVert; - emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge; - emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter; - - emdm->dm.drawEdges = emDM_drawEdges; - emdm->dm.drawMappedEdges = emDM_drawMappedEdges; - emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp; - emdm->dm.drawMappedFaces = emDM_drawMappedFaces; - emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex; - emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL; - emdm->dm.drawFacesTex = emDM_drawFacesTex; - emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL; - emdm->dm.drawUVEdges = emDM_drawUVEdges; - - emdm->dm.release = emDM_release; - - emdm->em = em; - emdm->vertexCos = vertexCos; - - if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { - EditVert *eve; - int i; - - DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL); - - for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i) - DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT, - CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT)); - } - - if(vertexCos) { - EditVert *eve; - EditFace *efa; - int totface = BLI_countlist(&em->faces); - int i; - - for (i=0,eve=em->verts.first; eve; eve= eve->next) - eve->tmp.l = (intptr_t) i++; - - emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno"); - emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno"); - - for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) { - float *v1 = vertexCos[(int) efa->v1->tmp.l]; - float *v2 = vertexCos[(int) efa->v2->tmp.l]; - float *v3 = vertexCos[(int) efa->v3->tmp.l]; - float *no = emdm->faceNos[i]; - - if(efa->v4) { - float *v4 = vertexCos[(int) efa->v4->tmp.l]; - - normal_quad_v3( no,v1, v2, v3, v4); - add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no); - } - else { - normal_tri_v3( no,v1, v2, v3); - } - - add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no); - add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no); - add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no); - } - - for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) { - float *no = emdm->vertexNos[i]; - /* following Mesh convention; we use vertex coordinate itself - * for normal in this case */ - if (normalize_v3(no) == 0.0f) { - normalize_v3_v3(no, vertexCos[i]); - } - } - } - - return (DerivedMesh*) emdm; -} - /***/ -DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md) +DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, + ModifierData *md, int build_shapekey_layers) { Mesh *me = ob->data; ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1505,7 +689,11 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier if (!(md->mode&eModifierMode_Realtime)) return NULL; if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; - + + if (build_shapekey_layers && me->key && ob->shapenr <= BLI_countlist(&me->key->block)) { + key_to_mesh(BLI_findlink(&me->key->block, ob->shapenr-1), me); + } + if (mti->type==eModifierTypeType_OnlyDeform) { int numVerts; float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts); @@ -1513,9 +701,16 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0); dm = mesh_create_derived(me, ob, deformedVerts); + if (build_shapekey_layers) + add_shapekey_layers(dm, me, ob); + MEM_freeN(deformedVerts); } else { DerivedMesh *tdm = mesh_create_derived(me, ob, NULL); + + if (build_shapekey_layers) + add_shapekey_layers(tdm, me, ob); + dm = mti->applyModifier(md, ob, tdm, 0, 0); if(tdm != dm) tdm->release(tdm); @@ -1524,30 +719,29 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier return dm; } -static float *get_editmesh_orco_verts(EditMesh *em) +static float *get_editbmesh_orco_verts(BMEditMesh *em) { - EditVert *eve; + BMIter iter; + BMVert *eve; float *orco; int a, totvert; /* these may not really be the orco's, but it's only for preview. * could be solver better once, but isn't simple */ - totvert= 0; - for(eve=em->verts.first; eve; eve=eve->next) - totvert++; + totvert= em->bm->totvert; orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco"); - for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) + eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (a=0; eve; eve=BMIter_Step(&iter), a+=3) VECCOPY(orco+a, eve->co); return orco; } /* orco custom data layer */ - -static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) +static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free) { *free= 0; @@ -1556,7 +750,7 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) *free= 1; if(em) - return (float(*)[3])get_editmesh_orco_verts(em); + return (float(*)[3])get_editbmesh_orco_verts(em); else return (float(*)[3])get_mesh_orco_verts(ob); } @@ -1565,10 +759,12 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) by a more flexible customdata system, but not simple */ if(!em) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); - - if(kb->data) - return kb->data; + if (clmd) { + KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); + + if(kb->data) + return kb->data; + } } return NULL; @@ -1577,13 +773,13 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) return NULL; } -static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer) +static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int layer) { DerivedMesh *dm; float (*orco)[3]; int free; - if(em) dm= CDDM_from_editmesh(em, me); + if(em) dm= CDDM_from_BMEditMesh(em, me, 0); else dm= CDDM_from_mesh(me, ob); orco= get_orco_coords_dm(ob, em, layer, &free); @@ -1598,7 +794,8 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer return dm; } -static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer) +static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm, + DerivedMesh *orcodm, int layer) { float (*orco)[3], (*layerorco)[3]; int totvert, free; @@ -1745,21 +942,28 @@ void vDM_ColorBand_store(ColorBand *coba) static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) { - Mesh *me = ob->data; - MFace *mf = me->mface; + // Mesh *me = ob->data; // UNUSED + 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 */ unsigned char *wtcol; - int i; - + 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_len = BLI_countlist(&ob->defbase); char *defbase_sel = MEM_mallocN(defbase_len * sizeof(char), __func__); int selected = get_selected_defgroups(ob, defbase_sel, defbase_len); int unselected = defbase_len - selected; - wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); + wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap"); - 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*/ calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag); calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag); calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag); @@ -1767,9 +971,110 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag); } + 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++) { + ml = mloop + mp->loopstart; + + for (j=0; j<mp->totloop; j++, ml++, totloop++) { + BLI_array_growone(wlcol); + + calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[ml->v] : ml->v, + (unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag); + } + } + MEM_freeN(defbase_sel); - CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); + 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__); + } + } +} + +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): @@ -1780,14 +1085,15 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, - int needMapping, CustomDataMask dataMask, int index, int useCache) + int needMapping, CustomDataMask dataMask, + int index, int useCache, int build_shapekey_layers) { Mesh *me = ob->data; ModifierData *firstmd, *md; LinkNode *datamasks, *curr; CustomDataMask mask, nextmask; float (*deformedVerts)[3] = NULL; - DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm; + DerivedMesh *dm=NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; int required_mode; int isPrevDeform= FALSE; @@ -1858,7 +1164,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos */ if (deform_r) { *deform_r = CDDM_from_mesh(me, ob); - + + if (build_shapekey_layers) + add_shapekey_layers(dm, me, ob); + if(deformedVerts) { CDDM_apply_vert_coords(*deform_r, deformedVerts); CDDM_calc_normals(*deform_r); @@ -1941,7 +1250,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* if this is not the last modifier in the stack then recalculate the normals * to avoid giving bogus normals to the next modifier see: [#23673] */ - if(isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { + if(dm && isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { /* XXX, this covers bug #23673, but we may need normal calc for other types */ if(dm && dm->type == DM_TYPE_CDDM) { CDDM_apply_vert_coords(dm, deformedVerts); @@ -1962,7 +1271,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* apply vertex coordinates or build a DerivedMesh as necessary */ if(dm) { if(deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); + DerivedMesh *tdm = CDDM_copy(dm, 0); dm->release(dm); dm = tdm; @@ -1972,14 +1281,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } else { dm = CDDM_from_mesh(me, ob); + if (build_shapekey_layers) + add_shapekey_layers(dm, me, ob); + if(deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); CDDM_calc_normals(dm); } - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, dm, draw_flag); - /* Constructive modifiers need to have an origindex * otherwise they wont have anywhere to copy the data from. * @@ -1995,8 +1304,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos range_vni(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); range_vni(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); - range_vni(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0); + range_vni(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); } + + if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) + add_weight_mcol_dm(ob, dm, draw_flag); + } @@ -2013,7 +1326,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* add an origspace layer if needed */ if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE) if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) - DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); + DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache); @@ -2082,7 +1395,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos * DerivedMesh then we need to build one. */ if(dm && deformedVerts) { - finaldm = CDDM_copy(dm); + finaldm = CDDM_copy(dm, 0); dm->release(dm); @@ -2094,13 +1407,23 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } else if(dm) { finaldm = dm; } else { - finaldm = CDDM_from_mesh(me, ob); + int recalc_normals= 0; + finaldm = CDDM_from_mesh(me, ob); + + if(build_shapekey_layers) { + add_shapekey_layers(finaldm, me, ob); + recalc_normals= 1; + } + if(deformedVerts) { CDDM_apply_vert_coords(finaldm, deformedVerts); - CDDM_calc_normals(finaldm); + recalc_normals= 1; } + if(recalc_normals) + CDDM_calc_normals(finaldm); + if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) add_weight_mcol_dm(ob, finaldm, draw_flag); } @@ -2138,21 +1461,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos BLI_linklist_free(datamasks, NULL); } -float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3] +float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3] { - int i, numVerts = *numVerts_r = BLI_countlist(&em->verts); + int i, numVerts = *numVerts_r = em->bm->totvert; float (*cos)[3]; - EditVert *eve; + BMIter iter; + BMVert *eve; + + cos = MEM_mallocN(sizeof(float)*3*numVerts, "vertexcos"); - cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos"); - for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) { + eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (i=0; eve; eve=BMIter_Step(&iter), i++) { VECCOPY(cos[i], eve->co); } return cos; } -int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm) +int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; @@ -2166,7 +1492,7 @@ int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm return 1; } -static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r, +static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r, DerivedMesh **final_r, CustomDataMask dataMask) { @@ -2181,7 +1507,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri modifiers_clearErrors(ob); if(cage_r && cageIndex == -1) { - *cage_r = editmesh_get_derived(em, NULL); + *cage_r = getEditDerivedBMesh(em, ob, NULL); } dm = NULL; @@ -2195,7 +1521,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri md->scene= scene; - if(!editmesh_modifier_is_enabled(scene, md, dm)) + if(!editbmesh_modifier_is_enabled(scene, md, dm)) continue; /* add an orco layer if needed by this modifier */ @@ -2223,7 +1549,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); dm->getVertCos(dm, deformedVerts); } else { - deformedVerts = editmesh_get_vertex_cos(em, &numVerts); + deformedVerts = editbmesh_get_vertex_cos(em, &numVerts); } } @@ -2236,7 +1562,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri /* apply vertex coordinates or build a DerivedMesh as necessary */ if(dm) { if(deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); + DerivedMesh *tdm = CDDM_copy(dm, 0); if(!(cage_r && dm == *cage_r)) dm->release(dm); dm = tdm; @@ -2245,11 +1571,11 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri } else if(cage_r && dm == *cage_r) { /* dm may be changed by this modifier, so we need to copy it */ - dm = CDDM_copy(dm); + dm = CDDM_copy(dm, 0); } } else { - dm = CDDM_from_editmesh(em, ob->data); + dm = CDDM_from_BMEditMesh(em, ob->data, 0); if(deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); @@ -2285,7 +1611,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri if(mask & CD_MASK_ORIGSPACE) if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) - DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); + DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); if (mti->applyModifierEM) ndm = mti->applyModifierEM(md, ob, em, dm); @@ -2307,13 +1633,13 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri if(cage_r && i == cageIndex) { if(dm && deformedVerts) { - *cage_r = CDDM_copy(dm); + *cage_r = CDDM_copy(dm, 0); CDDM_apply_vert_coords(*cage_r, deformedVerts); } else if(dm) { *cage_r = dm; } else { *cage_r = - editmesh_get_derived(em, + getEditDerivedBMesh(em, ob, deformedVerts ? MEM_dupallocN(deformedVerts) : NULL); } } @@ -2326,7 +1652,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri * then we need to build one. */ if(dm && deformedVerts) { - *final_r = CDDM_copy(dm); + *final_r = CDDM_copy(dm, 0); if(!(cage_r && dm == *cage_r)) dm->release(dm); @@ -2337,7 +1663,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri } else if (!deformedVerts && cage_r && *cage_r) { *final_r = *cage_r; } else { - *final_r = editmesh_get_derived(em, deformedVerts); + *final_r = getEditDerivedBMesh(em, ob, deformedVerts); deformedVerts = NULL; } @@ -2384,10 +1710,11 @@ static void clear_mesh_caches(Object *ob) } } -static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) +static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask, + int build_shapekey_layers) { Object *obact = scene->basact?scene->basact->object:NULL; - int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);/* paint_vertsel_test */ + int editing = paint_facesel_test(ob); /* weight paint and face select need original indices because of selection buffer drawing */ int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT))); @@ -2395,7 +1722,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1, - needMapping, dataMask, -1, 1); + needMapping, dataMask, -1, 1, build_shapekey_layers); DM_set_object_boundbox (ob, ob->derivedFinal); @@ -2404,7 +1731,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) ob->lastDataMask = dataMask; } -static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) +static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) { clear_mesh_caches(obedit); @@ -2421,7 +1748,7 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust em->derivedCage = NULL; } - editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask); + editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask); DM_set_object_boundbox (obedit, em->derivedFinal); em->lastDataMask = dataMask; @@ -2429,12 +1756,13 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust em->derivedCage->needsFree = 0; } -void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask) +void makeDerivedMesh(Scene *scene, Object *ob, BMEditMesh *em, + CustomDataMask dataMask, int build_shapekey_layers) { if (em) { - editmesh_build_data(scene, ob, em, dataMask); + editbmesh_build_data(scene, ob, em, dataMask); } else { - mesh_build_data(scene, ob, dataMask); + mesh_build_data(scene, ob, dataMask, build_shapekey_layers); } } @@ -2446,7 +1774,7 @@ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dat * the data we need, rebuild the derived mesh */ if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask) - mesh_build_data(scene, ob, dataMask); + mesh_build_data(scene, ob, dataMask, 0); return ob->derivedFinal; } @@ -2457,7 +1785,7 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da * the data we need, rebuild the derived mesh */ if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask) - mesh_build_data(scene, ob, dataMask); + mesh_build_data(scene, ob, dataMask, 0); return ob->derivedDeform; } @@ -2466,7 +1794,7 @@ DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0, 0); return final; } @@ -2475,7 +1803,7 @@ DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDa { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0); + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0, 0); return final; } @@ -2484,7 +1812,7 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0); return final; } @@ -2494,7 +1822,7 @@ DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*ver { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0, 0); return final; } @@ -2504,7 +1832,7 @@ DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*ve { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0, 0); return final; } @@ -2514,7 +1842,7 @@ DerivedMesh *mesh_create_derived_physics(Scene *scene, Object *ob, float (*vertC { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0, 0); return final; } @@ -2525,14 +1853,14 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob, { DerivedMesh *final; - mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0); + mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0, 0); return final; } /***/ -DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r, +DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **final_r, CustomDataMask dataMask) { /* if there's no derived mesh or the last data mask used doesn't include @@ -2540,27 +1868,27 @@ DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, E */ if(!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) - editmesh_build_data(scene, obedit, em, dataMask); + editbmesh_build_data(scene, obedit, em, dataMask); *final_r = em->derivedFinal; return em->derivedCage; } -DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) +DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) { /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh */ if(!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) - editmesh_build_data(scene, obedit, em, dataMask); + editbmesh_build_data(scene, obedit, em, dataMask); return em->derivedCage; } -DerivedMesh *editmesh_get_derived_base(Object *UNUSED(obedit), EditMesh *em) +DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em) { - return editmesh_get_derived(em, NULL); + return getEditDerivedBMesh(em, obedit, NULL); } @@ -2600,7 +1928,7 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) if(ob->type!=OB_MESH || me->totvert==0) return NULL; - dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH|CD_MASK_ORIGINDEX); vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map"); if(dm->foreachMappedVert) { @@ -2729,15 +2057,15 @@ void DM_add_tangent_layer(DerivedMesh *dm) if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) return; - nors = dm->getFaceDataArray(dm, CD_NORMAL); + nors = dm->getTessFaceDataArray(dm, CD_NORMAL); /* check we have all the needed layers */ totvert= dm->getNumVerts(dm); - totface= dm->getNumFaces(dm); + totface= dm->getNumTessFaces(dm); mvert= dm->getVertArray(dm); - mface= dm->getFaceArray(dm); - mtface= dm->getFaceDataArray(dm, CD_MTFACE); + mface= dm->getTessFaceArray(dm); + mtface= dm->getTessFaceDataArray(dm, CD_MTFACE); if(!mtface) { orco= dm->getVertDataArray(dm, CD_ORCO); @@ -2746,8 +2074,8 @@ void DM_add_tangent_layer(DerivedMesh *dm) } /* create tangent layer */ - DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL); - tangent= DM_get_face_data_layer(dm, CD_TANGENT); + DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL); + tangent= DM_get_tessface_data_layer(dm, CD_TANGENT); /* allocate some space */ arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena"); @@ -2868,15 +2196,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, memset(attribs, 0, sizeof(DMVertexAttribs)); vdata = &dm->vertData; - fdata = &dm->faceData; - - /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we - * can use offsets instead */ - if(dm->release == emDM_release) - tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata; - else - tfdata = fdata; - + fdata = tfdata = dm->getTessFaceDataLayout(dm); + /* add a tangent layer if necessary */ for(b = 0; b < gattribs->totlayer; b++) if(gattribs->layer[b].type == CD_TANGENT) @@ -2898,8 +2219,26 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, attribs->tface[a].array = tfdata->layers[layer].data; attribs->tface[a].emOffset = tfdata->layers[layer].offset; attribs->tface[a].glIndex = gattribs->layer[b].glindex; - attribs->tface[a].glTexco = gattribs->layer[b].gltexco; - } + } /*else { + int player; + CustomData *pdata = dm->getFaceDataLayout(dm); + + if(gattribs->layer[b].name[0]) + player = CustomData_get_named_layer_index(pdata, CD_MTEXPOLY, + gattribs->layer[b].name); + else + player = CustomData_get_active_layer_index(pdata, CD_MTEXPOLY); + + if (player != -1) { + a = attribs->tottface++; + + attribs->tface[a].array = NULL; + attribs->tface[a].emOffset = pdata->layers[layer].offset; + attribs->tface[a].glIndex = gattribs->layer[b].glindex; + attribs->tface[a].glTexco = gattribs->layer[b].gltexco; + + } + }*/ } else if(gattribs->layer[b].type == CD_MCOL) { /* vertex colors */ |