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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-05-30 21:36:43 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-05-30 21:36:43 +0400
commit09e11ad6ef1187d581b64a9ac6ebbbb6f056f7d9 (patch)
tree7f3100eed9f03496573b80ead9a8f3cf32e75b3b /source
parent1be293629833a43a5ecf3a76c6ed838d183a2683 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c149
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c11
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c3
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c1
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c3
-rw-r--r--source/blender/editors/space_view3d/drawobject.c5
-rw-r--r--source/blender/modifiers/intern/MOD_array.c9
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c4
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c2
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c2
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c4
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c2
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c2
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c3
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c2
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_util.c6
23 files changed, 149 insertions, 77 deletions
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)