diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 5bc5fe58cba..0364393f7fd 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -48,7 +48,7 @@ map> OSLShaderManager::ss_shared; int OSLShaderManager::ss_shared_users = 0; thread_mutex OSLShaderManager::ss_shared_mutex; -int OSLCompiler::texture_shared_unique_id = 0; +std::atomic OSLCompiler::texture_shared_unique_id = 0; /* Shader Manager */ diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h index bf6d260f292..ba4e88fbaac 100644 --- a/intern/cycles/scene/osl.h +++ b/intern/cycles/scene/osl.h @@ -4,6 +4,8 @@ #pragma once +#include + #include "util/array.h" #include "util/set.h" #include "util/string.h" @@ -180,7 +182,7 @@ class OSLCompiler { ShaderType current_type; Shader *current_shader; - static int texture_shared_unique_id; + static std::atomic texture_shared_unique_id; }; CCL_NAMESPACE_END diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc index 1e911cb5798..e00b1387c5e 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc @@ -2985,6 +2985,7 @@ static bke::CurvesGeometry extrude_grease_pencil_curves(const bke::CurvesGeometr const int new_curves_num = dst_to_src_curves.size(); bke::CurvesGeometry dst(new_points_num, new_curves_num); + BKE_defgroup_copy_list(&dst.vertex_group_names, &src.vertex_group_names); /* Setup curve offsets, based on the number of points in each curve. */ MutableSpan new_curve_offsets = dst.offsets_for_write(); diff --git a/source/blender/editors/sculpt_paint/grease_pencil_interpolate.cc b/source/blender/editors/sculpt_paint/grease_pencil_interpolate.cc index cf42d03e154..4d0b2bb2a33 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_interpolate.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_interpolate.cc @@ -455,6 +455,61 @@ static bool compute_auto_flip(const Span from_positions, const Span src_positions, + const bool cyclic, + MutableSpan dst_sample_offsets) +{ + const IndexRange src_points = src_positions.index_range(); + /* Extra segment at the end for cyclic curves. */ + const int num_src_segments = src_points.size() - 1 + cyclic; + const int num_free_samples = num_dst_points - num_src_segments; + BLI_assert(dst_sample_offsets.size() == num_src_segments + 1); + + Array segment_lengths(num_src_segments + 1); + segment_lengths[0] = 0.0f; + for (const int i : src_points.drop_front(1)) { + segment_lengths[i] = segment_lengths[i - 1] + math::distance(src_positions[src_points[i - 1]], + src_positions[src_points[i]]); + } + if (cyclic) { + const int i = src_points.size(); + segment_lengths[i] = segment_lengths[i - 1] + math::distance(src_positions[src_points[i - 1]], + src_positions[src_points[0]]); + } + const float total_length = segment_lengths.last(); + + constexpr float length_epsilon = 1e-4f; + if (total_length > length_epsilon) { + /* Factor for computing the fraction of remaining samples in a segment. */ + const float length_to_free_sample_count = math::safe_divide(float(num_free_samples), + total_length); + int samples_start = 0; + for (const int segment : IndexRange(num_src_segments)) { + const int free_samples_start = math::round(segment_lengths[segment] * + length_to_free_sample_count); + const int free_samples_end = math::round(segment_lengths[segment + 1] * + length_to_free_sample_count); + dst_sample_offsets[segment] = samples_start; + samples_start += 1 + free_samples_end - free_samples_start; + } + } + else { + /* If source segment lengths are zero use uniform mapping by index as fallback. */ + const float index_to_free_sample_count = math::safe_divide(float(num_free_samples), + float(num_src_segments)); + int samples_start = 0; + for (const int segment : IndexRange(num_src_segments)) { + dst_sample_offsets[segment] = samples_start; + const int free_samples_start = math::round(segment * index_to_free_sample_count); + const int free_samples_end = math::round((segment + 1) * index_to_free_sample_count); + samples_start += 1 + free_samples_end - free_samples_start; + } + } + /* This also assigns any remaining samples in case of rounding error. */ + dst_sample_offsets.last() = num_dst_points; +} + /** * Copy existing sample positions and insert new samples in between to reach the final count. */ @@ -471,38 +526,19 @@ static void sample_curve_padded(const bke::CurvesGeometry &curves, const int num_src_segments = src_points.size() - 1 + cyclic; /* There should be at least one source point for every output sample. */ BLI_assert(num_dst_points >= num_src_segments); - const Span src_positions = curves.positions(); if (src_points.is_empty()) { return; } - Array segment_lengths(num_src_segments + 1); - segment_lengths[0] = 0.0f; - for (const int i : src_points.index_range().drop_front(1)) { - segment_lengths[i] = segment_lengths[i - 1] + math::distance(src_positions[src_points[i - 1]], - src_positions[src_points[i]]); - } - if (cyclic) { - const int i = src_points.size(); - segment_lengths[i] = segment_lengths[i - 1] + math::distance(src_positions[src_points[i - 1]], - src_positions[src_points[0]]); - } - const float total_length = segment_lengths.last(); - const int num_free_samples = num_dst_points - num_src_segments; - /* Factor for computing the fraction of remaining samples in a segment. */ - const float length_to_free_sample_count = math::safe_divide(float(num_free_samples), - total_length); + /* First destination point in each source segment. */ + Array dst_sample_offsets(num_src_segments + 1); + assign_samples_to_segments( + num_dst_points, curves.positions().slice(src_points), cyclic, dst_sample_offsets); - int samples_start = 0; + OffsetIndices dst_samples_by_src_segment = OffsetIndices(dst_sample_offsets); for (const int segment : IndexRange(num_src_segments)) { - const int free_samples_start = math::round(segment_lengths[segment] * - length_to_free_sample_count); - const int free_samples_end = math::round(segment_lengths[segment + 1] * - length_to_free_sample_count); - const IndexRange samples = IndexRange::from_begin_size( - samples_start, 1 + free_samples_end - free_samples_start); + const IndexRange samples = dst_samples_by_src_segment[segment]; BLI_assert(samples.size() >= 1); - samples_start = samples.one_after_last(); const int point_index = segment < src_points.size() ? segment : 0; r_segment_indices.slice(samples).fill(point_index); @@ -520,7 +556,6 @@ static void sample_curve_padded(const bke::CurvesGeometry &curves, r_segment_indices.last() = src_points.size() - 1; r_factors.last() = 0.0f; } - BLI_assert(samples_start == num_dst_points); } static bke::CurvesGeometry interpolate_between_curves(const GreasePencil &grease_pencil, diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 14c92a4bc35..41579495daf 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -70,13 +70,14 @@ void FinalEngine::render() render_task_delegate_->bind(); auto t = tasks(); - engine_->Execute(render_index_.get(), &t); char elapsed_time[32]; double time_begin = BLI_time_now_seconds(); float percent_done = 0.0; while (true) { + engine_->Execute(render_index_.get(), &t); + if (RE_engine_test_break(bl_engine_)) { break; }