[Bf-blender-cvs] [7b95d64d2f5] master: Cleanup: better naming, comments, variable scoping in mesh_calc_modifiers.
Brecht Van Lommel
noreply at git.blender.org
Thu Mar 28 20:04:50 CET 2019
Commit: 7b95d64d2f521cafe6a521af5b082c0a13cf8460
Author: Brecht Van Lommel
Date: Thu Mar 28 11:42:53 2019 +0100
Branches: master
https://developer.blender.org/rB7b95d64d2f521cafe6a521af5b082c0a13cf8460
Cleanup: better naming, comments, variable scoping in mesh_calc_modifiers.
===================================================================
M source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 886545ff4b1..ac2ae8a1e35 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -879,18 +879,18 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
static void add_orco_mesh(
Object *ob, BMEditMesh *em, Mesh *mesh,
- Mesh *me_orco, int layer)
+ Mesh *mesh_orco, int layer)
{
float (*orco)[3], (*layerorco)[3];
int totvert, free;
totvert = mesh->totvert;
- if (me_orco) {
+ if (mesh_orco) {
free = 1;
- if (me_orco->totvert == totvert) {
- orco = BKE_mesh_vertexCos_get(me_orco, NULL);
+ if (mesh_orco->totvert == totvert) {
+ orco = BKE_mesh_vertexCos_get(mesh_orco, NULL);
}
else {
orco = BKE_mesh_vertexCos_get(mesh, NULL);
@@ -991,6 +991,59 @@ static void mesh_copy_autosmooth(Mesh *me, Mesh *me_orig)
}
}
+static void mesh_calc_modifier_final_normals(
+ const Mesh *mesh_input,
+ const CustomData_MeshMasks *dataMask,
+ const bool sculpt_dyntopo,
+ Mesh *mesh_final)
+{
+ /* Compute normals. */
+ const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 ||
+ (dataMask->lmask & CD_MASK_NORMAL) != 0);
+ /* Some modifiers may need this info from their target (other) object, simpler to generate it here as well.
+ * Note that they will always be generated when no loop normals are comptuted,
+ * since they are needed by drawing code. */
+ const bool do_poly_normals = ((dataMask->pmask & CD_MASK_NORMAL) != 0);
+
+ if (do_loop_normals) {
+ /* In case we also need poly normals, add the layer here, then BKE_mesh_calc_normals_split() will fill it. */
+ if (do_poly_normals) {
+ if (!CustomData_has_layer(&mesh_final->pdata, CD_NORMAL)) {
+ CustomData_add_layer(&mesh_final->pdata, CD_NORMAL, CD_CALLOC, NULL, mesh_final->totpoly);
+ }
+ }
+ /* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
+ BKE_mesh_calc_normals_split(mesh_final);
+ BKE_mesh_tessface_clear(mesh_final);
+ }
+
+ if (sculpt_dyntopo == false) {
+ /* watch this! after 2.75a we move to from tessface to looptri (by default) */
+ if (dataMask->fmask & CD_MASK_MFACE) {
+ BKE_mesh_tessface_ensure(mesh_final);
+ }
+
+ /* without this, drawing ngon tri's faces will show ugly tessellated face
+ * normals and will also have to calculate normals on the fly, try avoid
+ * this where possible since calculating polygon normals isn't fast,
+ * note that this isn't a problem for subsurf (only quads) or editmode
+ * which deals with drawing differently.
+ *
+ * Only calc vertex normals if they are flagged as dirty.
+ * If using loop normals, poly nors have already been computed.
+ */
+ if (!do_loop_normals) {
+ BKE_mesh_ensure_normals_for_display(mesh_final);
+ }
+ }
+
+ /* Some modifiers, like datatransfer, may generate those data as temp layer, we do not want to keep them,
+ * as they are used by display code when available (i.e. even if autosmooth is disabled). */
+ if (!do_loop_normals && CustomData_has_layer(&mesh_final->ldata, CD_NORMAL)) {
+ CustomData_free_layers(&mesh_final->ldata, CD_NORMAL, mesh_final->totloop);
+ }
+}
+
static void mesh_calc_modifiers(
struct Depsgraph *depsgraph,
Scene *scene, Object *ob,
@@ -998,58 +1051,62 @@ static void mesh_calc_modifiers(
const bool need_mapping,
const CustomData_MeshMasks *dataMask,
const int index,
- const bool useCache,
+ const bool use_cache,
/* return args */
Mesh **r_deform,
Mesh **r_final)
{
- ModifierData *firstmd, *md, *previewmd = NULL;
- CDMaskLink *datamasks, *curr;
- /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
- CustomData_MeshMasks mask, nextmask, previewmask = {0}, append_mask = CD_MASK_BAREMESH_ORIGINDEX;
-
- float (*deformedVerts)[3] = NULL;
- int numVerts = ((Mesh *)ob->data)->totvert;
- const bool useRenderParams = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- const int required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime;
+ /* Input and final mesh. Final mesh is only created the moment the first
+ * constructive modifier is executed, or a deform modifier needs normals
+ * or certain data layers. */
+ Mesh *mesh_input = ob->data;
+ Mesh *mesh_final = NULL;
+ Mesh *mesh_deform = NULL;
+ BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
+
+ /* Deformed vertex locations array. Deform only modifier need this type of
+ * float array rather than MVert*. Tracked along with mesh_final as an
+ * optimization to avoid copying coordinates back and forth if there are
+ * multiple sequential deform only modifiers. */
+ float (*deformed_verts)[3] = NULL;
+ int num_deformed_verts = mesh_input->totvert;
bool isPrevDeform = false;
+
+ /* Mesh with constructive modifiers but no deformation applied. Tracked
+ * along with final mesh if undeformed / orco coordinates are requested
+ * for texturing. */
+ Mesh *mesh_orco = NULL;
+ Mesh *mesh_orco_cloth = NULL;
+
+ /* Modifier evaluation modes. */
+ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+
+ /* Sculpt can skip certain modifiers. */
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
bool multires_applied = false;
- const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
- const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams;
+ const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
+ const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;
- /* Generic preview only in object mode! */
- const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
- const bool do_loop_normals = ((((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) != 0 ||
- (dataMask->lmask & CD_MASK_NORMAL) != 0);
- /* Some modifiers may need this info from their target (other) object, simpler to generate it here as well.
- * Note that they will always be generated when no loop normals are comptuted,
- * since they are needed by drawing code. */
- const bool do_poly_normals = ((dataMask->pmask & CD_MASK_NORMAL) != 0);
+ /* Modifier evaluation contexts for different types of modifiers. */
+ ModifierApplyFlag app_render = use_render ? MOD_APPLY_RENDER : 0;
+ ModifierApplyFlag app_cache = use_cache ? MOD_APPLY_USECACHE : 0;
+ const ModifierEvalContext mectx = {depsgraph, ob, app_render | app_cache};
+ const ModifierEvalContext mectx_orco = {depsgraph, ob, app_render | MOD_APPLY_ORCO};
+ /* Get effective list of modifiers to execute. Some effects like shape keys
+ * are added as virtual modifiers before the user created modifiers. */
VirtualModifierData virtualModifierData;
+ ModifierData *firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+ ModifierData *md = firstmd;
- ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0;
- ModifierApplyFlag deform_app_flags = app_flags;
-
- BLI_assert((((Mesh *)ob->data)->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
-
- if (useCache)
- app_flags |= MOD_APPLY_USECACHE;
- if (useDeform)
- deform_app_flags |= MOD_APPLY_USECACHE;
-
- /* TODO(sybren): do we really need three context objects? Or do we modify
- * them on the fly to change the flags where needed? */
- const ModifierEvalContext mectx_deform = {depsgraph, ob, deform_app_flags};
- const ModifierEvalContext mectx_apply = {depsgraph, ob, app_flags};
- const ModifierEvalContext mectx_orco = {depsgraph, ob, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO};
-
- md = firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-
- modifiers_clearErrors(ob);
-
+ /* Preview colors by modifiers such as dynamic paint, to show the results
+ * even if the resulting data is not used in a material. Only in object mode.
+ * TODO: this is broken, not drawn by the drawn manager. */
+ const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
+ ModifierData *previewmd = NULL;
+ CustomData_MeshMasks previewmask = {0};
if (do_mod_mcol) {
/* Find the last active modifier generating a preview, or NULL if none. */
/* XXX Currently, DPaint modifier just ignores this.
@@ -1058,21 +1115,21 @@ static void mesh_calc_modifiers(
previewmd = modifiers_getLastPreview(scene, md, required_mode);
}
- datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, &previewmask);
- curr = datamasks;
-
- if (r_deform) {
- *r_deform = NULL;
- }
- *r_final = NULL;
+ /* Compute accumulated datamasks needed by each modifier. It helps to do
+ * this fine grained so that for example vertex groups are preserved up to
+ * an armature modifier, but not through a following subsurf modifier where
+ * subdividing them is expensive. */
+ CDMaskLink *datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, &previewmask);
+ CDMaskLink *md_datamask = datamasks;
+ /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
+ CustomData_MeshMasks append_mask = CD_MASK_BAREMESH_ORIGINDEX;
- /* We need mesh even for deform-only part of the stack, in cases where some modifier needs
- * e.g. access to updated normals. See T62633 for an example. */
- Mesh *me = NULL;
+ /* Clear errors before evaluation. */
+ modifiers_clearErrors(ob);
+ /* Apply all leading deform modifiers. */
if (useDeform) {
- /* Apply all leading deforming modifiers */
- for (; md; md = md->next, curr = curr->next) {
+ for (; md; md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (!modifier_isEnabled(scene, md, required_mode)) {
@@ -1084,19 +1141,18 @@ static void mesh_calc_modifiers(
}
if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
- if (!deformedVerts) {
- deformedVerts = BKE_mesh_vertexCo
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list