From 2a317bad3e6d64f171f5b5d914858cace280da86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 28 May 2025 18:23:25 +0200 Subject: [PATCH] Fix #139471: Grease Pencil: Trace materials must be created on main thread Creating materials in worker threads does not work, this relies on BKE functions which must only be called from the main thread. Create the foreground/background materials in advance before starting the trace job. Pull Request: https://projects.blender.org/blender/blender/pulls/139532 --- .../sculpt_paint/grease_pencil_trace.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/sculpt_paint/grease_pencil_trace.cc b/source/blender/editors/sculpt_paint/grease_pencil_trace.cc index 2a4ae4ea6f3..5000e4e2d25 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_trace.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_trace.cc @@ -98,6 +98,8 @@ struct TraceJob { TraceMode mode; /* Custom source frame, allows overriding the default scene frame. */ int frame_number; + int foreground_material_index; + int background_material_index; bool success; bool was_canceled; @@ -207,17 +209,18 @@ static bke::CurvesGeometry grease_pencil_trace_image(TraceJob &trace_job, const /* Assign different materials to foreground curves and hole curves. */ bke::MutableAttributeAccessor attributes = trace_curves.attributes_for_write(); - const int material_fg = ensure_foreground_material( - trace_job.bmain, trace_job.ob_grease_pencil, "Stroke"); - const int material_bg = ensure_background_material( - trace_job.bmain, trace_job.ob_grease_pencil, "Holdout"); + BLI_assert_msg(trace_job.foreground_material_index >= 0, + "ensure_foreground_material must be called on the main thread"); + BLI_assert_msg(trace_job.background_material_index >= 0, + "ensure_background_material must be called on the main thread"); const VArraySpan holes = *attributes.lookup(hole_attribute_id); bke::SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_span( "material_index", bke::AttrDomain::Curve); threading::parallel_for(trace_curves.curves_range(), 4096, [&](const IndexRange range) { for (const int curve_i : range) { const bool is_hole = holes[curve_i]; - material_indices.span[curve_i] = (is_hole ? material_bg : material_fg); + material_indices.span[curve_i] = (is_hole ? trace_job.background_material_index : + trace_job.foreground_material_index); } }); material_indices.finish(); @@ -424,6 +427,12 @@ static wmOperatorStatus grease_pencil_trace_image_exec(bContext *C, wmOperator * /* Back to active base. */ blender::ed::object::base_activate(job->C, job->base_active); + /* Create materials on the main thread before starting the job. */ + job->foreground_material_index = ensure_foreground_material( + job->bmain, job->ob_grease_pencil, "Stroke"); + job->background_material_index = ensure_background_material( + job->bmain, job->ob_grease_pencil, "Holdout"); + if ((job->image->source == IMA_SRC_FILE) || (job->frame_number > 0)) { wmJobWorkerStatus worker_status = {}; trace_start_job(job, &worker_status);