diff options
Diffstat (limited to 'source/blender/blenkernel/intern/DerivedMesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 822 |
1 files changed, 678 insertions, 144 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 27aeeb95903..573edb78687 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" #include "BKE_deform.h" #ifdef WITH_GAMEENGINE @@ -78,6 +82,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); + /////////////////////////////////// /////////////////////////////////// @@ -109,20 +116,48 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm) return medge; } -static MFace *dm_getFaceArray(DerivedMesh *dm) +static MFace *dm_getTessFaceArray(DerivedMesh *dm) { MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE); 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->getNumLoops(dm)); + 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->getNumPolys(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), @@ -145,41 +180,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->getNumLoops(dm), + "dm_dupLoopArray tmp"); + + if(tmp) dm->copyLoopArray(dm, tmp); + + return tmp; +} + +static MPoly *dm_dupPolyArray(DerivedMesh *dm) +{ + MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumPolys(dm), + "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_getTessFaceCData(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_getTessFaceArray; + 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_getTessFaceCData; + dm->getLoopDataLayout = dm_getLoopCData; + dm->getPolyDataLayout = dm_getPolyCData; dm->getVertData = DM_get_vert_data; dm->getEdgeData = DM_get_edge_data; - dm->getFaceData = DM_get_face_data; + dm->getTessFaceData = DM_get_tessface_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 numTessFaces, int numLoops, int numPolys) { dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; - dm->numFaceData = numFaces; + dm->numTessFaceData = numTessFaces; + dm->numLoopData = numLoops; + dm->numPolyData = numPolys; DM_init_funcs(dm); @@ -188,19 +280,26 @@ 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 numTessFaces, + int numLoops, int numPolys) { CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, CD_CALLOC, numVerts); CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH, CD_CALLOC, numEdges); CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numFaces); + CD_CALLOC, numTessFaces); + 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->numTessFaceData = numTessFaces; + dm->numLoopData = numLoops; + dm->numPolyData = numPolys; DM_init_funcs(dm); @@ -214,63 +313,152 @@ int DM_release(DerivedMesh *dm) GPU_drawobject_free( dm ); CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); - CustomData_free(&dm->faceData, dm->numFaceData); + CustomData_free(&dm->faceData, dm->numTessFaceData); + CustomData_free(&dm->loopData, dm->numLoopData); + CustomData_free(&dm->polyData, dm->numPolyData); return 1; } else { 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->faceData, dm->numTessFaceData); + 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_free(&target->loopData, source->numLoopData); + CustomData_free(&target->polyData, source->numPolyData); + + CustomData_copy(&source->loopData, &target->loopData, CD_MASK_DERIVEDMESH, CD_DUPLICATE, source->numLoopData); + CustomData_copy(&source->polyData, &target->polyData, CD_MASK_DERIVEDMESH, CD_DUPLICATE, 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); + } +} + +/* note: until all modifiers can take MPoly's as input, + * use this at the start of modifiers */ +void DM_ensure_tessface(DerivedMesh *dm) +{ + const int numTessFaces = dm->getNumTessFaces(dm); + const int numPolys = dm->getNumPolys(dm); + + if ( (numTessFaces == 0) && (numPolys != 0)) { + dm->recalcTesselation(dm); + + if (dm->getNumTessFaces(dm) != 0) { + /* printf("info %s: polys -> ngons calculated\n", __func__); */ + } + else { + printf("warning %s: could not create tessfaces from %d polygons, dm->type=%d\n", + __func__, numPolys, dm->type); + } + } +} + +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 */ /* UNUSED */, 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); + totloop = tmp.totloop = dm->getNumLoops(dm); + totpoly = tmp.totpoly = dm->getNumPolys(dm); 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 uid; + + if (ob) { + kb = BLI_findlink(&me->key->block, ob->shapenr-1); + if (kb) { + uid = kb->uid; + } + else { + printf("%s: error - could not find active shapekey %d!\n", + __func__, ob->shapenr-1); + uid = INT_MAX; + } + } + else { + /*if no object, set to INT_MAX so we don't mess up any shapekey layers*/ + uid = INT_MAX; + } + + shapekey_layers_to_keyblocks(dm, me, uid); + 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)) CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert); 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); + 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); } } - mesh_update_customdata_pointers(&tmp); + /* yes, must be before _and_ after tesselate */ + mesh_update_customdata_pointers(&tmp, TRUE); + + BKE_mesh_tessface_calc(&tmp); 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; } @@ -315,9 +503,19 @@ 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->numTessFaceData); +} + +void DM_add_loop_layer(DerivedMesh *dm, int type, int alloctype, void *layer) { - CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData); + CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData); +} + +void DM_add_poly_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) @@ -330,7 +528,7 @@ void *DM_get_edge_data(DerivedMesh *dm, int index, int type) return CustomData_get(&dm->edgeData, index, type); } -void *DM_get_face_data(DerivedMesh *dm, int index, int type) +void *DM_get_tessface_data(DerivedMesh *dm, int index, int type) { return CustomData_get(&dm->faceData, index, type); } @@ -351,14 +549,24 @@ 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); + if (type == CD_MFACE) + return dm->getTessFaceArray(dm); return CustomData_get_layer(&dm->faceData, type); } +void *DM_get_poly_data_layer(DerivedMesh *dm, int type) +{ + return CustomData_get_layer(&dm->polyData, type); +} + +void *DM_get_loop_data_layer(DerivedMesh *dm, int type) +{ + return CustomData_get_layer(&dm->loopData, type); +} + void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data) { CustomData_set(&dm->vertData, index, type, data); @@ -369,7 +577,7 @@ void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data) CustomData_set(&dm->edgeData, index, type, data); } -void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data) +void DM_set_tessface_data(DerivedMesh *dm, int index, int type, void *data) { CustomData_set(&dm->faceData, index, type, data); } @@ -388,13 +596,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_poly_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); @@ -405,11 +627,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_poly_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) @@ -427,7 +659,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) @@ -436,13 +668,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_poly_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); @@ -458,17 +705,25 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) return dm; } -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); DerivedMesh *dm; + KeyBlock *kb; md->scene= scene; if (!(md->mode&eModifierMode_Realtime)) return NULL; if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; - + + if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr-1))) { + key_to_mesh(kb, me); + } + if (mti->type==eModifierTypeType_OnlyDeform) { int numVerts; float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts); @@ -476,9 +731,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); @@ -487,22 +749,22 @@ 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 = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (a=0; eve; eve=BM_iter_step(&iter), a+=3) { copy_v3_v3(orco+a, eve->co); } @@ -510,8 +772,7 @@ static float *get_editmesh_orco_verts(EditMesh *em) } /* 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; @@ -520,7 +781,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); } @@ -541,13 +802,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, FALSE, FALSE); else dm= CDDM_from_mesh(me, ob); orco= get_orco_coords_dm(ob, em, layer, &free); @@ -562,7 +823,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; @@ -775,19 +1037,35 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, { ColorBand *coba= stored_cb; /* warning, not a local var */ - MFace *mf = dm->getFaceArray(dm); - int numFaces = dm->getNumFaces(dm); - int numVerts = dm->getNumVerts(dm); unsigned char *wtcol_v; - unsigned char *wtcol_f = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); - int i; +#if 0 /* See coment below. */ + unsigned char *wtcol_f = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL); +#endif + unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_WEIGHT_MLOOPCOL); +#if 0 /* See coment below. */ + MFace *mf = dm->getTessFaceArray(dm); +#endif + MLoop *mloop = dm->getLoopArray(dm), *ml; + MPoly *mp = dm->getPolyArray(dm); + int numFaces = dm->getNumTessFaces(dm); + int numVerts = dm->getNumVerts(dm); + int totloop; + int i, j; +#if 0 /* See comment below */ /* If no CD_WEIGHT_MCOL existed yet, add a new one! */ if (!wtcol_f) wtcol_f = CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces); if (wtcol_f) { unsigned char *wtcol_f_step = wtcol_f; +# else + /* XXX We have to create a CD_WEIGHT_MCOL, else it might sigsev (after a SubSurf mod, eg)... */ + if(!dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL)) + CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces); + + { +#endif /* Weights are given by caller. */ if (weights) { @@ -813,7 +1091,13 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); /* Now copy colors in all face verts. */ + /*first add colors to the tesselation faces*/ + /* XXX Why update that layer? We have to update WEIGHT_MLOOPCOL anyway, + * and tesselation recreates mface layers from mloop/mpoly ones, so no + * need to fill WEIGHT_MCOL here. */ +#if 0 for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) { + /*origindex being NULL means we're operating on original mesh data*/ #if 0 unsigned int fidx= mf->v4 ? 3:2; @@ -830,13 +1114,137 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, do { copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], - (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); + (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); } while (fidx--); } +#endif + /*now add to loops, so the data can be passed through the modifier stack*/ + /* If no CD_WEIGHT_MLOOPCOL existed yet, we have to add a new one! */ + if (!wtcol_l) { + BLI_array_declare(wtcol_l); + totloop = 0; + for (i=0; i<dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + + BLI_array_growitems(wtcol_l, mp->totloop); + for (j = 0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); + } + } + CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); + } + else { + totloop = 0; + for (i=0; i < dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + + for (j=0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); + } + } + } MEM_freeN(wtcol_v); } } + +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 i; + const size_t shape_alloc_len = sizeof(float) * 3 * me->totvert; + + if (!me->key) + return; + + /* ensure we can use mesh vertex count for derived mesh custom data */ + if (me->totvert != dm->getNumVerts(dm)) { + fprintf(stderr, + "%s: vertex size mismatch (mesh/dm) '%s' (%d != %d)\n", + __func__, me->id.name+2, me->totvert, dm->getNumVerts(dm)); + return; + } + + for (i=0, kb=key->block.first; kb; kb=kb->next, i++) { + int ci; + float *array; + + if (me->totvert != kb->totelem) { + fprintf(stderr, + "%s: vertex size mismatch (mesh/keyblock) '%s' (%d != %d)\n", + __func__, me->id.name+2, me->totvert, kb->totelem); + array = MEM_callocN(shape_alloc_len, __func__); + } + else { + array = MEM_mallocN(shape_alloc_len, __func__); + memcpy(array, kb->data, shape_alloc_len); + } + + CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_ASSIGN, array, dm->numVertData, kb->name); + ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i); + + dm->vertData.layers[ci].uid = kb->uid; + } +} + /* new value for useDeform -1 (hack for the gameengine): * - apply only the modifier stack of the object, skipping the virtual modifiers, * - don't apply the key @@ -845,14 +1253,15 @@ void DM_update_weight_mcol(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, *previewmd = NULL; LinkNode *datamasks, *curr; CustomDataMask mask, nextmask, append_mask = 0; 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; @@ -940,7 +1349,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); @@ -1054,6 +1466,9 @@ 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); @@ -1073,11 +1488,11 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* calc */ DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); - range_vn_i(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0); + range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); } } @@ -1094,9 +1509,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); /* 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); + if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE_MLOOP) { + if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) { + DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL); + DM_init_origspace(dm); + } + } ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache); @@ -1196,10 +1614,21 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); #endif } 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); + recalc_normals= 1; + } + + if(recalc_normals) { CDDM_calc_normals(finaldm); } @@ -1228,6 +1657,36 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } #endif /* WITH_GAMEENGINE */ + { + /* calculating normals can re-calculate tessfaces in some cases */ + int num_tessface = finaldm->getNumTessFaces(finaldm); + /* --------------------------------------------------------------------- */ + /* First calculate the polygon and vertex normals, re-tesselation + * copies these into the tessface's normal layer */ + + + /* comment because this causes a bug when deform is applied after a + * bug when applied after a subsurf modifier (SubSurf -> Cast) for eg, + * it also looks like this isn't even needed since code above recalc's + * normals - campbell */ +#if 0 + finaldm->calcNormals(finaldm); +#endif + + /* Re-tesselation is necessary to push render data (uvs, textures, colors) + * from loops and polys onto the tessfaces. This may be currently be + * redundantin cases where the render mode doesn't use these inputs, but + * ideally eventually tesselation would happen on-demand, and this is one + * of the primary places it would be needed. */ + if (num_tessface == 0 && finaldm->getNumTessFaces(finaldm) == 0) { + finaldm->recalcTesselation(finaldm); + } + /* Need to watch this, it can cause issues, see bug [#29338] */ + /* take care with this block, we really need testing frameworks */ + /* --------------------------------------------------------------------- */ + } + + *final_r = finaldm; if(orcodm) @@ -1241,21 +1700,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 = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (i=0; eve; eve=BM_iter_step(&iter), i++) { copy_v3_v3(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; @@ -1269,7 +1731,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) { @@ -1284,7 +1746,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; @@ -1298,7 +1760,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 */ @@ -1326,7 +1788,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); } } @@ -1352,7 +1814,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri } } else { - dm = CDDM_from_editmesh(em, ob->data); + dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE); if(deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); @@ -1386,9 +1848,12 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX); - if(mask & CD_MASK_ORIGSPACE) - if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) - DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); + if(mask & CD_MASK_ORIGSPACE_MLOOP) { + if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) { + DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL); + DM_init_origspace(dm); + } + } if (mti->applyModifierEM) ndm = mti->applyModifierEM(md, ob, em, dm); @@ -1416,7 +1881,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri *cage_r = dm; } else { *cage_r = - editmesh_get_derived(em, + getEditDerivedBMesh(em, ob, deformedVerts ? MEM_dupallocN(deformedVerts) : NULL); } } @@ -1434,16 +1899,26 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri if(!(cage_r && dm == *cage_r)) dm->release(dm); CDDM_apply_vert_coords(*final_r, deformedVerts); - CDDM_calc_normals(*final_r); + CDDM_calc_normals(*final_r); /* was CDDM_calc_normals_mapping - campbell */ } else if (dm) { *final_r = dm; + (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */ } else if (!deformedVerts && cage_r && *cage_r) { *final_r = *cage_r; + (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */ } else { - *final_r = editmesh_get_derived(em, deformedVerts); + *final_r = getEditDerivedBMesh(em, ob, deformedVerts); deformedVerts = NULL; + (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */ } + /* --- */ + /* BMESH_ONLY, ensure tessface's used for drawing, + * but dont recalculate if the last modifier in the stack gives us tessfaces */ + DM_ensure_tessface(*final_r); + if (cage_r && (*cage_r != *final_r)) DM_ensure_tessface(*cage_r); + /* --- */ + /* add an orco layer if needed */ if(dataMask & CD_MASK_ORCO) add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO); @@ -1487,18 +1962,19 @@ 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))); + int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT))); clear_mesh_caches(ob); 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); @@ -1507,7 +1983,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); @@ -1524,7 +2000,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; @@ -1532,12 +2008,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); } } @@ -1549,7 +2026,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; } @@ -1560,7 +2037,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; } @@ -1569,7 +2046,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; } @@ -1578,7 +2055,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; } @@ -1587,7 +2064,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; } @@ -1597,7 +2074,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; } @@ -1607,7 +2084,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; } @@ -1617,7 +2094,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; } @@ -1628,14 +2105,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 @@ -1643,27 +2120,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); } @@ -1703,7 +2180,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) { @@ -1733,7 +2210,7 @@ typedef struct MVert * mvert; // vertices & normals float (*orco)[3]; float (*tangent)[4]; // destination - int numFaces; + int numTessFaces; } SGLSLMeshToTangent; @@ -1743,7 +2220,7 @@ typedef struct static int GetNumFaces(const SMikkTSpaceContext * pContext) { SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; - return pMesh->numFaces; + return pMesh->numTessFaces; } static int GetNumVertsOfFace(const SMikkTSpaceContext * pContext, const int face_num) @@ -1832,15 +2309,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); @@ -1849,8 +2326,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"); @@ -1870,7 +2347,7 @@ void DM_add_tangent_layer(DerivedMesh *dm) mesh2tangent.mvert = mvert; mesh2tangent.orco = orco; mesh2tangent.tangent = tangent; - mesh2tangent.numFaces = totface; + mesh2tangent.numTessFaces = totface; sContext.m_pUserData = &mesh2tangent; sContext.m_pInterface = &sInterface; @@ -1963,11 +2440,11 @@ void DM_add_tangent_layer(DerivedMesh *dm) void DM_calc_auto_bump_scale(DerivedMesh *dm) { /* int totvert= dm->getNumVerts(dm); */ /* UNUSED */ - int totface= dm->getNumFaces(dm); + int totface= dm->getNumTessFaces(dm); MVert * mvert = dm->getVertArray(dm); - MFace * mface = dm->getFaceArray(dm); - MTFace * mtface = dm->getFaceDataArray(dm, CD_MTFACE); + MFace * mface = dm->getTessFaceArray(dm); + MTFace * mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); if(mtface) { @@ -2124,15 +2601,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->type == DM_TYPE_EDITMESH) - tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata; - else - tfdata = fdata; - + fdata = tfdata = dm->getTessFaceDataLayout(dm); + /* calc auto bump scale if necessary */ if(dm->auto_bump_scale<=0.0f) DM_calc_auto_bump_scale(dm); @@ -2158,8 +2628,30 @@ 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; + /* attribs->tface[a].glTexco = gattribs->layer[b].gltexco; */ /* BMESH_TODO, trunk has this but not bmesh, need to investigate whats going on here - campbell */ + } + /* BMESH ONLY, may need to get this working?, otherwise remove */ + /* else { + int player; + CustomData *pdata = dm->getPolyDataLayout(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 */ @@ -2223,6 +2715,15 @@ void DM_set_object_boundbox(Object *ob, DerivedMesh *dm) /* --- NAVMESH (begin) --- */ #ifdef WITH_GAMEENGINE +/* BMESH_TODO, navmesh is not working right currently + * All tools set this as MPoly data, but derived mesh currently draws from MFace (tessface) + * + * Proposed solution, rather then copy CD_RECAST into the MFace array, + * use ORIGINDEX to get the original poly index and then get the CD_RECAST + * data from the original me->mpoly layer. - campbell + */ + + BM_INLINE int navmesh_bit(int a, int b) { return (a & (1 << b)) >> b; @@ -2262,7 +2763,7 @@ static void navmesh_drawColored(DerivedMesh *dm) DEBUG_VBO( "Using legacy code. drawNavMeshColored\n" ); //glShadeModel(GL_SMOOTH); glBegin(glmode = GL_QUADS); - for(a = 0; a < dm->numFaceData; a++, mface++) { + for(a = 0; a < dm->numTessFaceData; a++, mface++) { int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; int pi = polygonIdx[a]; if (pi <= 0) { @@ -2315,7 +2816,7 @@ static void navmesh_DM_drawFacesSolid(DerivedMesh *dm, static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm) { DerivedMesh *result; - int maxFaces = dm->getNumFaces(dm); + int maxFaces = dm->getNumPolys(dm); int *recastData; int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; float* verts=NULL; @@ -2393,6 +2894,30 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm) /* --- NAVMESH (end) --- */ +void DM_init_origspace(DerivedMesh *dm) +{ + static float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; + + OrigSpaceLoop *lof_array = CustomData_get_layer(&dm->loopData, CD_ORIGSPACE_MLOOP); + OrigSpaceLoop *lof; + const int numpoly = dm->getNumPolys(dm); + // const int numloop = dm->getNumLoops(dm); + MPoly *mp = dm->getPolyArray(dm); + int i, j; + + for (i = 0; i < numpoly; i++, mp++) { + /* only quads/tri's for now */ + if (mp->totloop == 3 || mp->totloop == 4) { + lof = lof_array + mp->loopstart; + for (j = 0; j < mp->totloop; j++, lof++) { + copy_v2_v2(lof->uv, default_osf[j]); + } + } + } +} + + + /* derivedmesh info printing function, * to help track down differences DM output */ @@ -2429,26 +2954,35 @@ char *DM_debug_info(DerivedMesh *dm) BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)dm); switch (dm->type) { case DM_TYPE_CDDM: tstr = "DM_TYPE_CDDM"; break; - case DM_TYPE_EDITMESH: tstr = "DM_TYPE_EDITMESH"; break; + case DM_TYPE_EDITBMESH: tstr = "DM_TYPE_EDITMESH"; break; case DM_TYPE_CCGDM: tstr = "DM_TYPE_CCGDM"; break; default: tstr = "UNKNOWN"; break; } BLI_dynstr_appendf(dynstr, " 'type': '%s',\n", tstr); BLI_dynstr_appendf(dynstr, " 'numVertData': %d,\n", dm->numVertData); BLI_dynstr_appendf(dynstr, " 'numEdgeData': %d,\n", dm->numEdgeData); - BLI_dynstr_appendf(dynstr, " 'numFaceData': %d,\n", dm->numFaceData); + BLI_dynstr_appendf(dynstr, " 'numTessFaceData': %d,\n", dm->numTessFaceData); + BLI_dynstr_appendf(dynstr, " 'numPolyData': %d,\n", dm->numPolyData); BLI_dynstr_appendf(dynstr, " 'deformedOnly': %d,\n", dm->deformedOnly); BLI_dynstr_appendf(dynstr, " 'vertexLayers': (\n"); dm_debug_info_layers(dynstr, dm, dm->getVertDataArray); BLI_dynstr_appendf(dynstr, " ),\n"); + BLI_dynstr_appendf(dynstr, " 'loopLayers': (\n"); + dm_debug_info_layers(dynstr, dm, DM_get_loop_data_layer); + BLI_dynstr_appendf(dynstr, " ),\n"); + BLI_dynstr_appendf(dynstr, " 'edgeLayers': (\n"); dm_debug_info_layers(dynstr, dm, dm->getEdgeDataArray); BLI_dynstr_appendf(dynstr, " ),\n"); - BLI_dynstr_appendf(dynstr, " 'faceLayers': (\n"); - dm_debug_info_layers(dynstr, dm, dm->getFaceDataArray); + BLI_dynstr_appendf(dynstr, " 'tessFaceLayers': (\n"); + dm_debug_info_layers(dynstr, dm, dm->getTessFaceDataArray); + BLI_dynstr_appendf(dynstr, " ),\n"); + + BLI_dynstr_appendf(dynstr, " 'polyLayers': (\n"); + dm_debug_info_layers(dynstr, dm, DM_get_poly_data_layer); BLI_dynstr_appendf(dynstr, " ),\n"); BLI_dynstr_appendf(dynstr, "}\n"); |