Blender V4.3
grease_pencil_merge_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "BKE_attribute.hh"
8#include "BKE_curves.hh"
10#include "BKE_idtype.hh"
11#include "BKE_lib_id.hh"
12#include "BKE_main.hh"
13
14#include "BLI_array.hh"
15#include "BLI_vector.hh"
16#include "BLI_virtual_array.hh"
17
18#include "ED_grease_pencil.hh"
19
20#include <iostream>
21
23
25 Main *bmain = nullptr;
27
29 {
31 this->bmain = BKE_main_new();
32 this->grease_pencil = static_cast<GreasePencil *>(BKE_id_new(this->bmain, ID_GP, "GP"));
33 }
38};
39
40TEST(grease_pencil_merge, merge_simple)
41{
42 using namespace bke::greasepencil;
44 GreasePencil &grease_pencil = *ctx.grease_pencil;
45
46 Layer &layer1 = grease_pencil.add_layer("Layer1");
47 Layer &layer2 = grease_pencil.add_layer("Layer2");
48
49 grease_pencil.insert_frame(layer1, 0);
50
51 grease_pencil.insert_frame(layer2, 0);
52 grease_pencil.insert_frame(layer2, 2);
53
54 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
55
56 /* Merge Layer1 and Layer2. */
57 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}});
59 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
60
61 EXPECT_EQ(merged_grease_pencil->layers().size(), 1);
62 EXPECT_EQ(merged_grease_pencil->layer(0).frames().size(), 2);
63 EXPECT_STREQ(merged_grease_pencil->layer(0).name().c_str(), "Layer1");
64
65 BKE_id_free(nullptr, merged_grease_pencil);
66}
67
68TEST(grease_pencil_merge, merge_in_same_group)
69{
70 using namespace bke::greasepencil;
72 GreasePencil &grease_pencil = *ctx.grease_pencil;
73
74 LayerGroup &group1 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group1");
75 LayerGroup &group2 = grease_pencil.add_layer_group(group1, "Group2");
76 LayerGroup &group3 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group3");
77
78 Layer &layer1 = grease_pencil.add_layer("Layer1");
79 Layer &layer2 = grease_pencil.add_layer(group1, "Layer2");
80 Layer &layer3 = grease_pencil.add_layer(group2, "Layer3");
81 Layer &layer4 = grease_pencil.add_layer(group2, "Layer4");
82 grease_pencil.add_layer(group3, "Layer5");
83
84 grease_pencil.insert_frame(layer1, 0);
85
86 grease_pencil.insert_frame(layer2, 0);
87 grease_pencil.insert_frame(layer2, 2);
88
89 grease_pencil.insert_frame(layer3, 0);
90 grease_pencil.insert_frame(layer3, 3);
91
92 grease_pencil.insert_frame(layer4, 1);
93 grease_pencil.insert_frame(layer4, 3);
94
95 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
96 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
97
98 /* Merge "Layer3" and "Layer4" */
99 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}, {2}, {3}, {4}});
101 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
102
103 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
104
105 Array<std::string> expected_layer_names({"Layer3", "Layer2", "Layer5", "Layer1"});
106 for (const int i : merged_grease_pencil->layers().index_range()) {
107 const Layer &layer = merged_grease_pencil->layer(i);
108 EXPECT_STREQ(layer.name().c_str(), expected_layer_names[i].c_str());
109 }
110
111 Array<int> expected_layer3_keyframes({0, 1, 3});
112 for (const int i : merged_grease_pencil->layer(0).sorted_keys().index_range()) {
113 const int key = merged_grease_pencil->layer(0).sorted_keys()[i];
114 EXPECT_EQ(key, expected_layer3_keyframes[i]);
115 }
116
117 BKE_id_free(nullptr, merged_grease_pencil);
118}
119
120TEST(grease_pencil_merge, merge_in_different_group)
121{
122 using namespace bke::greasepencil;
124 GreasePencil &grease_pencil = *ctx.grease_pencil;
125
126 LayerGroup &group1 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group1");
127 LayerGroup &group2 = grease_pencil.add_layer_group(group1, "Group2");
128 LayerGroup &group3 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group3");
129 LayerGroup &group4 = grease_pencil.add_layer_group(group2, "Group4");
130 LayerGroup &group5 = grease_pencil.add_layer_group(group4, "Group5");
131 LayerGroup &group6 = grease_pencil.add_layer_group(group1, "Group6");
132
133 Layer &layer1 = grease_pencil.add_layer("Layer1");
134 Layer &layer2 = grease_pencil.add_layer(group6, "Layer2");
135 Layer &layer3 = grease_pencil.add_layer(group5, "Layer3");
136 Layer &layer4 = grease_pencil.add_layer(group2, "Layer4");
137 grease_pencil.add_layer(group3, "Layer5");
138
139 grease_pencil.insert_frame(layer1, 0);
140
141 grease_pencil.insert_frame(layer2, 0);
142 grease_pencil.insert_frame(layer2, 2);
143
144 grease_pencil.insert_frame(layer3, 0);
145 grease_pencil.insert_frame(layer3, 3);
146
147 grease_pencil.insert_frame(layer4, 1);
148 grease_pencil.insert_frame(layer4, 3);
149
150 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
151 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
152
153 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 2}, {1}, {3}, {4}});
155 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
156
157 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
158
159 TreeNode *node = merged_grease_pencil->find_node_by_name("Layer3");
160 EXPECT_TRUE(node != nullptr);
161 EXPECT_TRUE(node->is_layer());
162 EXPECT_TRUE(node->parent_group() && node->parent_group()->name() == "Group1");
163
164 EXPECT_EQ(node->as_layer().frames().size(), 3);
165
166 Array<int> expected_layer3_keyframes({0, 2, 3});
167 for (const int i : node->as_layer().sorted_keys().index_range()) {
168 const int key = node->as_layer().sorted_keys()[i];
169 EXPECT_EQ(key, expected_layer3_keyframes[i]);
170 }
171
172 Array<std::string> expected_layer_names({"Layer4", "Layer3", "Layer5", "Layer1"});
173 for (const int i : merged_grease_pencil->layers().index_range()) {
174 const Layer &layer = merged_grease_pencil->layer(i);
175 EXPECT_STREQ(layer.name().c_str(), expected_layer_names[i].c_str());
176 }
177
178 BKE_id_free(nullptr, merged_grease_pencil);
179}
180
181TEST(grease_pencil_merge, merge_keyframes)
182{
183 using namespace bke::greasepencil;
185 GreasePencil &grease_pencil = *ctx.grease_pencil;
186
187 Layer &layer1 = grease_pencil.add_layer("Layer1");
188 Layer &layer2 = grease_pencil.add_layer("Layer2");
189 Layer &layer3 = grease_pencil.add_layer("Layer3");
190 Layer &layer4 = grease_pencil.add_layer("Layer4");
191 grease_pencil.add_layer("Layer5");
192
193 Drawing *drawing = grease_pencil.insert_frame(layer1, 0);
194 drawing->strokes_for_write().resize(10, 2);
195
196 drawing = grease_pencil.insert_frame(layer2, 0);
197 drawing->strokes_for_write().resize(20, 3);
198 drawing = grease_pencil.insert_frame(layer2, 2);
199 drawing->strokes_for_write().resize(30, 4);
200
201 drawing = grease_pencil.insert_frame(layer3, 0);
202 drawing->strokes_for_write().resize(40, 5);
203 drawing = grease_pencil.insert_frame(layer3, 3);
204 drawing->strokes_for_write().resize(50, 6);
205
206 drawing = grease_pencil.insert_frame(layer4, 1);
207 drawing->strokes_for_write().resize(60, 7);
208 drawing = grease_pencil.insert_frame(layer4, 3);
209 drawing->strokes_for_write().resize(70, 8);
210
211 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
212 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
213
214 Array<Vector<int>> src_layer_indices_by_dst_layer({{0}, {1, 2}, {3}, {4}});
216 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
217
218 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
219
220 Layer &expected_layer_1 = merged_grease_pencil->find_node_by_name("Layer1")->as_layer();
221 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_1, 0)->strokes().points_num(), 10);
222
223 Layer &expected_layer_2 = merged_grease_pencil->find_node_by_name("Layer2")->as_layer();
224 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_2, 0)->strokes().points_num(), 60);
225
226 Layer &expected_layer_4 = merged_grease_pencil->find_node_by_name("Layer4")->as_layer();
227 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_4, 3)->strokes().points_num(), 70);
228
229 BKE_id_free(nullptr, merged_grease_pencil);
230}
231
232TEST(grease_pencil_merge, merge_layer_attributes)
233{
234 using namespace bke;
235 using namespace bke::greasepencil;
237 GreasePencil &grease_pencil = *ctx.grease_pencil;
238
239 grease_pencil.add_layer("Layer1");
240 grease_pencil.add_layer("Layer2");
241 grease_pencil.add_layer("Layer3");
242
243 Array<float> test_float_values({4.2f, 1.0f, -12.0f});
244 SpanAttributeWriter<float> test_attribute =
245 grease_pencil.attributes_for_write().lookup_or_add_for_write_only_span<float>(
246 "test", AttrDomain::Layer);
247 test_attribute.span.copy_from(test_float_values);
248 test_attribute.finish();
249
250 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
251
252 /* Merge Layer1 and Layer2. */
253 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}, {2}});
255 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
256
257 EXPECT_EQ(merged_grease_pencil->layers().size(), 2);
258
259 VArray<float> merged_values = *merged_grease_pencil->attributes().lookup<float>("test");
260 Array<float> expected_float_values({2.6, -12.0f});
261 for (const int i : merged_grease_pencil->layers().index_range()) {
262 EXPECT_FLOAT_EQ(merged_values[i], expected_float_values[i]);
263 }
264
265 BKE_id_free(nullptr, merged_grease_pencil);
266}
267
268} // namespace blender::ed::greasepencil::tests
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_grease_pencil_copy_parameters(const GreasePencil &src, GreasePencil &dst)
GreasePencil * BKE_grease_pencil_new_nomain()
void BKE_idtype_init()
Definition idtype.cc:127
void BKE_id_free(Main *bmain, void *idv)
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1482
Main * BKE_main_new(void)
Definition main.cc:45
void BKE_main_free(Main *bmain)
Definition main.cc:175
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
@ ID_GP
void resize(int points_num, int curves_num)
bke::CurvesGeometry & strokes_for_write()
TEST(grease_pencil_merge, merge_simple)
void merge_layers(const GreasePencil &src_grease_pencil, const Span< Vector< int > > src_layer_indices_by_dst_layer, GreasePencil &dst_grease_pencil)