diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2019-07-03 01:26:53 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2019-07-03 01:33:49 +0300 |
commit | 50ccbe6bb2339ac132298305f8782bec4a6da079 (patch) | |
tree | 23d2e8ab0eb6a852c1ec88ae8eb98c781a493371 /source/blender/editors/object | |
parent | 2d35fed6f846a256c0869b1a913d545b7953310a (diff) |
Fix T63302: Crash when baking normals from selected to active with no cage
When we create the cage procedurally, we need to remove any edge split
modifiers. Since the new depsgraph in 2.80 we were removing the
modifiers straight from the evaluated object (it is a copy anyways).
On top of that we need to reset its eval data state (BKE_object_eval_reset)
to make sure the call to BKE_object_to_mesh to generate the cage would take the
new modifier stack state into account.
However doing so was freeing the low poly mesh we use later to convert
the normal space.
The solution (and this patch in fact ;) ) as suggested by Sergey Sharybin is to
use BKE_mesh_new_from_object() directly as well as force the modifiers to be
recalculated when any edge split modifier is removed.
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 6164958bf2c..410ccccbd0d 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -707,7 +707,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re /* create new mesh with edit mode changes and modifiers applied */ static Mesh *bake_mesh_new_from_object(Object *object) { - Mesh *me = BKE_object_to_mesh(NULL, object, false); + Mesh *me = BKE_mesh_new_from_object(NULL, object, false); if (me->flag & ME_AUTOSMOOTH) { BKE_mesh_split_faces(me, true); @@ -927,7 +927,7 @@ static int bake(Render *re, } } else if (is_cage) { - BKE_object_eval_reset(ob_low_eval); + bool is_changed = false; ModifierData *md = ob_low_eval->modifiers.first; while (md) { @@ -942,11 +942,23 @@ static int bake(Render *re, if (md->type == eModifierType_EdgeSplit) { BLI_remlink(&ob_low_eval->modifiers, md); modifier_free(md); + is_changed = true; } md = md_next; } - me_cage = BKE_object_to_mesh(NULL, ob_low_eval, false); + if (is_changed) { + /* Make sure object is evaluated with the new modifier settings. + * + * NOTE: Since the dependency graph was fully evaluated prior to bake, and we only made + * single modification to this object all the possible dependencies for evaluation are + * already up to date. This means we can do a cheap single object update + * (as an opposite of full depsgraph update). */ + BKE_object_eval_reset(ob_low_eval); + BKE_object_handle_data_update(depsgraph, scene, ob_low_eval); + } + + me_cage = BKE_mesh_new_from_object(NULL, ob_low_eval, false); RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); } @@ -965,7 +977,7 @@ static int bake(Render *re, highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter); highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER; highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER); - highpoly[i].me = BKE_object_to_mesh(NULL, highpoly[i].ob_eval, false); + highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false); /* lowpoly to highpoly transformation matrix */ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat); @@ -1088,7 +1100,7 @@ static int bake(Render *re, } /* Evaluate modifiers again. */ - me_nores = BKE_object_to_mesh(NULL, ob_low_eval, false); + me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false); RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer); RE_bake_normal_world_to_tangent(pixel_array_low, @@ -1098,7 +1110,7 @@ static int bake(Render *re, me_nores, normal_swizzle, ob_low_eval->obmat); - BKE_object_to_mesh_clear(ob_low_eval); + BKE_id_free(NULL, &me_nores->id); if (md) { md->mode = mode; @@ -1221,8 +1233,8 @@ cleanup: if (highpoly) { int i; for (i = 0; i < tot_highpoly; i++) { - if (highpoly[i].ob_eval) { - BKE_object_to_mesh_clear(highpoly[i].ob_eval); + if (highpoly[i].me != NULL) { + BKE_id_free(NULL, &highpoly[i].me->id); } } MEM_freeN(highpoly); @@ -1252,12 +1264,12 @@ cleanup: MEM_freeN(result); } - if (ob_low_eval) { - BKE_object_to_mesh_clear(ob_low_eval); + if (me_low != NULL) { + BKE_id_free(NULL, &me_low->id); } - if (ob_cage_eval) { - BKE_object_to_mesh_clear(ob_cage_eval); + if (me_cage != NULL) { + BKE_id_free(NULL, &me_cage->id); } DEG_graph_free(depsgraph); |