Commit: 5788f6cc37a9277032ae919741652784ee11018d Author: Falk David Date: Thu May 5 11:07:17 2022 +0200 Branches: gpencil-new-data-proposal https://developer.blender.org/rB5788f6cc37a9277032ae919741652784ee11018d
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..06cffb3e959 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 { @@ -65,11 +87,9 @@ class GPData : public ::GPData { if (this->frames_size > 0) { this->frames_array = reinterpret_cast<::GPFrame *>( MEM_calloc_arrayN(this->frames_size, sizeof(::GPFrame), __func__)); - this->active_frame_index = 0; } else { this->frames_array = nullptr; - this->active_frame_index = -1; } CustomData_reset(&this->frame_data); @@ -103,6 +123,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 +151,28 @@ 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); + BLI_assert(index != -1); + return new_frame_on_layer(index); + } + private: const bool ensure_layer_array_has_size_at_least(int64_t size) { @@ -147,25 +195,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 +286,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 _______________________________________________ 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