Blender V5.0
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
21
23 Main *bmain = nullptr;
25
27 {
29 this->bmain = BKE_main_new();
30 this->grease_pencil = BKE_id_new<GreasePencil>(this->bmain, "GP");
31 }
36};
37
38TEST(grease_pencil_merge, merge_simple)
39{
40 using namespace bke::greasepencil;
42 GreasePencil &grease_pencil = *ctx.grease_pencil;
43
44 Layer &layer1 = grease_pencil.add_layer("Layer1");
45 Layer &layer2 = grease_pencil.add_layer("Layer2");
46
47 grease_pencil.insert_frame(layer1, 0);
48
49 grease_pencil.insert_frame(layer2, 0);
50 grease_pencil.insert_frame(layer2, 2);
51
52 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
53
54 /* Merge Layer1 and Layer2. */
55 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}});
57 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
58
59 EXPECT_EQ(merged_grease_pencil->layers().size(), 1);
60 EXPECT_EQ(merged_grease_pencil->layer(0).frames().size(), 2);
61 EXPECT_STREQ(merged_grease_pencil->layer(0).name().c_str(), "Layer1");
62
63 BKE_id_free(nullptr, merged_grease_pencil);
64}
65
66TEST(grease_pencil_merge, merge_in_same_group)
67{
68 using namespace bke::greasepencil;
70 GreasePencil &grease_pencil = *ctx.grease_pencil;
71
72 LayerGroup &group1 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group1");
73 LayerGroup &group2 = grease_pencil.add_layer_group(group1, "Group2");
74 LayerGroup &group3 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group3");
75
76 Layer &layer1 = grease_pencil.add_layer("Layer1");
77 Layer &layer2 = grease_pencil.add_layer(group1, "Layer2");
78 Layer &layer3 = grease_pencil.add_layer(group2, "Layer3");
79 Layer &layer4 = grease_pencil.add_layer(group2, "Layer4");
80 grease_pencil.add_layer(group3, "Layer5");
81
82 grease_pencil.insert_frame(layer1, 0);
83
84 grease_pencil.insert_frame(layer2, 0);
85 grease_pencil.insert_frame(layer2, 2);
86
87 grease_pencil.insert_frame(layer3, 0);
88 grease_pencil.insert_frame(layer3, 3);
89
90 grease_pencil.insert_frame(layer4, 1);
91 grease_pencil.insert_frame(layer4, 3);
92
93 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
94 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
95
96 /* Merge "Layer3" and "Layer4" */
97 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}, {2}, {3}, {4}});
99 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
100
101 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
102
103 Array<std::string> expected_layer_names({"Layer3", "Layer2", "Layer5", "Layer1"});
104 for (const int i : merged_grease_pencil->layers().index_range()) {
105 const Layer &layer = merged_grease_pencil->layer(i);
106 EXPECT_STREQ(layer.name().c_str(), expected_layer_names[i].c_str());
107 }
108
109 Array<int> expected_layer3_keyframes({0, 1, 3});
110 for (const int i : merged_grease_pencil->layer(0).sorted_keys().index_range()) {
111 const int key = merged_grease_pencil->layer(0).sorted_keys()[i];
112 EXPECT_EQ(key, expected_layer3_keyframes[i]);
113 }
114
115 BKE_id_free(nullptr, merged_grease_pencil);
116}
117
118TEST(grease_pencil_merge, merge_in_different_group)
119{
120 using namespace bke::greasepencil;
122 GreasePencil &grease_pencil = *ctx.grease_pencil;
123
124 LayerGroup &group1 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group1");
125 LayerGroup &group2 = grease_pencil.add_layer_group(group1, "Group2");
126 LayerGroup &group3 = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group3");
127 LayerGroup &group4 = grease_pencil.add_layer_group(group2, "Group4");
128 LayerGroup &group5 = grease_pencil.add_layer_group(group4, "Group5");
129 LayerGroup &group6 = grease_pencil.add_layer_group(group1, "Group6");
130
131 Layer &layer1 = grease_pencil.add_layer("Layer1");
132 Layer &layer2 = grease_pencil.add_layer(group6, "Layer2");
133 Layer &layer3 = grease_pencil.add_layer(group5, "Layer3");
134 Layer &layer4 = grease_pencil.add_layer(group2, "Layer4");
135 grease_pencil.add_layer(group3, "Layer5");
136
137 grease_pencil.insert_frame(layer1, 0);
138
139 grease_pencil.insert_frame(layer2, 0);
140 grease_pencil.insert_frame(layer2, 2);
141
142 grease_pencil.insert_frame(layer3, 0);
143 grease_pencil.insert_frame(layer3, 3);
144
145 grease_pencil.insert_frame(layer4, 1);
146 grease_pencil.insert_frame(layer4, 3);
147
148 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
149 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
150
151 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 2}, {1}, {3}, {4}});
153 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
154
155 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
156
157 TreeNode *node = merged_grease_pencil->find_node_by_name("Layer3");
158 EXPECT_TRUE(node != nullptr);
159 EXPECT_TRUE(node->is_layer());
160 EXPECT_TRUE(node->parent_group() && node->parent_group()->name() == "Group1");
161
162 EXPECT_EQ(node->as_layer().frames().size(), 3);
163
164 Array<int> expected_layer3_keyframes({0, 2, 3});
165 for (const int i : node->as_layer().sorted_keys().index_range()) {
166 const int key = node->as_layer().sorted_keys()[i];
167 EXPECT_EQ(key, expected_layer3_keyframes[i]);
168 }
169
170 Array<std::string> expected_layer_names({"Layer4", "Layer3", "Layer5", "Layer1"});
171 for (const int i : merged_grease_pencil->layers().index_range()) {
172 const Layer &layer = merged_grease_pencil->layer(i);
173 EXPECT_STREQ(layer.name().c_str(), expected_layer_names[i].c_str());
174 }
175
176 BKE_id_free(nullptr, merged_grease_pencil);
177}
178
179TEST(grease_pencil_merge, merge_keyframes)
180{
181 using namespace bke::greasepencil;
183 GreasePencil &grease_pencil = *ctx.grease_pencil;
184
185 Layer &layer1 = grease_pencil.add_layer("Layer1");
186 Layer &layer2 = grease_pencil.add_layer("Layer2");
187 Layer &layer3 = grease_pencil.add_layer("Layer3");
188 Layer &layer4 = grease_pencil.add_layer("Layer4");
189 grease_pencil.add_layer("Layer5");
190
191 Drawing *drawing = grease_pencil.insert_frame(layer1, 0);
192 drawing->strokes_for_write().resize(10, 2);
194
195 drawing = grease_pencil.insert_frame(layer2, 0);
196 drawing->strokes_for_write().resize(20, 3);
198 drawing = grease_pencil.insert_frame(layer2, 2);
199 drawing->strokes_for_write().resize(30, 4);
201
202 drawing = grease_pencil.insert_frame(layer3, 0);
203 drawing->strokes_for_write().resize(40, 5);
205 drawing = grease_pencil.insert_frame(layer3, 3);
206 drawing->strokes_for_write().resize(50, 6);
208
209 drawing = grease_pencil.insert_frame(layer4, 1);
210 drawing->strokes_for_write().resize(60, 7);
212 drawing = grease_pencil.insert_frame(layer4, 3);
213 drawing->strokes_for_write().resize(70, 8);
215
216 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
217 BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);
218
219 Array<Vector<int>> src_layer_indices_by_dst_layer({{0}, {1, 2}, {3}, {4}});
221 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
222
223 EXPECT_EQ(merged_grease_pencil->layers().size(), 4);
224
225 Layer &expected_layer_1 = merged_grease_pencil->find_node_by_name("Layer1")->as_layer();
226 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_1, 0)->strokes().points_num(), 10);
227
228 Layer &expected_layer_2 = merged_grease_pencil->find_node_by_name("Layer2")->as_layer();
229 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_2, 0)->strokes().points_num(), 60);
230
231 Layer &expected_layer_4 = merged_grease_pencil->find_node_by_name("Layer4")->as_layer();
232 EXPECT_EQ(merged_grease_pencil->get_drawing_at(expected_layer_4, 3)->strokes().points_num(), 70);
233
234 BKE_id_free(nullptr, merged_grease_pencil);
235}
236
237TEST(grease_pencil_merge, merge_layer_attributes)
238{
239 using namespace bke;
240 using namespace bke::greasepencil;
242 GreasePencil &grease_pencil = *ctx.grease_pencil;
243
244 grease_pencil.add_layer("Layer1");
245 grease_pencil.add_layer("Layer2");
246 grease_pencil.add_layer("Layer3");
247
248 Array<float> test_float_values({4.2f, 1.0f, -12.0f});
249 SpanAttributeWriter<float> test_attribute =
250 grease_pencil.attributes_for_write().lookup_or_add_for_write_only_span<float>(
251 "test", AttrDomain::Layer);
252 EXPECT_TRUE(test_attribute);
253 test_attribute.span.copy_from(test_float_values);
254 test_attribute.finish();
255
256 GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
257
258 /* Merge Layer1 and Layer2. */
259 Array<Vector<int>> src_layer_indices_by_dst_layer({{0, 1}, {2}});
261 grease_pencil, src_layer_indices_by_dst_layer, *merged_grease_pencil);
262
263 EXPECT_EQ(merged_grease_pencil->layers().size(), 2);
264
265 VArray<float> merged_values = *merged_grease_pencil->attributes().lookup<float>("test");
266 Array<float> expected_float_values({2.6, -12.0f});
267 for (const int i : merged_grease_pencil->layers().index_range()) {
268 EXPECT_FLOAT_EQ(merged_values[i], expected_float_values[i]);
269 }
270
271 BKE_id_free(nullptr, merged_grease_pencil);
272}
273
274} // 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:121
void BKE_id_free(Main *bmain, void *idv)
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1514
Main * BKE_main_new()
Definition main.cc:89
void BKE_main_free(Main *bmain)
Definition main.cc:192
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
int64_t size() const
Definition BLI_map.hh:976
void resize(int points_num, int curves_num)
bke::CurvesGeometry & strokes_for_write()
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
Span< FramesMapKeyT > sorted_keys() const
const LayerGroup * parent_group() const
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)
i
Definition text_draw.cc:230