[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