116 using namespace bke::greasepencil;
117 const int num_dst_layers = src_layer_indices_by_dst_layer.size();
124 dst_grease_pencil, src_grease_pencil.root_group(), dst_grease_pencil.root_group());
125 BLI_assert(src_groups.
size() == dst_grease_pencil.layer_groups().size());
128 Array<int> parent_group_index_by_dst_layer(num_dst_layers);
129 for (
const int dst_layer_i : src_layer_indices_by_dst_layer.index_range()) {
130 const Span<int> src_layer_indices = src_layer_indices_by_dst_layer[dst_layer_i];
133 parent_group_index_by_dst_layer[dst_layer_i] = src_groups.
first_index_try(&parent);
141 int num_dst_drawings = 0;
145 for (
const int dst_layer_i : src_layer_indices_by_dst_layer.index_range()) {
146 const Span<int> src_layer_indices = src_layer_indices_by_dst_layer[dst_layer_i];
147 const Layer &src_first = *src_layers[src_layer_indices.
first()];
148 const int parent_index = parent_group_index_by_dst_layer[dst_layer_i];
150 LayerGroup &dst_parent = (parent_index == -1) ? dst_grease_pencil.root_group() :
151 *dst_groups[parent_index];
152 Layer &dst_layer = dst_grease_pencil.add_layer(dst_parent, src_first.name(),
false);
156 dst_layer_to_old_index_map.
add(&dst_layer, dst_layer_i);
158 const int dst_drawing_start_index = src_drawing_indices_by_dst_drawing.
size();
161 if (src_layer_indices.
size() == 1) {
166 for (
const FramesMapKeyT key : src_first.
sorted_keys()) {
175 src_transforms_by_dst_drawing.
append(
180 index = index + dst_drawing_start_index;
182 value.drawing_index = index;
189 struct InsertKeyframe {
194 for (
const int src_layer_i : src_layer_indices) {
195 const Layer &src_layer = *src_layers[src_layer_i];
196 for (
const auto &item : src_layer.
frames().
items()) {
197 if (item.value.is_end()) {
204 [&](InsertKeyframe *frame) {
205 *frame = {item.value, duration};
207 [&](InsertKeyframe *frame) {
214 else if (frame->duration > 0) {
216 frame->duration = std::max(frame->duration, duration);
225 for (
const FramesMapKeyT key : dst_frames.keys()) {
226 sorted_keys[i++] = key;
228 std::sort(sorted_keys.
begin(), sorted_keys.
end());
233 for (
const int src_layer_i : src_layer_indices) {
234 const Layer &src_layer = *src_layers[src_layer_i];
235 for (
const int key_i : sorted_keys.
index_range()) {
236 const FramesMapKeyT key = sorted_keys[key_i];
238 if (drawing_index != -1) {
239 src_drawing_indices_by_frame[key_i].append(drawing_index);
240 src_transforms_by_frame[key_i].append(dst_layer_transform_inv *
248 for (
const int key_i : sorted_keys.
index_range()) {
249 const FramesMapKeyT key = sorted_keys[key_i];
250 const InsertKeyframe value = dst_frames.lookup(key);
251 const Vector<int> &src_drawing_indices = src_drawing_indices_by_frame[key_i];
256 frame->
flag = value.frame.flag;
257 frame->
type = value.frame.type;
260 int index = unique_src_indices_per_drawing.
index_of_try(src_drawing_indices);
262 unique_src_indices_per_drawing.
add_new(src_drawing_indices);
264 src_transforms_by_dst_drawing.
append(src_transforms);
268 index = index + dst_drawing_start_index;
273 dst_layer.tag_frames_map_changed();
278 Array<int> old_to_new_index_map(num_dst_layers);
279 for (
const int layer_i : dst_grease_pencil.layers().index_range()) {
280 const Layer *layer = &dst_grease_pencil.layer(layer_i);
281 old_to_new_index_map[dst_layer_to_old_index_map.lookup(layer)] = layer_i;
285 if (num_dst_drawings > 0) {
286 dst_grease_pencil.add_empty_drawings(num_dst_drawings);
289 MutableSpan<GreasePencilDrawingBase *> dst_drawings = dst_grease_pencil.drawings();
291 for (const int dst_drawing_i : range) {
292 const Span<int> src_drawing_indices = src_drawing_indices_by_dst_drawing[dst_drawing_i];
293 const Span<float4x4> src_transforms_to_apply = src_transforms_by_dst_drawing[dst_drawing_i];
294 const GreasePencilDrawingBase *src_first_base = src_drawings[src_drawing_indices.first()];
295 BLI_assert(src_first_base->type == GP_DRAWING);
296 GreasePencilDrawingBase *dst_base = dst_drawings[dst_drawing_i];
297 BLI_assert(dst_base->type == GP_DRAWING);
299 dst_base->flag = src_first_base->flag;
301 Drawing &dst_drawing = reinterpret_cast<GreasePencilDrawing *>(dst_base)->wrap();
302 if (src_drawing_indices.size() == 1) {
303 const Drawing &src_drawing =
304 reinterpret_cast<const GreasePencilDrawing *>(src_first_base)->wrap();
305 dst_drawing.strokes_for_write() = src_drawing.strokes();
306 dst_drawing.tag_topology_changed();
311 Vector<const bke::CurvesGeometry *> all_src_curves;
312 for (const int src_darwing_i : src_drawing_indices) {
313 const GreasePencilDrawingBase *src_base = src_drawings[src_darwing_i];
314 BLI_assert(src_base->type == GP_DRAWING);
315 const Drawing &src_drawing =
316 reinterpret_cast<const GreasePencilDrawing *>(src_base)->wrap();
317 all_src_curves.append(&src_drawing.strokes());
320 dst_drawing.strokes_for_write() = join_curves(
321 src_grease_pencil, all_src_curves, src_transforms_to_apply);
322 dst_drawing.tag_topology_changed();
327 for (
const Layer *dst_layer : dst_grease_pencil.layers()) {
328 dst_grease_pencil.update_drawing_users_for_layer(*dst_layer);
332 const bke::AttributeAccessor src_attributes = src_grease_pencil.attributes();
333 bke::MutableAttributeAccessor dst_attributes = dst_grease_pencil.attributes_for_write();
338 bke::GAttributeReader src_attribute = src_attributes.lookup(iter.
name);
339 if (!src_attribute) {
342 bke::GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
345 const CPPType &type = dst_attribute.span.type();
346 bke::attribute_math::convert_to_static_type(type, [&](
auto type) {
347 using T =
decltype(type);
348 const VArraySpan<T> src_span = src_attribute.varray.typed<T>();
349 MutableSpan<T> new_span = dst_attribute.span.typed<T>();
351 bke::attribute_math::DefaultMixer<T> mixer(new_span);
352 for (
const int dst_layer_i : IndexRange(num_dst_layers)) {
353 const Span<int> src_layer_indices = src_layer_indices_by_dst_layer[dst_layer_i];
354 const int new_index = old_to_new_index_map[dst_layer_i];
355 for (
const int src_layer_i : src_layer_indices) {
356 const T &src_value = src_span[src_layer_i];
357 mixer.mix_in(new_index, src_value);
363 dst_attribute.finish();