[Bf-blender-cvs] [fcc0e61c389] gpencil-new-data-proposal: Add insert frame test
Falk David
noreply at git.blender.org
Tue May 17 17:38:49 CEST 2022
Commit: fcc0e61c389cf2c58e823d97cd1b5fa5c7c99d51
Author: Falk David
Date: Tue May 17 17:38:16 2022 +0200
Branches: gpencil-new-data-proposal
https://developer.blender.org/rBfcc0e61c389cf2c58e823d97cd1b5fa5c7c99d51
Add insert frame test
===================================================================
M source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
index 4ca0ca7a4fb..78f2bdf1186 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
@@ -429,6 +429,16 @@ class GPData : public ::GPData {
return layers_for_write()[index];
}
+ const GPLayer &active_layer()
+ {
+ return this->layers()[this->active_layer_index];
+ }
+
+ GPLayer &active_layer_for_write()
+ {
+ return this->layers_for_write()[this->active_layer_index];
+ }
+
int add_layer(StringRefNull name)
{
/* Ensure that the layer array has enough space. */
@@ -457,21 +467,7 @@ class GPData : public ::GPData {
return -1;
}
- GPFrame new_frame(frame_start);
- new_frame.layer_index = layer_index;
- this->frames_for_write().last() = std::move(new_frame);
-
- /* Sort frame array. */
- update_frames_array();
-
- /* Find the frame again and return its index (now from the sorted array). */
- auto it = std::lower_bound(this->frames().begin(),
- this->frames().end(),
- std::pair<int, int>(layer_index, new_frame.start_time));
- if (it == this->frames().end() || it->start_time != new_frame.start_time) {
- return -1;
- }
- return std::distance(this->frames().begin(), it);
+ return add_frame_on_layer_initialized(layer_index, frame_start, 1);
}
int add_frame_on_layer(GPLayer &layer, int frame_start)
@@ -483,10 +479,23 @@ class GPData : public ::GPData {
return add_frame_on_layer(index, frame_start);
}
+ int add_frame_on_active_layer(int frame_start)
+ {
+ return add_frame_on_layer(active_layer_index, frame_start);
+ }
+
void add_frames_on_layer(int layer_index, Array<int> start_frames)
{
+ int new_frames_size = start_frames.size();
+ /* TODO: Check for collisions before resizing the array. */
+ if (!ensure_frames_array_has_size_at_least(this->frames_size + new_frames_size)) {
+ return;
+ }
+
+ int reserved = new_frames_size;
for (int start_frame : start_frames) {
- add_frame_on_layer(layer_index, start_frame);
+ add_frame_on_layer_initialized(layer_index, start_frame, reserved);
+ reserved--;
}
}
@@ -627,6 +636,42 @@ class GPData : public ::GPData {
return true;
}
+ /**
+ * Creates a new frame and inserts it into the \a frames_array so that the ordering is kept.
+ * Assumes that \a frames_array is sorted and that the array has been reallocated + expaned by \a
+ * reserved.
+ */
+ int add_frame_on_layer_initialized(int layer_index, int frame_start, int reserved)
+ {
+ /* Create the new frame. */
+ GPFrame new_frame(frame_start);
+ new_frame.layer_index = layer_index;
+
+ int last_index = this->frames_size - reserved - 1;
+
+ /* Check if the frame can be appended at the end. */
+ if (this->frames_size == 0 || this->frames_size == reserved ||
+ this->frames(last_index) < std::pair<int, int>(layer_index, frame_start)) {
+ this->frames_for_write(last_index + 1) = std::move(new_frame);
+ return last_index + 1;
+ }
+
+ /* Look for the first frame that is equal or greater than the new frame. */
+ auto it = std::lower_bound(this->frames().begin(),
+ this->frames().drop_back(reserved).end(),
+ std::pair<int, int>(layer_index, frame_start));
+ /* Get the index of the frame. */
+ int index = std::distance(this->frames().begin(), it);
+ /* Move all the frames and make space at index. */
+ initialized_reversed_move_n(reinterpret_cast<GPFrame *>(this->frames_array + index),
+ this->frames_size - index - 1,
+ reinterpret_cast<GPFrame *>(this->frames_array + index + 1));
+ /* Move the new frame into the space at index. */
+ this->frames_for_write(index) = std::move(new_frame);
+
+ return index;
+ }
+
void update_frames_array()
{
/* Make sure frames are ordered chronologically and by layer order. */
@@ -643,7 +688,7 @@ namespace blender::bke::gpencil::tests {
static GPData build_gpencil_data(int num_layers,
int frames_per_layer,
- int strokes_per_layer,
+ int strokes_per_frame,
int points_per_stroke)
{
GPData gpd;
@@ -660,7 +705,7 @@ static GPData build_gpencil_data(int num_layers,
}
for (const int i : gpd.frames().index_range()) {
- for (const int j : IndexRange(strokes_per_layer)) {
+ for (const int j : IndexRange(strokes_per_frame)) {
GPStroke stroke = gpd.frames_for_write(i).add_new_stroke(points_per_stroke);
for (const int k : stroke.points_positions_for_write().index_range()) {
stroke.points_positions_for_write()[k] = {
@@ -674,7 +719,7 @@ static GPData build_gpencil_data(int num_layers,
static bGPdata *build_old_gpencil_data(int num_layers,
int frames_per_layer,
- int strokes_per_layer,
+ int strokes_per_frame,
int points_per_stroke)
{
bGPdata *gpd = reinterpret_cast<bGPdata *>(MEM_mallocN(sizeof(bGPdata), __func__));
@@ -682,6 +727,7 @@ static bGPdata *build_old_gpencil_data(int num_layers,
for (int i = 0; i < num_layers; i++) {
bGPDlayer *gpl = reinterpret_cast<bGPDlayer *>(MEM_mallocN(sizeof(bGPDlayer), __func__));
sprintf(gpl->info, "%s%d", "GPLayer", i);
+ gpl->flag = 0;
BLI_listbase_clear(&gpl->mask_layers);
BLI_listbase_clear(&gpl->frames);
@@ -690,7 +736,7 @@ static bGPdata *build_old_gpencil_data(int num_layers,
gpf->framenum = j;
BLI_listbase_clear(&gpf->strokes);
- for (int k = 0; k < strokes_per_layer; k++) {
+ for (int k = 0; k < strokes_per_frame; k++) {
bGPDstroke *gps = reinterpret_cast<bGPDstroke *>(
MEM_mallocN(sizeof(bGPDstroke), __func__));
gps->totpoints = points_per_stroke;
@@ -728,6 +774,12 @@ static bGPdata *copy_old_gpencil_data(bGPdata *gpd_src)
return gpd_dst;
}
+static void insert_new_frame_old_gpencil_data(bGPdata *gpd, int frame_num)
+{
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BKE_gpencil_frame_addnew(gpl_active, frame_num);
+}
+
static void free_old_gpencil_data(bGPdata *gpd)
{
BKE_gpencil_free_layers(&gpd->layers);
@@ -952,4 +1004,43 @@ TEST(gpencil_proposal, TimeBigGPDataCopy)
free_old_gpencil_data(old_data_copy);
}
+TEST(gpencil_proposal, TimeBigGPDataInsertFrame)
+{
+ int layers_num = 100, frames_num = 1000, strokes_num = 10, points_num = 10;
+ GPData data = build_gpencil_data(layers_num, frames_num, strokes_num, points_num);
+ data.set_active_layer(7);
+
+ TIMEIT_START(TimeBigGPDataInsertFrame);
+ data.add_frame_on_active_layer(347);
+ TIMEIT_END(TimeBigGPDataInsertFrame);
+
+ EXPECT_EQ(data.frames_on_active_layer().size(), 1001);
+
+ bGPdata *old_data = build_old_gpencil_data(layers_num, frames_num, strokes_num, points_num);
+ int i = 0;
+ bGPDlayer *gpl_active = NULL;
+ LISTBASE_FOREACH_INDEX (bGPDlayer *, gpl, &old_data->layers, i) {
+ if (i == 7) {
+ BKE_gpencil_layer_active_set(old_data, gpl);
+ gpl_active = gpl;
+ break;
+ }
+ }
+ /* Remove the frame so we can insert it again. */
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_active->frames) {
+ if (gpf->framenum == 347) {
+ BKE_gpencil_layer_frame_delete(gpl_active, gpf);
+ break;
+ }
+ }
+
+ TIMEIT_START(TimeBigGPDataOldInsertFrame);
+ insert_new_frame_old_gpencil_data(old_data, 347);
+ TIMEIT_END(TimeBigGPDataOldInsertFrame);
+
+ EXPECT_EQ(BLI_listbase_count(&gpl_active->frames), 1000);
+
+ free_old_gpencil_data(old_data);
+}
+
} // namespace blender::bke::gpencil::tests
More information about the Bf-blender-cvs
mailing list