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 _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs