From ab652f7b5f03abcc6a3fdf6e2c2dcbfb8a80e7f2 Mon Sep 17 00:00:00 2001 From: Falk David Date: Wed, 25 Oct 2023 10:19:19 +0200 Subject: [PATCH] Fix: GPv3: Crash earsing when using modifier This issue happend when a geometry nodes modifier wouldn't output grease pencil geometry. In this case, we write an emtpy grease pencil data-block to the evaluated `geometry_set`. But we don't update the `eval_frame` that indicates on what frame the grease pencil data-block was evaluated on. The fix makes sure we update the `eval_frame` even if the output is empty. Additionally, there was a missing return in the `get_evaluated_grease_pencil_drawing_deformation` function that lead to an empty `deformation.positions` span. The fix makes sure we return the correct deformation with the correct positions. --- .../blender/blenkernel/intern/crazyspace.cc | 34 +++++++++++-------- .../blenkernel/intern/grease_pencil.cc | 4 ++- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index f5212ed0af0..d7c062e6136 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -677,7 +677,9 @@ GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object const GreasePencil &grease_pencil_orig = *static_cast(ob_orig.data); const int eval_frame = grease_pencil.runtime->eval_frame; - const int drawing_index = grease_pencil_orig.layers()[layer_index]->drawing_index_at(eval_frame); + const Span layers_orig = grease_pencil_orig.layers(); + BLI_assert(layer_index >= 0 && layer_index < layers_orig.size()); + const int drawing_index = layers_orig[layer_index]->drawing_index_at(eval_frame); if (drawing_index == -1) { return {}; } @@ -707,11 +709,12 @@ GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object if (edit_hints != nullptr && &edit_hints->grease_pencil_id_orig == &grease_pencil_orig && edit_hints->drawing_hints.has_value()) { - BLI_assert(edit_hints->drawing_hints->size() == grease_pencil_orig.layers().size()); + BLI_assert(edit_hints->drawing_hints->size() == layers_orig.size()); const GreasePencilDrawingEditHints &drawing_hints = edit_hints->drawing_hints.value()[layer_index]; if (drawing_hints.positions.has_value()) { deformation.positions = *drawing_hints.positions; + return deformation; } } @@ -721,18 +724,21 @@ GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object { if (const GreasePencil *grease_pencil_eval = grease_pencil_component_eval->get()) { Span layers_eval = grease_pencil_eval->layers(); - const bke::greasepencil::Layer *layer_eval = layers_eval[layer_index]; - const int drawing_index_eval = layer_eval->drawing_index_at(eval_frame); - if (drawing_index_eval != -1) { - const GreasePencilDrawingBase *drawing_base_eval = grease_pencil_eval->drawing( - drawing_index_eval); - if (drawing_base_eval->type != GP_DRAWING) { - return {}; - } - const bke::greasepencil::Drawing &drawing_eval = - reinterpret_cast(drawing_base_eval)->wrap(); - if (drawing_eval.strokes().points_num() == drawing_orig.strokes().points_num()) { - deformation.positions = drawing_eval.strokes().positions(); + if (layers_eval.size() != layers_orig.size()) { + const bke::greasepencil::Layer *layer_eval = layers_eval[layer_index]; + const int drawing_index_eval = layer_eval->drawing_index_at(eval_frame); + if (drawing_index_eval != -1) { + const GreasePencilDrawingBase *drawing_base_eval = grease_pencil_eval->drawing( + drawing_index_eval); + if (drawing_base_eval->type != GP_DRAWING) { + return deformation; + } + const bke::greasepencil::Drawing &drawing_eval = + reinterpret_cast(drawing_base_eval)->wrap(); + if (drawing_eval.strokes().points_num() == drawing_orig.strokes().points_num()) { + deformation.positions = drawing_eval.strokes().positions(); + return deformation; + } } } } diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index fc1f94f80e6..98f5937351a 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -1199,7 +1199,9 @@ void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *o grease_pencil_evaluate_modifiers(depsgraph, scene, object, geometry_set); if (!geometry_set.has_grease_pencil()) { - geometry_set.replace_grease_pencil(BKE_grease_pencil_new_nomain()); + GreasePencil *empty_grease_pencil = BKE_grease_pencil_new_nomain(); + empty_grease_pencil->runtime->eval_frame = int(DEG_get_ctime(depsgraph)); + geometry_set.replace_grease_pencil(empty_grease_pencil); } /* For now the evaluated data is not const. We could use #get_grease_pencil_for_write, but that