From 09e11ad6ef1187d581b64a9ac6ebbbb6f056f7d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 May 2013 17:36:43 +0000 Subject: modifier stack: lazy initialize normals many modifiers were calculating normals, when those normals were ignored by the next modifier. now flag normals as dirty and recalculate for modifiers that set use `dependsOnNormals()` callback. Quick test on mesh with 12 modifiers (mostly build type), calculated normals 6 times, now it only runs once - so this will give some speedup too. --- source/blender/blenkernel/BKE_DerivedMesh.h | 6 +- source/blender/blenkernel/intern/DerivedMesh.c | 149 ++++++++++++++------- source/blender/blenkernel/intern/cdderivedmesh.c | 11 ++ source/blender/blenkernel/intern/editderivedmesh.c | 3 +- source/blender/blenkernel/intern/modifiers_bmesh.c | 2 +- source/blender/blenkernel/intern/smoke.c | 1 + source/blender/blenkernel/intern/subsurf_ccg.c | 3 +- source/blender/editors/space_view3d/drawobject.c | 5 + source/blender/modifiers/intern/MOD_array.c | 9 +- source/blender/modifiers/intern/MOD_bevel.c | 4 +- source/blender/modifiers/intern/MOD_boolean_util.c | 2 +- source/blender/modifiers/intern/MOD_edgesplit.c | 2 +- source/blender/modifiers/intern/MOD_explode.c | 2 +- source/blender/modifiers/intern/MOD_mask.c | 2 +- source/blender/modifiers/intern/MOD_mirror.c | 2 +- source/blender/modifiers/intern/MOD_ocean.c | 4 +- .../modifiers/intern/MOD_particleinstance.c | 2 +- source/blender/modifiers/intern/MOD_remesh.c | 2 +- source/blender/modifiers/intern/MOD_screw.c | 3 +- source/blender/modifiers/intern/MOD_skin.c | 2 +- source/blender/modifiers/intern/MOD_solidify.c | 2 +- source/blender/modifiers/intern/MOD_triangulate.c | 2 +- source/blender/modifiers/intern/MOD_util.c | 6 +- 23 files changed, 149 insertions(+), 77 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index f0df766ffde..668eac5e8bc 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -160,7 +160,10 @@ typedef enum DMDirtyFlag { * without actually rebuilding dm (hence by defautl keeping same GPUDrawObject, and same colors * buffer, which prevents update during a stroke!). */ DM_DIRTY_MCOL_UPDATE_DRAW = 1 << 1, -} DMDirtyFlag; + + /* check this with modifier dependsOnNormals callback to see if normals need recalculation */ + DM_DIRTY_NORMALS = 1 << 2, +} DMDirtyFlag; typedef struct DerivedMesh DerivedMesh; struct DerivedMesh { @@ -560,6 +563,7 @@ void DM_free_poly_data(struct DerivedMesh *dm, int index, int count); /*sets up mpolys for a DM based on face iterators in source*/ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target); +void DM_ensure_normals(DerivedMesh *dm); void DM_ensure_tessface(DerivedMesh *dm); void DM_update_tessface_data(DerivedMesh *dm); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 7b2ff7df670..4a5aaa65f90 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -376,6 +376,14 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target) } } +void DM_ensure_normals(DerivedMesh *dm) +{ + if (dm->dirty & DM_DIRTY_NORMALS) { + dm->calcNormals(dm); + } + BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0); +} + /* note: until all modifiers can take MPoly's as input, * use this at the start of modifiers */ void DM_ensure_tessface(DerivedMesh *dm) @@ -818,16 +826,68 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) if (!dm) return NULL; - if (vertCos) + if (vertCos) { CDDM_apply_vert_coords(dm, vertCos); - - CDDM_calc_normals(dm); + } return dm; } /***/ +/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */ + +static DerivedMesh *modwrap_applyModifier( + ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag flag) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { + DM_ensure_normals(dm); + } + return mti->applyModifier(md, ob, dm, flag); +} + +static DerivedMesh *modwrap_applyModifierEM( + ModifierData *md, Object *ob, + BMEditMesh *em, + DerivedMesh *dm, + ModifierApplyFlag flag) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { + DM_ensure_normals(dm); + } + return mti->applyModifierEM(md, ob, em, dm, flag); +} + +static void modwrap_deformVerts( + ModifierData *md, Object *ob, + DerivedMesh *dm, + float (*vertexCos)[3], int numVerts, + ModifierApplyFlag flag) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { + DM_ensure_normals(dm); + } + mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag); +} + +static void modwrap_deformVertsEM( + ModifierData *md, Object *ob, + BMEditMesh *em, DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { + DM_ensure_normals(dm); + } + mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts); +} +/* end modifier callback wrappers */ + DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md, int build_shapekey_layers) { @@ -849,7 +909,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, int numVerts; float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts); - mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0); + modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, 0); dm = mesh_create_derived(me, ob, deformedVerts); if (build_shapekey_layers) @@ -863,7 +923,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, if (build_shapekey_layers) add_shapekey_layers(tdm, me, ob); - dm = mti->applyModifier(md, ob, tdm, 0); + dm = modwrap_applyModifier(md, ob, tdm, 0); if (tdm != dm) tdm->release(tdm); } @@ -937,8 +997,6 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay if (free) MEM_freeN(orco); } - CDDM_calc_normals(dm); - return dm; } @@ -1372,6 +1430,20 @@ static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob)) } } +/** + * Called after calculating all modifiers. + * + * \note tessfaces should already be calculated. + */ +static void dm_ensure_display_normals(DerivedMesh *dm) +{ + if ((dm->type == DM_TYPE_CDDM) && + ((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == FALSE)) + { + /* if normals are dirty we want to calculate vertex normals too */ + CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + } +} /* 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 @@ -1468,7 +1540,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (!deformedVerts) deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); - mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, deform_app_flags); + modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, deform_app_flags); } else { break; @@ -1491,7 +1563,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (deformedVerts) { CDDM_apply_vert_coords(*deform_r, deformedVerts); - CDDM_calc_normals(*deform_r); } } } @@ -1582,11 +1653,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* 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); - CDDM_calc_normals(dm); } } - mti->deformVerts(md, ob, dm, deformedVerts, numVerts, deform_app_flags); + modwrap_deformVerts(md, ob, dm, deformedVerts, numVerts, deform_app_flags); } else { DerivedMesh *ndm; @@ -1605,7 +1675,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos dm = tdm; CDDM_apply_vert_coords(dm, deformedVerts); - CDDM_calc_normals(dm); } } else { @@ -1616,7 +1685,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); - CDDM_calc_normals(dm); } if (do_init_wmcol) @@ -1667,7 +1735,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } } - ndm = mti->applyModifier(md, ob, dm, app_flags); + ndm = modwrap_applyModifier(md, ob, dm, app_flags); if (ndm) { /* if the modifier returned a new dm, release the old one */ @@ -1692,7 +1760,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX | (mti->requiredDataMask ? mti->requiredDataMask(ob, md) : 0)); - ndm = mti->applyModifier(md, ob, orcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + + ndm = modwrap_applyModifier(md, ob, orcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); if (ndm) { /* if the modifier returned a new dm, release the old one */ @@ -1708,7 +1777,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos nextmask &= ~CD_MASK_CLOTH_ORCO; DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); - ndm = mti->applyModifier(md, ob, clothorcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + + ndm = modwrap_applyModifier(md, ob, clothorcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); if (ndm) { /* if the modifier returned a new dm, release the old one */ @@ -1751,7 +1821,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos dm->release(dm); CDDM_apply_vert_coords(finaldm, deformedVerts); - CDDM_calc_normals(finaldm); #if 0 /* For later nice mod preview! */ /* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */ @@ -1769,22 +1838,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos #endif } else { - 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); } /* In this case, we should never have weight-modifying modifiers in stack... */ @@ -1848,11 +1909,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos * note that this isn't a problem for subsurf (only quads) or editmode * which deals with drawing differently. * - * Never calc vertex normals because other code ensures these are up to date. + * Only calc vertex normals if they are flagged as dirty. */ - if ((finaldm->type == DM_TYPE_CDDM) && (CustomData_has_layer(&finaldm->faceData, CD_NORMAL) == FALSE)) { - CDDM_calc_normals_mapping_ex(finaldm, TRUE); - } + dm_ensure_display_normals(finaldm); } #ifdef WITH_GAMEENGINE @@ -1984,9 +2043,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } if (mti->deformVertsEM) - mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); + modwrap_deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); else - mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0); + modwrap_deformVerts(md, ob, dm, deformedVerts, numVerts, 0); } else { DerivedMesh *ndm; @@ -1999,7 +2058,6 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D dm = tdm; CDDM_apply_vert_coords(dm, deformedVerts); - CDDM_calc_normals(dm); } else if (cage_r && dm == *cage_r) { /* dm may be changed by this modifier, so we need to copy it @@ -2013,7 +2071,6 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if (deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); - CDDM_calc_normals(dm); } if (do_init_wmcol) { @@ -2031,9 +2088,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D DM_set_only_copy(orcodm, mask | CD_MASK_ORIGINDEX); if (mti->applyModifierEM) - ndm = mti->applyModifierEM(md, ob, em, orcodm, MOD_APPLY_ORCO); + ndm = modwrap_applyModifierEM(md, ob, em, orcodm, MOD_APPLY_ORCO); else - ndm = mti->applyModifier(md, ob, orcodm, MOD_APPLY_ORCO); + ndm = modwrap_applyModifier(md, ob, orcodm, MOD_APPLY_ORCO); if (ndm) { /* if the modifier returned a new dm, release the old one */ @@ -2053,9 +2110,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D DM_init_origspace(dm); } } - + if (mti->applyModifierEM) - ndm = mti->applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE); + ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE); else ndm = mti->applyModifier(md, ob, dm, MOD_APPLY_USECACHE); @@ -2100,22 +2157,13 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if (!(cage_r && dm == *cage_r)) dm->release(dm); CDDM_apply_vert_coords(*final_r, deformedVerts); - CDDM_calc_normals(*final_r); /* was CDDM_calc_normals_mapping - campbell */ } else if (dm) { *final_r = dm; - - /* once we support skipping normal calculation with modifiers we may want to add this back */ -#if 0 // was added for bmesh but is not needed - (*final_r)->calcNormals(*final_r); -#endif } else if (!deformedVerts && cage_r && *cage_r) { /* cage should already have up to date normals */ *final_r = *cage_r; -#if 0 // was added for bmesh but is not needed - (*final_r)->calcNormals(*final_r); -#endif /* In this case, we should never have weight-modifying modifiers in stack... */ if (do_init_wmcol) @@ -2152,6 +2200,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } /* --- */ + /* same as mesh_calc_modifiers */ + dm_ensure_display_normals(*final_r); + /* add an orco layer if needed */ if (dataMask & CD_MASK_ORCO) add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO); @@ -2191,6 +2242,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask, * but this avoids waiting on first stroke) */ ob->sculpt->pbvh = ob->derivedFinal->getPBVH(ob, ob->derivedFinal); } + + BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS)); } static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) @@ -2217,6 +2270,8 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C em->lastDataMask = dataMask; em->derivedFinal->needsFree = 0; em->derivedCage->needsFree = 0; + + BLI_assert(!(em->derivedFinal->dirty & DM_DIRTY_NORMALS)); } static CustomDataMask object_get_datamask(Scene *scene, Object *ob) @@ -2271,6 +2326,7 @@ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dat if (!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask) mesh_build_data(scene, ob, dataMask, 0); + if (ob->derivedFinal) { BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS)); } return ob->derivedFinal; } @@ -2380,6 +2436,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, } *final_r = em->derivedFinal; + if (em->derivedFinal) { BLI_assert(!(em->derivedFinal->dirty & DM_DIRTY_NORMALS)); } return em->derivedCage; } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 743b4a33bc2..80bd71e7b59 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1841,6 +1841,7 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) dm = CDDM_new(totvert, totedge, 0, totloop, totpoly); dm->deformedOnly = 1; + dm->dirty |= DM_DIRTY_NORMALS; cddm = (CDDerivedMesh *)dm; @@ -2197,6 +2198,8 @@ void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3]) for (i = 0; i < dm->numVertData; ++i, ++vert) copy_v3_v3(vert->co, vertCoords[i]); + + cddm->dm.dirty |= DM_DIRTY_NORMALS; } void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3]) @@ -2211,6 +2214,8 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3]) for (i = 0; i < dm->numVertData; ++i, ++vert) copy_v3_v3_short(vert->no, vertNormals[i]); + + cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals) @@ -2255,6 +2260,8 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numTessFaceData); + + cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } @@ -2285,6 +2292,8 @@ void CDDM_calc_normals(DerivedMesh *dm) BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), dm->numLoopData, dm->numPolyData, poly_nors); + + cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } void CDDM_calc_normals_tessface(DerivedMesh *dm) @@ -2305,6 +2314,8 @@ void CDDM_calc_normals_tessface(DerivedMesh *dm) BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData, cddm->mface, dm->numTessFaceData, face_nors); + + cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } #if 1 diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 794e6481d34..be072d9cc16 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -74,10 +74,11 @@ typedef struct EditDerivedBMesh { float (*polyNos)[3]; } EditDerivedBMesh; -static void emDM_calcNormals(DerivedMesh *UNUSED(dm)) +static void emDM_calcNormals(DerivedMesh *dm) { /* Nothing to do: normals are already calculated and stored on the * BMVerts and BMFaces */ + dm->dirty &= ~DM_DIRTY_NORMALS; } static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm)) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 85ed20bcb14..b5f07176e2b 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -157,7 +157,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) /* note: i_alt is aligned with bmesh faces which may not always align with mpolys */ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); - face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ + face_normals = (dm->dirty & DM_DIRTY_NORMALS) ? NULL : CustomData_get_layer(&dm->polyData, CD_NORMAL); for (i = 0; i < dm->numPolyData; i++, mp++) { BMLoop *l_iter; BMLoop *l_first; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 2bf11b993c4..05c3550d810 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -2602,6 +2602,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) CDDM_calc_edges(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 91a992ff92f..1934a7052e5 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3071,9 +3071,10 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm)) /* Nothing to do: CCG handles creating its own tessfaces */ } -static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm)) +static void ccgDM_calcNormals(DerivedMesh *dm) { /* Nothing to do: CCG calculates normals during drawing */ + dm->dirty &= ~DM_DIRTY_NORMALS; } static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index ba2949fbbec..5f2e45decd0 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2969,6 +2969,9 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, BMEdge *eed_act = NULL; BMVert *eve_act = NULL; + if (cageDM) BLI_assert(!(cageDM->dirty & DM_DIRTY_NORMALS)); + if (finalDM) BLI_assert(!(finalDM->dirty & DM_DIRTY_NORMALS)); + if (em->bm->selected.last) { BMEditSelection *ese = em->bm->selected.last; /* face is handeled above */ @@ -3215,6 +3218,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if (!dm) return; + if (dm) BLI_assert(!(dm->dirty & DM_DIRTY_NORMALS)); + /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). * Note: Last "preview-active" modifier in stack will win! */ if (DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL) && modifiers_isPreview(ob)) diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index a1fdae5792c..902afd2ed41 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -565,11 +565,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) { /* Update normals in case offset object has rotation. */ - - /* BMESH_TODO: check if normal recalc needed under any other - * conditions? */ - - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; } BM_mesh_free(bm); @@ -591,9 +587,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = arrayModifier_doArray(amd, md->scene, ob, dm, 0); - //if (result != dm) - // CDDM_calc_normals_mapping(result); - return result; } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 7cd10491c89..cbb0e05aa4a 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -171,7 +171,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BM_mesh_free(bm); - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } @@ -208,7 +208,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), /* until we allow for dirty normal flag, always calc, * note: calculating on the CDDM is faster then the BMesh equivalent */ - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index ed5bb1d3f4d..75a05633507 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -485,7 +485,7 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( DM_ensure_tessface(result); #endif - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 94e7475e9b3..0c50d4d3323 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -136,7 +136,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der result = edgesplitModifier_do(emd, ob, derivedData); if (result != derivedData) - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index f0eb113e46f..c8899bac450 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -971,7 +971,7 @@ static DerivedMesh *explodeMesh(ExplodeModifierData *emd, /* finalization */ CDDM_calc_edges_tessface(explode); CDDM_tessfaces_to_faces(explode); - CDDM_calc_normals(explode); + explode->dirty |= DM_DIRTY_NORMALS; if (psmd->psys->lattice) { end_latt_deform(psmd->psys->lattice); diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 46a590e24e9..0d302fed3e6 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -384,7 +384,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* why is this needed? - campbell */ /* recalculate normals */ - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; /* free hashes */ BLI_ghash_free(vertHash, NULL, NULL); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index b85ca2c1532..2e7b7c7ab7d 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -330,7 +330,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = mirrorModifier__doMirror(mmd, ob, derivedData); if (result != derivedData) - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 34c89fc6ee3..125d4bc3789 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -386,6 +386,8 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) } } + result->dirty |= DM_DIRTY_NORMALS; + return result; } @@ -543,7 +545,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = doOcean(md, ob, derivedData, 0); if (result != derivedData) - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 2c942b38286..b0de27b7292 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -391,7 +391,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (size) MEM_freeN(size); - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index 746cad10a01..c8fdbc535bc 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -202,7 +202,7 @@ static DerivedMesh *applyModifier(ModifierData *md, } CDDM_calc_edges(result); - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index bbafa8c939e..475d294abd6 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -897,8 +897,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, #endif if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { - /* BMESH_TODO, we only need to get vertex normals here, this is way overkill */ - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; } return result; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index ad58aac1746..6c2bd25f0a5 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1805,7 +1805,7 @@ static DerivedMesh *base_skin(DerivedMesh *origdm, BM_mesh_free(bm); CDDM_calc_edges(result); - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; skin_set_orig_indices(result); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index c54ed26d47e..ef7f0050bb1 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -820,7 +820,7 @@ static DerivedMesh *applyModifier( /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ if (dvert) { - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; } if (numFaces == 0 && numEdges != 0) { diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index 59973fe77a8..fd0bc218bc4 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -54,7 +54,7 @@ static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag) for (i = 0; i < total_edges; i++, me++) me->flag |= ME_EDGEDRAW | ME_EDGERENDER; - CDDM_calc_normals(result); + result->dirty |= DM_DIRTY_NORMALS; return result; } diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 1084023fcf0..c3748ce0265 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -184,11 +184,9 @@ DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float else { dm = CDDM_copy(dm); CDDM_apply_vert_coords(dm, vertexCos); + dm->dirty |= DM_DIRTY_NORMALS; } - if (dm) - CDDM_calc_normals(dm); - return dm; } @@ -204,7 +202,7 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (* if (vertexCos) { CDDM_apply_vert_coords(dm, vertexCos); - //CDDM_calc_normals(dm); + dm->dirty |= DM_DIRTY_NORMALS; } if (orco) -- cgit v1.2.3