diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 821c963de1c..01f863a4c2e 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -78,6 +78,12 @@ typedef struct DMGridAdjacency { int rotation[4]; } DMGridAdjacency; +typedef enum DerivedMeshType { + DM_TYPE_CDDM, + DM_TYPE_EDITMESH, + DM_TYPE_CCGDM +} DerivedMeshType; + typedef struct DerivedMesh DerivedMesh; struct DerivedMesh { /* Private DerivedMesh data, only for internal DerivedMesh use */ @@ -87,6 +93,7 @@ struct DerivedMesh { int deformedOnly; /* set by modifier stack if only deformed from original */ BVHCache bvhCache; struct GPUDrawObject *drawObject; + DerivedMeshType type; /* Misc. Queries */ @@ -329,12 +336,14 @@ void DM_init_funcs(DerivedMesh *dm); * of vertices, edges and faces (doesn't allocate memory for them, just * sets up the custom data layers) */ -void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces); +void DM_init(DerivedMesh *dm, DerivedMeshType type, + int numVerts, int numEdges, int numFaces); /* utility function to initialise a DerivedMesh for the desired number * of vertices, edges and faces, with a layer setup copied from source */ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, + DerivedMeshType type, int numVerts, int numEdges, int numFaces); /* utility function to release a DerivedMesh's layers diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a614404dc5e..b54f90880b8 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -184,9 +184,10 @@ void DM_init_funcs(DerivedMesh *dm) bvhcache_init(&dm->bvhCache); } -void DM_init(DerivedMesh *dm, +void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, int numFaces) { + dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; @@ -196,7 +197,7 @@ void DM_init(DerivedMesh *dm, dm->needsFree = 1; } -void DM_from_template(DerivedMesh *dm, DerivedMesh *source, +void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, int numVerts, int numEdges, int numFaces) { CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, @@ -206,6 +207,7 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, CD_CALLOC, numFaces); + dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; @@ -336,16 +338,25 @@ void *DM_get_face_data(DerivedMesh *dm, int index, int type) void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { + if(type == CD_MVERT) + return dm->getVertArray(dm); + return CustomData_get_layer(&dm->vertData, type); } void *DM_get_edge_data_layer(DerivedMesh *dm, int type) { + if(type == CD_MEDGE) + return dm->getEdgeArray(dm); + return CustomData_get_layer(&dm->edgeData, type); } void *DM_get_face_data_layer(DerivedMesh *dm, int type) { + if(type == CD_MFACE) + return dm->getFaceArray(dm); + return CustomData_get_layer(&dm->faceData, type); } @@ -1450,7 +1461,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob, { EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm"); - DM_init(&emdm->dm, BLI_countlist(&em->verts), + DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts), BLI_countlist(&em->edges), BLI_countlist(&em->faces)); emdm->dm.getMinMax = emDM_getMinMax; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 32cde20eb6b..e9a1021a203 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1406,7 +1406,7 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces) CDDerivedMesh *cddm = cdDM_create("CDDM_new dm"); DerivedMesh *dm = &cddm->dm; - DM_init(dm, numVerts, numEdges, numFaces); + DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces); CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); @@ -1432,7 +1432,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) /* this does a referenced copy, with an exception for fluidsim */ - DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface); + DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface); dm->deformedOnly = 1; @@ -1565,7 +1565,7 @@ DerivedMesh *CDDM_copy(DerivedMesh *source) source->getFaceDataArray(source, CD_ORIGINDEX); /* this initializes dm, and copies all non mvert/medge/mface layers */ - DM_from_template(dm, source, numVerts, numEdges, numFaces); + DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces); dm->deformedOnly = source->deformedOnly; CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); @@ -1591,7 +1591,7 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, DerivedMesh *dm = &cddm->dm; /* this does a copy of all non mvert/medge/mface layers */ - DM_from_template(dm, source, numVerts, numEdges, numFaces); + DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces); /* now add mvert/medge/mface layers */ CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 36e00cc8f3c..e6b086e994f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -144,12 +144,15 @@ static int is_last_displist(Object *ob) return 0; } -static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco) +/* returns a derived mesh if dm == NULL, for deforming modifiers that need it */ +static DerivedMesh *get_dm(Scene *scene, Object *ob, EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) { - DerivedMesh *dm= NULL; + if(dm) + return dm; if(ob->type==OB_MESH) { - dm = CDDM_from_mesh((Mesh*)(ob->data), ob); + if(em) dm= CDDM_from_editmesh(em, ob->data); + else dm = CDDM_from_mesh((Mesh*)(ob->data), ob); if(vertexCos) { CDDM_apply_vert_coords(dm, vertexCos); @@ -185,6 +188,26 @@ static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos) return dm; } +/* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */ +static DerivedMesh *get_cddm(Scene *scene, Object *ob, EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) +{ + if(dm && dm->type == DM_TYPE_CDDM) + return dm; + + if(!dm) { + dm= get_dm(scene, ob, em, dm, vertexCos, 0); + } + else { + dm= CDDM_copy(dm); + CDDM_apply_vert_coords(dm, vertexCos); + } + + if(dm) + CDDM_calc_normals(dm); + + return dm; +} + /***/ static int noneModifier_isDisabled(ModifierData *md, int userRenderParams) @@ -3770,37 +3793,26 @@ static void displaceModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm; - - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - else return; - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + DerivedMesh *dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos); displaceModifier_do((DisplaceModifierData *)md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static void displaceModifier_deformVertsEM( ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm; - - if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_editmesh(editData, ob->data); - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + DerivedMesh *dm= get_cddm(md->scene, ob, editData, derivedData, vertexCos); displaceModifier_do((DisplaceModifierData *)md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } /* UVProject */ @@ -4447,36 +4459,26 @@ static void smoothModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm; - - if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_mesh(ob->data, ob); - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0); smoothModifier_do((SmoothModifierData *)md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static void smoothModifier_deformVertsEM( ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm; - - if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_editmesh(editData, ob->data); - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + DerivedMesh *dm= get_dm(md->scene, ob, editData, derivedData, NULL, 0); smoothModifier_do((SmoothModifierData *)md, ob, dm, vertexCos, numVerts); - dm->release(dm); + if(dm != derivedData) + dm->release(dm); } /* Cast */ @@ -5027,38 +5029,34 @@ static void castModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm = derivedData; + DerivedMesh *dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0); CastModifierData *cmd = (CastModifierData *)md; - if (!dm && ob->type == OB_MESH) - dm = CDDM_from_mesh(ob->data, ob); - if (cmd->type == MOD_CAST_TYPE_CUBOID) { castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts); } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */ castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts); } - if (!derivedData && dm) dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static void castModifier_deformVertsEM( ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = derivedData; + DerivedMesh *dm = get_dm(md->scene, ob, editData, derivedData, NULL, 0); CastModifierData *cmd = (CastModifierData *)md; - if (!dm && ob->type == OB_MESH) - dm = CDDM_from_editmesh(editData, ob->data); - if (cmd->type == MOD_CAST_TYPE_CUBOID) { castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts); } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */ castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts); } - if (!derivedData && dm) dm->release(dm); + if(dm != derivedData) + dm->release(dm); } /* Wave */ @@ -5429,45 +5427,36 @@ static void waveModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm; + DerivedMesh *dm= derivedData; WaveModifierData *wmd = (WaveModifierData *)md; - if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM)) - dm = derivedData; - else if(derivedData) dm = derivedData; - else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - else return; - - if(wmd->flag & MOD_WAVE_NORM) { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); - } + if(wmd->flag & MOD_WAVE_NORM) + dm= get_cddm(md->scene, ob, NULL, dm, vertexCos); + else if(wmd->texture || wmd->defgrp_name[0]) + dm= get_dm(md->scene, ob, NULL, dm, NULL, 0); waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); - if(dm != derivedData) dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static void waveModifier_deformVertsEM( ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm; + DerivedMesh *dm= derivedData; WaveModifierData *wmd = (WaveModifierData *)md; - if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM)) - dm = derivedData; - else if(derivedData) dm = CDDM_copy(derivedData); - else dm = CDDM_from_editmesh(editData, ob->data); - - if(wmd->flag & MOD_WAVE_NORM) { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); - } + if(wmd->flag & MOD_WAVE_NORM) + dm= get_cddm(md->scene, ob, editData, dm, vertexCos); + else if(wmd->texture || wmd->defgrp_name[0]) + dm= get_dm(md->scene, ob, editData, dm, NULL, 0); waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); - if(dm != derivedData) dm->release(dm); + if(dm != derivedData) + dm->release(dm); } /* Armature */ @@ -6289,18 +6278,12 @@ static void smokeModifier_deformVerts( float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { SmokeModifierData *smd = (SmokeModifierData*) md; - DerivedMesh *dm = NULL; - - if(derivedData) dm = derivedData; - else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - else return; - - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + DerivedMesh *dm = dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos); smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc); - if(dm != derivedData) dm->release(dm); + if(dm != derivedData) + dm->release(dm); } static int smokeModifier_dependsOnTime(ModifierData *md) @@ -6701,7 +6684,7 @@ static void surfaceModifier_deformVerts( /* if possible use/create DerivedMesh */ if(derivedData) surmd->dm = CDDM_copy(derivedData); - else surmd->dm = get_original_dm(md->scene, ob, NULL, 0); + else surmd->dm = get_dm(md->scene, ob, NULL, NULL, NULL, 0); if(!ob->pd) { @@ -6944,7 +6927,7 @@ static void particleSystemModifier_deformVerts( return; if(dm==0) { - dm= get_original_dm(md->scene, ob, vertexCos, 1); + dm= get_dm(md->scene, ob, NULL, NULL, vertexCos, 1); if(!dm) return; @@ -8345,7 +8328,7 @@ static void meshdeformModifier_do( /* if we don't have one computed, use derivedmesh from data * without any modifiers */ if(!cagedm) { - cagedm= get_original_dm(md->scene, mmd->object, NULL, 0); + cagedm= get_dm(md->scene, mmd->object, NULL, NULL, NULL, 0); if(cagedm) cagedm->needsFree= 1; } @@ -8481,14 +8464,10 @@ static void meshdeformModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm; - - if (!derivedData) { - dm= get_original_dm(md->scene, ob, NULL, 0); - if (dm == NULL) return; - } - else dm= derivedData; + DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);; + if(!dm) + return; modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ @@ -8625,52 +8604,31 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm = NULL; + DerivedMesh *dm = derivedData; CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md); - /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ + /* ensure we get a CDDM with applied vertex coords */ if(dataMask) - { - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - else if(ob->type==OB_LATTICE) dm = NULL; - else return; - - if(dm != NULL && (dataMask & (1<scene, ob, NULL, dm, vertexCos); shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts); - if(dm) + if(dm != derivedData) dm->release(dm); } static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = NULL; + DerivedMesh *dm = derivedData; CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md); + /* ensure we get a CDDM with applied vertex coords */ if(dataMask) - { - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data); - else if(ob->type==OB_LATTICE) dm = NULL; - else return; - - if(dm != NULL && (dataMask & (1<scene, ob, editData, dm, vertexCos); shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts); - if(dm) + if(dm != derivedData) dm->release(dm); } @@ -8739,54 +8697,33 @@ static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *for static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm = NULL; + DerivedMesh *dm = derivedData; CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md); - /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ + /* we implement requiredDataMask but thats not really usefull since + mesh_calc_modifiers pass a NULL derivedData */ if(dataMask) - { - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - else if(ob->type==OB_LATTICE) dm = NULL; - else return; - - if(dm != NULL && (dataMask & CD_MVERT)) - { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); - } - } + dm= get_dm(md->scene, ob, NULL, dm, NULL, 0); SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts); - if(dm) + if(dm != derivedData) dm->release(dm); - } static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = NULL; + DerivedMesh *dm = derivedData; CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md); - /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ + /* we implement requiredDataMask but thats not really usefull since + mesh_calc_modifiers pass a NULL derivedData */ if(dataMask) - { - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data); - else if(ob->type==OB_LATTICE) dm = NULL; - else return; - - if(dm != NULL && (dataMask & CD_MVERT)) - { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); - } - } + dm= get_dm(md->scene, ob, editData, dm, NULL, 0); SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts); - if(dm) + if(dm != derivedData) dm->release(dm); } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 072a665e0e9..3997f83ed49 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2227,7 +2227,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, MFace *mface = NULL; FaceVertWeight *qweight, *tweight; - DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss), + DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, + ccgSubSurf_getNumFinalVerts(ss), ccgSubSurf_getNumFinalEdges(ss), ccgSubSurf_getNumFinalFaces(ss));