[Bf-blender-cvs] [96b9dc973ff] gpencil-new-data-proposal: Implement adding frames to layers, add comments

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


Commit: 96b9dc973ffef744b0c5fb18e899bb170ad3206f
Author: Falk David
Date:   Thu May 5 11:07:17 2022 +0200
Branches: gpencil-new-data-proposal
https://developer.blender.org/rB96b9dc973ffef744b0c5fb18e899bb170ad3206f

Implement adding frames to layers, add comments

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

M	source/blender/blenkernel/intern/gpencil_new_proposal.hh
M	source/blender/blenkernel/intern/gpencil_new_proposal_test.cc

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

diff --git a/source/blender/blenkernel/intern/gpencil_new_proposal.hh b/source/blender/blenkernel/intern/gpencil_new_proposal.hh
index 5fc3fa4e870..680975ea671 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal.hh
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal.hh
@@ -24,30 +24,61 @@ typedef struct GPDataRuntimeHandle GPDataRuntimeHandle;
 #endif
 
 typedef struct GPLayerGroup {
+  /**
+   * An array of GPLayerGroup's. A layer group can have N >= 0 number of layer group children.
+   */
   struct GPLayerGroup *children;
   int children_size;
 
+  /**
+   * An array of indices to the layers in GPData.layers_array. These are the layers contained in
+   * the group.
+   */
   int *layer_indices;
   int layer_indices_size;
 
+  /**
+   * The name of the layer group.
+   */
   char name[128];
 
   /* ... */
 } GPLayerGroup;
 
 typedef struct GPLayer {
+  /**
+   * The name of the layer.
+   */
   char name[128];
 
+  /**
+   * The layer flag.
+   */
   int flag;
 
   /* ... */
 } GPLayer;
 
 typedef struct GPFrame {
+  /**
+   * The curves in this frame. Each individual curve is a single stroke. The CurvesGeometry
+   * structure also stores attributes on the strokes and points.
+   */
   CurvesGeometry strokes;
 
+  /**
+   * The frame flag.
+   */
   int flag;
 
+  /**
+   * The index of the layer in GPData.layers_array that this frame is in.
+   */
+  int layer_index;
+
+  /**
+   * The start and end frame in the scene that the grease pencil frame is displayed.
+   */
   int start;
   int end;
 
@@ -55,21 +86,41 @@ typedef struct GPFrame {
 } GPFrame;
 
 typedef struct GPData {
+  /**
+   * The array of grease pencil frames. This is kept in cronological order (tiebreaks for two
+   * frames on different layers are resloved by the order of the layers).
+   */
   GPFrame *frames_array;
   int frames_size;
+
+  /**
+   * All attributes stored on the frames.
+   */
   CustomData frame_data;
-  int active_frame_index;
 
+  /**
+   * The array of grease pencil layers.
+   */
   GPLayer *layers_array;
   int layers_size;
+
+  /**
+   * The index of the active layer in the GPData.layers_array.
+   */
   int active_layer_index;
 
+  /**
+   * The root layer group. This must not be nullptr.
+   */
   GPLayerGroup *default_group;
 
+  /**
+   * The runtime data.
+   */
   GPDataRuntimeHandle *runtime;
 } GPData;
 
-/* This is the ID_GP structure that holds all the */
+/* This is the ID_GP structure that holds all the information at the object data level. */
 typedef struct GreasePencil {
   ID id;
   /* Animation data (must be immediately after id). */
@@ -78,6 +129,7 @@ typedef struct GreasePencil {
   /* Pointer to the actual data-block containing the frames, layers and layer groups. */
   GPData *grease_pencil_data;
 
+  /* GreasePencil flag. */
   int flag;
 
   /** Materials array. */
diff --git a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
index 93d5ae0541a..e6a3bc9064e 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
@@ -15,6 +15,7 @@ class GPLayerGroup : ::GPLayerGroup {
  public:
   GPLayerGroup()
   {
+    /* TODO */
   }
 
   ~GPLayerGroup()
@@ -31,7 +32,7 @@ class GPLayerGroup : ::GPLayerGroup {
 
 class GPDataRuntime {
  public:
-  mutable void *sbuffer;
+  /* mutable void *sbuffer */;
 };
 
 class GPLayer : public ::GPLayer {
@@ -46,6 +47,27 @@ class GPLayer : public ::GPLayer {
   }
 
   ~GPLayer() = default;
+
+  bool operator==(const GPLayer &other) const
+  {
+    return STREQ(this->name, other.name);
+  }
+};
+
+class GPFrame : public ::GPFrame {
+ public:
+  GPFrame()
+  {
+    this->layer_index = this->start = this->end = -1;
+  }
+
+  GPFrame(int layer_index)
+  {
+    this->layer_index = layer_index;
+    this->start = this->end = -1;
+  }
+
+  ~GPFrame() = default;
 };
 
 class GPData : public ::GPData {
@@ -103,6 +125,16 @@ class GPData : public ::GPData {
     this->runtime = nullptr;
   }
 
+  Span<GPFrame> frames() const
+  {
+    return {(const GPFrame *)this->frames_array, this->frames_size};
+  }
+
+  MutableSpan<GPFrame> frames_for_write()
+  {
+    return {(GPFrame *)this->frames_array, this->frames_size};
+  }
+
   Span<GPLayer> layers() const
   {
     return {(const GPLayer *)this->layers_array, this->layers_size};
@@ -121,10 +153,30 @@ class GPData : public ::GPData {
     }
 
     // Move new_layer to the end in the array.
-    this->layers_array[this->layers_size - 1] = new_layer;
+    this->layers_for_write().last() = new_layer;
     return true;
   }
 
+  const GPFrame &new_frame_on_layer(const int layer_index)
+  {
+    BLI_assert(layer_index >= 0 && layer_index < this->layers_size);
+
+    GPFrame new_frame(layer_index);
+    ensure_frame_array_has_size_at_least(this->frames_size + 1);
+    this->frames_for_write().last() = new_frame;
+
+    return this->frames().last();
+  }
+
+  const GPFrame &new_frame_on_layer(GPLayer &layer)
+  {
+    int index = this->layers().first_index_try(layer);
+    if (index == -1) {
+      return {};
+    }
+    return new_frame_on_layer(index);
+  }
+
  private:
   const bool ensure_layer_array_has_size_at_least(int64_t size)
   {
@@ -147,25 +199,33 @@ class GPData : public ::GPData {
 
     return true;
   }
-};
 
-}  // namespace blender::bke
+  const bool ensure_frame_array_has_size_at_least(int64_t size)
+  {
+    if (this->frames_size > size) {
+      return true;
+    }
 
-namespace blender::bke::gpencil::tests {
+    int old_size = this->frames_size;
+    this->frames_size = size;
 
-TEST(gpencil_proposal, Foo)
-{
-  //   GPData my_data;
-  //   GPLayer my_layer("FooLayer");
+    ::GPFrame *new_array = reinterpret_cast<::GPFrame *>(
+        MEM_calloc_arrayN(this->frames_size, sizeof(::GPFrame), __func__));
+    if (new_array == nullptr) {
+      return false;
+    }
 
-  //   my_data.add_layer(my_layer);
-  //   GPFrame my_frame = my_data.new_frame_on_layer(my_layer);
-  //   my_frame.set_start_and_end(5, 10);
+    memcpy(new_array, this->frames_array, old_size * sizeof(::GPFrame));
+    MEM_SAFE_FREE(this->frames_array);
+    this->frames_array = new_array;
 
-  //   GPStroke my_stroke(100);
-  //   fill_stroke_with_points(my_stroke);
-  //   my_frame.insert_stroke(my_stroke);
-}
+    return true;
+  }
+};
+
+}  // namespace blender::bke
+
+namespace blender::bke::gpencil::tests {
 
 TEST(gpencil_proposal, EmptyGPData)
 {
@@ -230,4 +290,16 @@ TEST(gpencil_proposal, ChangeLayerName)
   EXPECT_STREQ(my_data.layers().last().name, "BarLayer");
 }
 
+TEST(gpencil_proposal, AddFrameToLayer)
+{
+  GPData my_data;
+  GPLayer my_layer1("TestLayer1");
+  GPLayer my_layer2("TestLayer2");
+
+  my_data.add_layer(my_layer1);
+  my_data.add_layer(my_layer2);
+  GPFrame my_frame = my_data.new_frame_on_layer(my_layer2);
+  EXPECT_EQ(my_frame.layer_index, 1);
+}
+
 }  // namespace blender::bke::gpencil::tests
\ No newline at end of file



More information about the Bf-blender-cvs mailing list