[Bf-blender-cvs] [9039306a991] gpencil-new-data-proposal: Frame sorting

Falk David noreply at git.blender.org
Tue May 10 12:25:33 CEST 2022


Commit: 9039306a9912bc986ca0cf9d09355db24d569ac9
Author: Falk David
Date:   Thu May 5 18:03:09 2022 +0200
Branches: gpencil-new-data-proposal
https://developer.blender.org/rB9039306a9912bc986ca0cf9d09355db24d569ac9

Frame sorting

===================================================================

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 06cffb3e959..ce4f26378f4 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
@@ -3,6 +3,9 @@
 /** \file
  * \ingroup bke
  */
+
+#include <algorithm>
+
 #include "BKE_curves.hh"
 #include "BLI_math_vec_types.hh"
 
@@ -67,7 +70,27 @@ class GPFrame : public ::GPFrame {
     this->start = this->end = -1;
   }
 
+  GPFrame(int layer_index, int start_frame)
+  {
+    this->layer_index = layer_index;
+    this->start = start_frame;
+    this->end = -1;
+  }
+
   ~GPFrame() = default;
+
+  bool operator<(const GPFrame &other) const
+  {
+    if (this->start == other.start) {
+      return this->layer_index < other.layer_index;
+    }
+    return this->start < other.start;
+  }
+
+  bool operator==(const GPFrame &other) const
+  {
+    return this->layer_index == other.layer_index && this->start == other.start;
+  }
 };
 
 class GPData : public ::GPData {
@@ -155,22 +178,57 @@ class GPData : public ::GPData {
     return true;
   }
 
-  const GPFrame &new_frame_on_layer(const int layer_index)
+  /**
+   * Find a GPFrame in the frame_array given by the layer index and the frame number in logarithmic
+   * time. If the frame is found, returns a pointer/iterator to it, otherwise nullptr.
+   *
+   * Note: This assumes that the array is sorted.
+   */
+  const GPFrame *frame_at(const int layer_idx, const int start_frame_number)
   {
-    BLI_assert(layer_index >= 0 && layer_index < this->layers_size);
+    auto it = std::lower_bound(
+        this->frames().begin(), this->frames().end(), GPFrame(layer_idx, start_frame_number));
+    if (it == this->frames().end() || it->start != start_frame_number) {
+      return nullptr;
+    }
+    return it;
+  }
 
-    GPFrame new_frame(layer_index);
+  void create_new_frame_on_layer(const int layer_index, const int start_frame_number)
+  {
+    BLI_assert(layer_index >= 0 && layer_index < this->layers_size);
+    /* Allocate new space for the frame. */
     ensure_frame_array_has_size_at_least(this->frames_size + 1);
+
+    /* Create a new frame and append it at the end. */
+    GPFrame new_frame(layer_index, start_frame_number);
     this->frames_for_write().last() = new_frame;
 
-    return this->frames().last();
+    /* Sort the frame array. */
+    update_frames_array();
+  }
+
+  void create_new_frame_on_layer(GPLayer &layer, const int start_frame_number)
+  {
+    int index = this->layers().first_index_try(layer);
+    BLI_assert(index != -1);
+    create_new_frame_on_layer(index, start_frame_number);
+  }
+
+  const GPFrame &get_new_frame_on_layer(const int layer_index, const int start_frame_number)
+  {
+    create_new_frame_on_layer(layer_index, start_frame_number);
+    /* Find the frame in the array and return it. */
+    const GPFrame *gpf = this->frame_at(layer_index, start_frame_number);
+    BLI_assert(gpf != nullptr);
+    return *gpf;
   }
 
-  const GPFrame &new_frame_on_layer(GPLayer &layer)
+  const GPFrame &get_new_frame_on_layer(GPLayer &layer, const int start_frame_number)
   {
     int index = this->layers().first_index_try(layer);
     BLI_assert(index != -1);
-    return new_frame_on_layer(index);
+    return get_new_frame_on_layer(index, start_frame_number);
   }
 
  private:
@@ -217,6 +275,12 @@ class GPData : public ::GPData {
 
     return true;
   }
+
+  void update_frames_array()
+  {
+    /* Make sure frames are ordered chronologically and by layer order. */
+    std::sort(this->frames_for_write().begin(), this->frames_for_write().end());
+  }
 };
 
 }  // namespace blender::bke
@@ -294,8 +358,51 @@ TEST(gpencil_proposal, AddFrameToLayer)
 
   my_data.add_layer(my_layer1);
   my_data.add_layer(my_layer2);
-  GPFrame my_frame = my_data.new_frame_on_layer(my_layer2);
+  GPFrame my_frame = my_data.get_new_frame_on_layer(my_layer2, 0);
   EXPECT_EQ(my_frame.layer_index, 1);
 }
 
+TEST(gpencil_proposal, CheckFramesSorted1)
+{
+  GPData my_data;
+  GPLayer my_layer1("TestLayer1");
+
+  const int frame_numbers1[5] = {10, 5, 6, 1, 3};
+  const int frame_numbers_sorted1[5] = {1, 3, 5, 6, 10};
+
+  my_data.add_layer(my_layer1);
+  for (int i : IndexRange(5)) {
+    GPFrame my_frame = my_data.get_new_frame_on_layer(my_layer1, frame_numbers1[i]);
+    int idx = my_data.frames().first_index(my_frame);
+    EXPECT_EQ(my_data.frames()[idx].start, frame_numbers1[i]);
+  }
+
+  for (const int i : my_data.frames().index_range()) {
+    EXPECT_EQ(my_data.frames()[i].start, frame_numbers_sorted1[i]);
+  }
+}
+
+TEST(gpencil_proposal, CheckFramesSorted2)
+{
+  GPData my_data;
+  GPLayer my_layer1("TestLayer1");
+  GPLayer my_layer2("TestLayer2");
+  const int frame_numbers_layer1[5] = {10, 5, 6, 1, 3};
+  const int frame_numbers_layer2[5] = {8, 5, 7, 1, 4};
+  const int frame_numbers_sorted2[10][2] = {
+      {0, 1}, {1, 1}, {0, 3}, {1, 4}, {0, 5}, {1, 5}, {0, 6}, {1, 7}, {1, 8}, {0, 10}};
+
+  my_data.add_layer(my_layer1);
+  my_data.add_layer(my_layer2);
+  for (int i : IndexRange(5)) {
+    my_data.create_new_frame_on_layer(my_layer1, frame_numbers_layer1[i]);
+    my_data.create_new_frame_on_layer(my_layer2, frame_numbers_layer2[i]);
+  }
+
+  for (const int i : my_data.frames().index_range()) {
+    EXPECT_EQ(my_data.frames()[i].layer_index, frame_numbers_sorted2[i][0]);
+    EXPECT_EQ(my_data.frames()[i].start, frame_numbers_sorted2[i][1]);
+  }
+}
+
 }  // namespace blender::bke::gpencil::tests
\ No newline at end of file



More information about the Bf-blender-cvs mailing list