Initial Grease Pencil 3.0 stage #106848

Merged
Falk David merged 224 commits from filedescriptor/blender:grease-pencil-v3 into main 2023-05-30 11:14:22 +02:00
3 changed files with 176 additions and 68 deletions
Showing only changes of commit 85c87d901c - Show all commits

View File

@ -63,15 +63,15 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
/* Duplicate drawing array. */
grease_pencil_dst->drawing_array_size = grease_pencil_src->drawing_array_size;
grease_pencil_dst->drawing_array = MEM_cnew_array<GreasePencilDrawingOrReference *>(
grease_pencil_dst->drawing_array = MEM_cnew_array<GreasePencilDrawingBase *>(
grease_pencil_src->drawing_array_size, __func__);
for (int i = 0; i < grease_pencil_src->drawing_array_size; i++) {
const GreasePencilDrawingOrReference *src_drawing_or_ref = grease_pencil_src->drawing_array[i];
switch (src_drawing_or_ref->type) {
const GreasePencilDrawingBase *src_drawing_base = grease_pencil_src->drawing_array[i];
switch (src_drawing_base->type) {
case GP_DRAWING: {
const GreasePencilDrawing *src_drawing = reinterpret_cast<const GreasePencilDrawing *>(
src_drawing_or_ref);
grease_pencil_dst->drawing_array[i] = reinterpret_cast<GreasePencilDrawingOrReference *>(
src_drawing_base);
grease_pencil_dst->drawing_array[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_cnew<GreasePencilDrawing>(__func__));
GreasePencilDrawing *dst_drawing = reinterpret_cast<GreasePencilDrawing *>(
grease_pencil_dst->drawing_array[i]);
@ -86,8 +86,8 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
}
case GP_DRAWING_REFERENCE: {
const GreasePencilDrawingReference *src_drawing_reference =
reinterpret_cast<const GreasePencilDrawingReference *>(src_drawing_or_ref);
grease_pencil_dst->drawing_array[i] = reinterpret_cast<GreasePencilDrawingOrReference *>(
reinterpret_cast<const GreasePencilDrawingReference *>(src_drawing_base);
grease_pencil_dst->drawing_array[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_dupallocN(src_drawing_reference));
break;
}
@ -128,10 +128,10 @@ static void grease_pencil_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, grease_pencil->material_array[i], IDWALK_CB_USER);
}
for (int i = 0; i < grease_pencil->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = grease_pencil->drawing_array[i];
if (drawing_or_ref->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
if (drawing_base->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, drawing_reference->id_reference, IDWALK_CB_USER);
}
}
@ -194,10 +194,10 @@ static void grease_pencil_blend_read_lib(BlendLibReader *reader, ID *id)
BLO_read_id_address(reader, grease_pencil->id.lib, &grease_pencil->material_array[i]);
}
for (int i = 0; i < grease_pencil->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = grease_pencil->drawing_array[i];
if (drawing_or_ref->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
if (drawing_base->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
BLO_read_id_address(reader, grease_pencil->id.lib, &drawing_reference->id_reference);
}
}
@ -210,10 +210,10 @@ static void grease_pencil_blend_read_expand(BlendExpander *expander, ID *id)
BLO_expand(expander, grease_pencil->material_array[i]);
}
for (int i = 0; i < grease_pencil->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = grease_pencil->drawing_array[i];
if (drawing_or_ref->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
if (drawing_base->type == GP_DRAWING_REFERENCE) {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
BLO_expand(expander, drawing_reference->id_reference);
}
}
@ -661,10 +661,10 @@ BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
/* FIXME: this should somehow go through the visible drawings. We don't have access to the
* scene time here, so we probably need to cache the visible drawing for each layer somehow. */
for (int i = 0; i < grease_pencil->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = grease_pencil->drawing_array[i];
switch (drawing_or_ref->type) {
GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i];
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
const blender::bke::CurvesGeometry &curves = drawing->geometry.wrap();
if (!curves.bounds_min_max(min, max)) {
@ -824,9 +824,8 @@ static void grease_pencil_grow_drawing_array_by(GreasePencil &self, const int ad
{
BLI_assert(add_capacity > 0);
const int new_drawing_array_size = self.drawing_array_size + add_capacity;
GreasePencilDrawingOrReference **new_drawing_array =
reinterpret_cast<GreasePencilDrawingOrReference **>(
MEM_cnew_array<GreasePencilDrawingOrReference *>(new_drawing_array_size, __func__));
GreasePencilDrawingBase **new_drawing_array = reinterpret_cast<GreasePencilDrawingBase **>(
MEM_cnew_array<GreasePencilDrawingBase *>(new_drawing_array_size, __func__));
blender::uninitialized_relocate_n(
self.drawing_array, self.drawing_array_size, new_drawing_array);
@ -839,9 +838,8 @@ static void grease_pencil_shrink_drawing_array_by(GreasePencil &self, const int
{
BLI_assert(remove_capacity > 0);
const int new_drawing_array_size = self.drawing_array_size - remove_capacity;
GreasePencilDrawingOrReference **new_drawing_array =
reinterpret_cast<GreasePencilDrawingOrReference **>(
MEM_cnew_array<GreasePencilDrawingOrReference *>(new_drawing_array_size, __func__));
GreasePencilDrawingBase **new_drawing_array = reinterpret_cast<GreasePencilDrawingBase **>(
MEM_cnew_array<GreasePencilDrawingBase *>(new_drawing_array_size, __func__));
blender::uninitialized_move_n(self.drawing_array, new_drawing_array_size, new_drawing_array);
MEM_freeN(self.drawing_array);
@ -850,16 +848,15 @@ static void grease_pencil_shrink_drawing_array_by(GreasePencil &self, const int
self.drawing_array_size = new_drawing_array_size;
}
blender::Span<GreasePencilDrawingOrReference *> GreasePencil::drawings() const
blender::Span<GreasePencilDrawingBase *> GreasePencil::drawings() const
{
return blender::Span<GreasePencilDrawingOrReference *>{this->drawing_array,
this->drawing_array_size};
return blender::Span<GreasePencilDrawingBase *>{this->drawing_array, this->drawing_array_size};
}
blender::MutableSpan<GreasePencilDrawingOrReference *> GreasePencil::drawings_for_write()
blender::MutableSpan<GreasePencilDrawingBase *> GreasePencil::drawings_for_write()
{
return blender::MutableSpan<GreasePencilDrawingOrReference *>{this->drawing_array,
this->drawing_array_size};
return blender::MutableSpan<GreasePencilDrawingBase *>{this->drawing_array,
this->drawing_array_size};
}
void GreasePencil::add_empty_drawings(int n)
@ -868,10 +865,10 @@ void GreasePencil::add_empty_drawings(int n)
BLI_assert(n > 0);
const int prev_size = this->drawings().size();
grease_pencil_grow_drawing_array_by(*this, n);
MutableSpan<GreasePencilDrawingOrReference *> new_drawings =
this->drawings_for_write().drop_front(prev_size);
MutableSpan<GreasePencilDrawingBase *> new_drawings = this->drawings_for_write().drop_front(
prev_size);
for (const int i : IndexRange(new_drawings.size())) {
new_drawings[i] = reinterpret_cast<GreasePencilDrawingOrReference *>(
new_drawings[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_new<GreasePencilDrawing>(__func__));
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(new_drawings[i]);
new (&drawing->geometry) bke::CurvesGeometry();
@ -913,12 +910,11 @@ void GreasePencil::remove_drawing(int index_to_remove)
}
/* Delete the last drawing. */
GreasePencilDrawingOrReference *drawing_or_ref_to_remove =
this->drawings_for_write()[last_drawing_index];
switch (drawing_or_ref_to_remove->type) {
GreasePencilDrawingBase *drawing_base_to_remove = this->drawings_for_write()[last_drawing_index];
switch (drawing_base_to_remove->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing_to_remove = reinterpret_cast<GreasePencilDrawing *>(
drawing_or_ref_to_remove);
drawing_base_to_remove);
drawing_to_remove->geometry.wrap().~CurvesGeometry();
MEM_delete(drawing_to_remove->runtime);
drawing_to_remove->runtime = nullptr;
@ -927,7 +923,7 @@ void GreasePencil::remove_drawing(int index_to_remove)
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference_to_remove =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref_to_remove);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base_to_remove);
MEM_freeN(drawing_reference_to_remove);
break;
}
@ -950,18 +946,18 @@ void GreasePencil::foreach_visible_drawing(
{
using namespace blender::bke::greasepencil;
blender::Span<GreasePencilDrawingOrReference *> drawings = this->drawings();
blender::Span<GreasePencilDrawingBase *> drawings = this->drawings();
for (const Layer *layer : this->layers()) {
int index = layer->drawing_index_at(frame);
if (index == -1) {
continue;
}
GreasePencilDrawingOrReference *drawing_or_reference = drawings[index];
if (drawing_or_reference->type == GP_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_reference);
GreasePencilDrawingBase *drawing_baseerence = drawings[index];
if (drawing_baseerence->type == GP_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_baseerence);
function(*drawing);
}
else if (drawing_or_reference->type == GP_DRAWING_REFERENCE) {
else if (drawing_baseerence->type == GP_DRAWING_REFERENCE) {
/* TODO */
}
}
@ -1007,10 +1003,10 @@ void GreasePencil::read_drawing_array(BlendDataReader *reader)
BLO_read_pointer_array(reader, (void **)&this->drawing_array);
for (int i = 0; i < this->drawing_array_size; i++) {
BLO_read_data_address(reader, &this->drawing_array[i]);
GreasePencilDrawingOrReference *drawing_or_ref = this->drawing_array[i];
switch (drawing_or_ref->type) {
GreasePencilDrawingBase *drawing_base = this->drawing_array[i];
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
drawing->geometry.wrap().blend_read(*reader);
/* Initialize runtime data. */
drawing->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
@ -1021,7 +1017,7 @@ void GreasePencil::read_drawing_array(BlendDataReader *reader)
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
BLO_read_data_address(reader, &drawing_reference->id_reference);
break;
}
@ -1033,17 +1029,17 @@ void GreasePencil::write_drawing_array(BlendWriter *writer)
{
BLO_write_pointer_array(writer, this->drawing_array_size, this->drawing_array);
for (int i = 0; i < this->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = this->drawing_array[i];
switch (drawing_or_ref->type) {
GreasePencilDrawingBase *drawing_base = this->drawing_array[i];
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
BLO_write_struct(writer, GreasePencilDrawing, drawing);
drawing->geometry.wrap().blend_write(*writer, this->id);
break;
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
BLO_write_struct(writer, GreasePencilDrawingReference, drawing_reference);
break;
}
@ -1057,10 +1053,10 @@ void GreasePencil::free_drawing_array()
return;
}
for (int i = 0; i < this->drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = this->drawing_array[i];
switch (drawing_or_ref->type) {
GreasePencilDrawingBase *drawing_base = this->drawing_array[i];
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
drawing->geometry.wrap().~CurvesGeometry();
MEM_delete(drawing->runtime);
drawing->runtime = nullptr;
@ -1069,7 +1065,7 @@ void GreasePencil::free_drawing_array()
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_or_ref);
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base);
MEM_freeN(drawing_reference);
break;
}

View File

@ -184,7 +184,7 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
}
grease_pencil.drawing_array_size = num_drawings;
grease_pencil.drawing_array = reinterpret_cast<GreasePencilDrawingOrReference **>(
grease_pencil.drawing_array = reinterpret_cast<GreasePencilDrawingBase **>(
MEM_cnew_array<GreasePencilDrawing *>(num_drawings, __func__));
int i = 0, layer_idx = 0;
@ -205,6 +205,9 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
SET_FLAG_FROM_TEST(new_layer.flag, (gpl->flag & GP_LAYER_FRAMELOCK), GP_LAYER_TREE_NODE_MUTE);
SET_FLAG_FROM_TEST(
new_layer.flag, (gpl->flag & GP_LAYER_USE_LIGHTS), GP_LAYER_TREE_NODE_USE_LIGHTS);
SET_FLAG_FROM_TEST(new_layer.flag,
(gpl->onion_flag & GP_LAYER_ONIONSKIN),
GP_LAYER_TREE_NODE_USE_ONION_SKINNING);
new_layer.parent_type = static_cast<int8_t>(gpl->partype);
new_layer.blend_mode = static_cast<int8_t>(gpl->blend_mode);
@ -233,7 +236,7 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
copy_v3_v3(new_layer.scale, gpl->scale);
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
grease_pencil.drawing_array[i] = reinterpret_cast<GreasePencilDrawingOrReference *>(
grease_pencil.drawing_array[i] = reinterpret_cast<GreasePencilDrawingBase *>(
MEM_new<GreasePencilDrawing>(__func__));
GreasePencilDrawing &drawing = *reinterpret_cast<GreasePencilDrawing *>(
grease_pencil.drawing_array[i]);
@ -249,6 +252,20 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
}
}
/* Convert the onion skinning settings. */
grease_pencil.onion_skinning_settings.opacity = gpd.onion_factor;
grease_pencil.onion_skinning_settings.mode = gpd.onion_mode;
if (gpd.onion_keytype == -1) {
grease_pencil.onion_skinning_settings.filter = GREASE_PENCIL_ONION_SKINNING_FILTER_ALL;
}
else {
grease_pencil.onion_skinning_settings.filter = (1 << gpd.onion_keytype);
}
grease_pencil.onion_skinning_settings.num_frames_before = gpd.gstep;
grease_pencil.onion_skinning_settings.num_frames_after = gpd.gstep_next;
copy_v3_v3(grease_pencil.onion_skinning_settings.color_before, gpd.gcolor_prev);
copy_v3_v3(grease_pencil.onion_skinning_settings.color_after, gpd.gcolor_next);
grease_pencil.runtime->set_active_layer_index(active_layer_index);
BKE_id_materials_copy(&bmain, &gpd.id, &grease_pencil.id);

View File

@ -47,12 +47,28 @@ typedef enum GreasePencilStrokeCapType {
GP_STROKE_CAP_TYPE_MAX,
} GreasePencilStrokeCapType;
/**
* Type of drawing data.
* If `GP_DRAWING` the node is a `GreasePencilDrawing`,
* if `GP_DRAWING_REFERENCE` the node is a `GreasePencilDrawingReference`.
*/
typedef enum GreasePencilDrawingType {
GP_DRAWING = 0,
GP_DRAWING_REFERENCE = 1,
} GreasePencilDrawingType;
typedef struct GreasePencilDrawingOrReference {
/**
* Flag for drawings and drawing references. #GreasePencilDrawingBase.flag
*/
typedef enum GreasePencilDrawingBaseFlag {
/* TODO */
GreasePencilDrawingBaseFlag_TODO
} GreasePencilDrawingBaseFlag;
/**
* Base class for drawings and drawing references (drawings from other objects).
*/
typedef struct GreasePencilDrawingBase {
/**
* One of `GreasePencilDrawingType`.
* Indicates if this is an actual drawing or a drawing referenced from another object.
@ -60,17 +76,17 @@ typedef struct GreasePencilDrawingOrReference {
int8_t type;
char _pad[3];
/**
* Flag. Used to set e.g. the selection status.
* Flag. Used to set e.g. the selection status. See `GreasePencilDrawingBaseFlag`.
*/
uint32_t flag;
} GreasePencilDrawingOrReference;
} GreasePencilDrawingBase;
/**
* A grease pencil drawing is a set of strokes. The data is stored using the `CurvesGeometry` data
* structure and the custom attributes within it.
*/
typedef struct GreasePencilDrawing {
GreasePencilDrawingOrReference base;
GreasePencilDrawingBase base;
/**
* The stroke data for this drawing.
*/
@ -94,7 +110,7 @@ typedef struct GreasePencilDrawing {
} GreasePencilDrawing;
typedef struct GreasePencilDrawingReference {
GreasePencilDrawingOrReference base;
GreasePencilDrawingBase base;
/**
* A reference to another GreasePencil data-block.
* If the data-block has multiple drawings, this drawing references all of them sequentially.
@ -237,6 +253,11 @@ typedef struct GreasePencilLayer {
float location[3], rotation[3], scale[3];
} GreasePencilLayer;
/**
* Type of layer node.
* If `GP_LAYER_TREE_LEAF` the node is a `GreasePencilLayerTreeLeaf`,
* if `GP_LAYER_TREE_GROUP` the node is a `GreasePencilLayerTreeGroup`.
*/
typedef enum GreasePencilLayerTreeNodeType {
GP_LAYER_TREE_LEAF = 0,
GP_LAYER_TREE_GROUP = 1,
@ -251,6 +272,7 @@ typedef enum GreasePencilLayerTreeNodeFlag {
GP_LAYER_TREE_NODE_SELECT = (1 << 2),
GP_LAYER_TREE_NODE_MUTE = (1 << 3),
GP_LAYER_TREE_NODE_USE_LIGHTS = (1 << 4),
GP_LAYER_TREE_NODE_USE_ONION_SKINNING = (1 << 5),
} GreasePencilLayerTreeNodeFlag;
typedef struct GreasePencilLayerTreeNode {
@ -297,6 +319,77 @@ typedef struct GreasePencilLayerTreeStorage {
int active_layer_index;
} GreasePencilLayerTreeStorage;
/**
* Flag for the grease pencil data-block. #GreasePencil.flag
*/
typedef enum GreasePencilFlag {
/* TODO */
GreasePencilFlag_TODO
} GreasePencilFlag;
/**
* Onion skinning mode. #GreasePencilOnionSkinningSettings.mode
*/
typedef enum GreasePencilOnionSkinningMode {
GP_ONION_SKINNING_MODE_ABSOLUTE = 0,
GP_ONION_SKINNING_MODE_RELATIVE = 1,
GP_ONION_SKINNING_MODE_SELECTED = 2,
} GreasePencilOnionSkinningMode;
/**
* Flag for filtering the onion skinning per keyframe type.
* #GreasePencilOnionSkinningSettings.filter
* \note needs to match order of `eBezTriple_KeyframeType`.
*/
typedef enum GreasePencilOnionSkinningFilter {
GP_ONION_SKINNING_FILTER_KEYTYPE_KEYFRAME = (1 << 0),
GP_ONION_SKINNING_FILTER_KEYTYPE_EXTREME = (1 << 1),
GP_ONION_SKINNING_FILTER_KEYTYPE_BREAKDOWN = (1 << 2),
GP_ONION_SKINNING_FILTER_KEYTYPE_JITTER = (1 << 3),
GP_ONION_SKINNING_FILTER_KEYTYPE_MOVEHOLD = (1 << 4),
} GreasePencilOnionSkinningFilter;
#define GREASE_PENCIL_ONION_SKINNING_FILTER_ALL \
(GP_ONION_SKINNING_FILTER_KEYTYPE_KEYFRAME | GP_ONION_SKINNING_FILTER_KEYTYPE_EXTREME | \
GP_ONION_SKINNING_FILTER_KEYTYPE_BREAKDOWN | GP_ONION_SKINNING_FILTER_KEYTYPE_JITTER | \
GP_ONION_SKINNING_FILTER_KEYTYPE_MOVEHOLD)
/**
* Per data-block Grease Pencil onion skinning settings.
*/
typedef struct GreasePencilOnionSkinningSettings {
/**
* Opacity for the ghost frames.
*/
float opacity;
/**
* Onion skinning mode. See `GreasePencilOnionSkinningMode`.
*/
int8_t mode;
/**
* Onion skinning filtering flag. See `GreasePencilOnionSkinningFilter`.
*/
uint8_t filter;
char _pad[2];
/**
* Number of ghost frames shown before.
*/
int16_t num_frames_before;
/**
* Number of ghost frames shown after.
*/
int16_t num_frames_after;
/**
* Color of the ghost frames before.
*/
float color_before[3];
/**
* Color of the ghost frames after.
*/
float color_after[3];
char _pad2[4];
} GreasePencilOnionSkinningSettings;
/**
* The grease pencil data-block.
*/
@ -310,7 +403,7 @@ typedef struct GreasePencil {
* data-block. Note that the order of this array is arbitrary. The mapping of drawings to frames
* is done by the layers. See the `Layer` class in `BKE_grease_pencil.hh`.
*/
GreasePencilDrawingOrReference **drawing_array;
GreasePencilDrawingBase **drawing_array;
int drawing_array_size;
char _pad[4];
#ifdef __cplusplus
@ -333,19 +426,21 @@ typedef struct GreasePencil {
struct Material **material_array;
short material_array_size;
char _pad2[2];
/**
* Global flag on the data-block.
*/
uint32_t flag;
/**
* Onion skinning settings.
*/
GreasePencilOnionSkinningSettings onion_skinning_settings;
/**
* Runtime struct pointer.
*/
GreasePencilRuntimeHandle *runtime;
#ifdef __cplusplus
blender::Span<GreasePencilDrawingOrReference *> drawings() const;
blender::MutableSpan<GreasePencilDrawingOrReference *> drawings_for_write();
blender::Span<GreasePencilDrawingBase *> drawings() const;
blender::MutableSpan<GreasePencilDrawingBase *> drawings_for_write();
void add_empty_drawings(int n);
void remove_drawing(int index);
void foreach_visible_drawing(int frame,