GPv3: Python API for frame, drawing and drawing attributes #124787
@ -27,6 +27,7 @@ struct Mesh;
|
||||
struct PointCloud;
|
||||
struct Curves;
|
||||
struct GreasePencil;
|
||||
struct GreasePencilDrawing;
|
||||
|
||||
typedef enum AttrDomainMask {
|
||||
ATTR_DOMAIN_MASK_POINT = (1 << 0),
|
||||
@ -44,6 +45,7 @@ enum class AttributeOwnerType {
|
||||
PointCloud,
|
||||
Curves,
|
||||
GreasePencil,
|
||||
GreasePencilDrawing,
|
||||
};
|
||||
|
||||
class AttributeOwner {
|
||||
@ -63,6 +65,7 @@ class AttributeOwner {
|
||||
PointCloud *get_pointcloud() const;
|
||||
Curves *get_curves() const;
|
||||
GreasePencil *get_grease_pencil() const;
|
||||
GreasePencilDrawing *get_grease_pencil_drawing() const;
|
||||
};
|
||||
|
||||
#define ATTR_DOMAIN_AS_MASK(domain) ((AttrDomainMask)((1 << (int)(domain))))
|
||||
|
@ -1003,6 +1003,9 @@ inline bool GreasePencil::has_active_group() const
|
||||
return (this->active_node != nullptr) && (this->active_node->wrap().is_group());
|
||||
}
|
||||
|
||||
bool BKE_grease_pencil_drawing_attribute_required(const GreasePencilDrawing * /*drawing*/,
|
||||
const char *name);
|
||||
|
||||
void *BKE_grease_pencil_add(Main *bmain, const char *name);
|
||||
GreasePencil *BKE_grease_pencil_new_nomain();
|
||||
GreasePencil *BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src);
|
||||
|
@ -97,6 +97,13 @@ GreasePencil *AttributeOwner::get_grease_pencil() const
|
||||
return reinterpret_cast<GreasePencil *>(ptr_);
|
||||
}
|
||||
|
||||
GreasePencilDrawing *AttributeOwner::get_grease_pencil_drawing() const
|
||||
{
|
||||
BLI_assert(this->is_valid());
|
||||
BLI_assert(type_ == AttributeOwnerType::GreasePencilDrawing);
|
||||
return reinterpret_cast<GreasePencilDrawing *>(ptr_);
|
||||
}
|
||||
|
||||
struct DomainInfo {
|
||||
CustomData *customdata = nullptr;
|
||||
int length = 0;
|
||||
@ -152,6 +159,14 @@ static std::array<DomainInfo, ATTR_DOMAIN_NUM> get_domains(const AttributeOwner
|
||||
info[int(AttrDomain::Layer)].length = grease_pencil->layers().size();
|
||||
break;
|
||||
}
|
||||
case AttributeOwnerType::GreasePencilDrawing: {
|
||||
blender::bke::greasepencil::Drawing &drawing = owner.get_grease_pencil_drawing()->wrap();
|
||||
info[int(AttrDomain::Point)].customdata = &drawing.geometry.point_data;
|
||||
info[int(AttrDomain::Point)].length = drawing.geometry.point_num;
|
||||
info[int(AttrDomain::Curve)].customdata = &drawing.geometry.curve_data;
|
||||
info[int(AttrDomain::Curve)].length = drawing.geometry.curve_num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
@ -182,6 +197,10 @@ static std::optional<blender::bke::MutableAttributeAccessor> get_attribute_acces
|
||||
GreasePencil &grease_pencil = *owner.get_grease_pencil();
|
||||
return grease_pencil.attributes_for_write();
|
||||
}
|
||||
case AttributeOwnerType::GreasePencilDrawing: {
|
||||
blender::bke::greasepencil::Drawing &drawing = owner.get_grease_pencil_drawing()->wrap();
|
||||
return drawing.strokes_for_write().attributes_for_write();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -763,6 +782,8 @@ bool BKE_attribute_required(const AttributeOwner &owner, const char *name)
|
||||
return BKE_mesh_attribute_required(name);
|
||||
case AttributeOwnerType::GreasePencil:
|
||||
return false;
|
||||
case AttributeOwnerType::GreasePencilDrawing:
|
||||
return BKE_grease_pencil_drawing_attribute_required(owner.get_grease_pencil_drawing(), name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -825,6 +846,9 @@ int *BKE_attributes_active_index_p(AttributeOwner &owner)
|
||||
case AttributeOwnerType::GreasePencil: {
|
||||
return &(owner.get_grease_pencil())->attributes_active_index;
|
||||
}
|
||||
case AttributeOwnerType::GreasePencilDrawing: {
|
||||
return &(owner.get_grease_pencil_drawing())->attributes_active_index;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ using blender::Span;
|
||||
using blender::uint3;
|
||||
using blender::VectorSet;
|
||||
|
||||
static const char *ATTR_POSITION = "position";
|
||||
|
||||
/* Forward declarations. */
|
||||
static void read_drawing_array(GreasePencil &grease_pencil, BlendDataReader *reader);
|
||||
static void write_drawing_array(GreasePencil &grease_pencil, BlendWriter *writer);
|
||||
@ -1735,6 +1737,12 @@ std::optional<MutableSpan<float3>> GreasePencilDrawingEditHints::positions_for_w
|
||||
/** \name Grease Pencil kernel functions
|
||||
* \{ */
|
||||
|
||||
bool BKE_grease_pencil_drawing_attribute_required(const GreasePencilDrawing * /*drawing*/,
|
||||
const char *name)
|
||||
{
|
||||
return STREQ(name, ATTR_POSITION);
|
||||
}
|
||||
|
||||
void *BKE_grease_pencil_add(Main *bmain, const char *name)
|
||||
{
|
||||
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(BKE_id_new(bmain, ID_GP, name));
|
||||
|
@ -105,6 +105,8 @@ typedef struct GreasePencilDrawing {
|
||||
* The stroke data for this drawing.
|
||||
*/
|
||||
CurvesGeometry geometry;
|
||||
int attributes_active_index;
|
||||
char _pad[4];
|
||||
/**
|
||||
* Runtime data on the drawing.
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "DNA_curves_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_pointcloud_types.h"
|
||||
@ -181,6 +182,49 @@ const EnumPropertyItem rna_enum_attribute_curves_domain_items[] = {
|
||||
|
||||
# include "WM_api.hh"
|
||||
|
||||
static AttributeOwner owner_from_attribute_pointer_rna(PointerRNA *ptr)
|
||||
{
|
||||
ID *owner_id = static_cast<ID *>(ptr->owner_id);
|
||||
const CustomDataLayer *layer = static_cast<const CustomDataLayer *>(ptr->data);
|
||||
if (GS(owner_id->name) == ID_GP) {
|
||||
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(owner_id);
|
||||
/* First check the layer attributes. */
|
||||
CustomData *layers_data = &grease_pencil->layers_data;
|
||||
for (int i = 0; i < layers_data->totlayer; i++) {
|
||||
if (&layers_data->layers[i] == layer) {
|
||||
return AttributeOwner(AttributeOwnerType::GreasePencil, grease_pencil);
|
||||
}
|
||||
}
|
||||
/* Now check all the drawings. */
|
||||
for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
|
||||
if (base->type == GP_DRAWING) {
|
||||
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(base);
|
||||
CustomData *curve_data = &drawing->geometry.curve_data;
|
||||
for (int i = 0; i < curve_data->totlayer; i++) {
|
||||
if (&curve_data->layers[i] == layer) {
|
||||
return AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
|
||||
}
|
||||
}
|
||||
CustomData *point_data = &drawing->geometry.point_data;
|
||||
for (int i = 0; i < point_data->totlayer; i++) {
|
||||
if (&point_data->layers[i] == layer) {
|
||||
return AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return AttributeOwner::from_id(ptr->owner_id);
|
||||
}
|
||||
|
||||
static AttributeOwner owner_from_pointer_rna(PointerRNA *ptr)
|
||||
{
|
||||
if (ptr->type == &RNA_GreasePencilDrawing) {
|
||||
return AttributeOwner(AttributeOwnerType::GreasePencilDrawing, ptr->data);
|
||||
}
|
||||
return AttributeOwner::from_id(ptr->owner_id);
|
||||
}
|
||||
|
||||
/* Attribute */
|
||||
|
||||
static std::optional<std::string> rna_Attribute_path(const PointerRNA *ptr)
|
||||
@ -232,14 +276,14 @@ static StructRNA *rna_Attribute_refine(PointerRNA *ptr)
|
||||
static void rna_Attribute_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
|
||||
BKE_attribute_rename(owner, layer->name, value, nullptr);
|
||||
}
|
||||
|
||||
static int rna_Attribute_name_editable(const PointerRNA *ptr, const char **r_info)
|
||||
{
|
||||
CustomDataLayer *layer = static_cast<CustomDataLayer *>(ptr->data);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
AttributeOwner owner = owner_from_attribute_pointer_rna(const_cast<PointerRNA *>(ptr));
|
||||
if (BKE_attribute_required(owner, layer->name)) {
|
||||
*r_info = N_("Cannot modify name of required geometry attribute");
|
||||
return false;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
@ -73,6 +74,174 @@ static void rna_grease_pencil_dependency_update(Main *bmain, Scene * /*scene*/,
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, rna_grease_pencil(ptr));
|
||||
}
|
||||
|
||||
static void rna_GreasePencilLayer_frames_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(ptr->data)->wrap();
|
||||
blender::Span<FramesMapKeyT> sorted_keys = layer.sorted_keys();
|
||||
|
||||
rna_iterator_array_begin(
|
||||
iter, (void *)sorted_keys.data(), sizeof(FramesMapKeyT), sorted_keys.size(), false, nullptr);
|
||||
}
|
||||
|
||||
static PointerRNA rna_GreasePencilLayer_frames_get(CollectionPropertyIterator *iter)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
const FramesMapKeyT frame_key = *static_cast<FramesMapKeyT *>(rna_iterator_array_get(iter));
|
||||
const Layer &layer = static_cast<GreasePencilLayer *>(iter->parent.data)->wrap();
|
||||
const GreasePencilFrame *frame = layer.frames().lookup_ptr(frame_key);
|
||||
return rna_pointer_inherit_refine(&iter->parent,
|
||||
&RNA_GreasePencilFrame,
|
||||
static_cast<void *>(const_cast<GreasePencilFrame *>(frame)));
|
||||
}
|
||||
|
||||
static int rna_GreasePencilLayer_frames_length(PointerRNA *ptr)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(ptr->data)->wrap();
|
||||
return layer.frames().size();
|
||||
}
|
||||
|
||||
static bool rna_GreasePencilLayer_frames_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
GreasePencil &grease_pencil = *rna_grease_pencil(ptr);
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(ptr->data)->wrap();
|
||||
if (index < 0 || index >= layer.sorted_keys().size()) {
|
||||
return false;
|
||||
}
|
||||
const FramesMapKeyT frame_key = layer.sorted_keys()[index];
|
||||
const GreasePencilFrame *frame = layer.frames().lookup_ptr(frame_key);
|
||||
|
||||
r_ptr->owner_id = &grease_pencil.id;
|
||||
r_ptr->type = &RNA_GreasePencilFrame;
|
||||
r_ptr->data = static_cast<void *>(const_cast<GreasePencilFrame *>(frame));
|
||||
return true;
|
||||
}
|
||||
|
||||
static GreasePencilFrame *rna_Frames_frame_new(ID *id,
|
||||
GreasePencilLayer *layer_in,
|
||||
ReportList *reports,
|
||||
int frame_number)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(layer_in)->wrap();
|
||||
|
||||
if (layer.frames().contains(frame_number)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Frame already exists on frame number %d", frame_number);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
grease_pencil.insert_frame(layer, frame_number, 0, BEZT_KEYTYPE_KEYFRAME);
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
|
||||
|
||||
return layer.frame_at(frame_number);
|
||||
}
|
||||
|
||||
static void rna_Frames_frame_remove(ID *id,
|
||||
GreasePencilLayer *layer_in,
|
||||
ReportList *reports,
|
||||
int frame_number)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(layer_in)->wrap();
|
||||
|
||||
if (!layer.frames().contains(frame_number)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Frame doesn't exists on frame number %d", frame_number);
|
||||
return;
|
||||
}
|
||||
|
||||
if (grease_pencil.remove_frames(layer, {frame_number})) {
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
|
||||
}
|
||||
}
|
||||
|
||||
static GreasePencilFrame *rna_Frames_frame_copy(ID *id,
|
||||
GreasePencilLayer *layer_in,
|
||||
ReportList *reports,
|
||||
int from_frame_number,
|
||||
int to_frame_number,
|
||||
bool instance_drawing)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
|
||||
Layer &layer = static_cast<GreasePencilLayer *>(layer_in)->wrap();
|
||||
|
||||
if (!layer.frames().contains(from_frame_number)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Frame doesn't exists on frame number %d", from_frame_number);
|
||||
return nullptr;
|
||||
}
|
||||
if (layer.frames().contains(to_frame_number)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Frame already exists on frame number %d", to_frame_number);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
grease_pencil.insert_duplicate_frame(
|
||||
layer, from_frame_number, to_frame_number, instance_drawing);
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
|
||||
|
||||
return layer.frame_at(to_frame_number);
|
||||
}
|
||||
|
||||
static std::pair<int, const blender::bke::greasepencil::Layer *> find_layer_of_frame(
|
||||
const GreasePencil &grease_pencil, const GreasePencilFrame &find_frame)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
for (const Layer *layer : grease_pencil.layers()) {
|
||||
for (const auto &[key, frame] : layer->frames().items()) {
|
||||
if (&frame == &find_frame) {
|
||||
return {int(key), layer};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {0, nullptr};
|
||||
}
|
||||
|
||||
static PointerRNA rna_Frame_drawing_get(PointerRNA *ptr)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
const GreasePencil &grease_pencil = *rna_grease_pencil(ptr);
|
||||
GreasePencilFrame &frame_to_find = *static_cast<GreasePencilFrame *>(ptr->data);
|
||||
if (frame_to_find.is_end()) {
|
||||
return PointerRNA_NULL;
|
||||
}
|
||||
|
||||
/* RNA doesn't give access to the parented layer object, so we have to iterate over all layers
|
||||
* and search for the matching GreasePencilFrame pointer in the frames collection. */
|
||||
auto [frame_number, this_layer] = find_layer_of_frame(grease_pencil, frame_to_find);
|
||||
if (this_layer == nullptr) {
|
||||
return PointerRNA_NULL;
|
||||
}
|
||||
|
||||
const Drawing *drawing = grease_pencil.get_drawing_at(*this_layer, frame_number);
|
||||
return rna_pointer_inherit_refine(
|
||||
ptr, &RNA_GreasePencilDrawing, static_cast<void *>(const_cast<Drawing *>(drawing)));
|
||||
}
|
||||
|
||||
static int rna_Frame_frame_number_get(PointerRNA *ptr)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
const GreasePencil &grease_pencil = *rna_grease_pencil(ptr);
|
||||
GreasePencilFrame &frame_to_find = *static_cast<GreasePencilFrame *>(ptr->data);
|
||||
|
||||
/* RNA doesn't give access to the parented layer object, so we have to iterate over all layers
|
||||
* and search for the matching GreasePencilFrame pointer in the frames collection. */
|
||||
auto [frame_number, this_layer] = find_layer_of_frame(grease_pencil, frame_to_find);
|
||||
/* Layer should exist. */
|
||||
BLI_assert(this_layer != nullptr);
|
||||
return frame_number;
|
||||
}
|
||||
|
||||
static void rna_Frame_frame_number_index_range(
|
||||
PointerRNA * /*ptr*/, int *min, int *max, int * /*softmin*/, int * /*softmax*/)
|
||||
{
|
||||
*min = MINAFRAME;
|
||||
*max = MAXFRAME;
|
||||
}
|
||||
|
||||
static void rna_grease_pencil_layer_mask_name_get(PointerRNA *ptr, char *dst)
|
||||
{
|
||||
filedescriptor marked this conversation as resolved
Outdated
|
||||
using namespace blender;
|
||||
@ -127,6 +296,13 @@ static void rna_grease_pencil_active_mask_index_range(
|
||||
*max = max_ii(0, BLI_listbase_count(&layer->masks) - 1);
|
||||
}
|
||||
|
||||
static GreasePencilFrame *rna_GreasePencilLayer_get_frame_at(GreasePencilLayer *layer,
|
||||
int frame_number)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
return static_cast<Layer *>(layer)->frame_at(frame_number);
|
||||
}
|
||||
|
||||
static void rna_iterator_grease_pencil_layers_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
@ -541,6 +717,139 @@ static int rna_iterator_grease_pencil_layer_groups_length(PointerRNA *ptr)
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_grease_pencil_drawing(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem rna_enum_drawing_type_items[] = {
|
||||
{GP_DRAWING, "DRAWING", 0, "Drawing", ""},
|
||||
{GP_DRAWING_REFERENCE, "REFERENCE", 0, "Reference", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr}};
|
||||
|
||||
srna = RNA_def_struct(brna, "GreasePencilDrawing", nullptr);
|
||||
RNA_def_struct_sdna(srna, "GreasePencilDrawing");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Drawing", "A Grease Pencil drawing");
|
||||
|
||||
/* Type. */
|
||||
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "base.type");
|
||||
RNA_def_property_enum_items(prop, rna_enum_drawing_type_items);
|
||||
RNA_def_parameter_clear_flags(prop, PROP_EDITABLE, ParameterFlag(0));
|
||||
RNA_def_property_ui_text(prop, "Type", "Drawing type");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
|
||||
|
||||
/* Attributes. */
|
||||
rna_def_attributes_common(srna);
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_frame(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GreasePencilFrame", nullptr);
|
||||
RNA_def_struct_sdna(srna, "GreasePencilFrame");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Frame", "A Grease Pencil keyframe");
|
||||
|
||||
/* Drawing. */
|
||||
prop = RNA_def_property(srna, "drawing", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GreasePencilDrawing");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Frame_drawing_get", nullptr, nullptr, nullptr);
|
||||
RNA_def_property_ui_text(prop, "Drawing", "A Grease Pencil drawing");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
|
||||
|
||||
/* Frame number. */
|
||||
prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE);
|
||||
/* TODO: Make property editable, ensure frame number isn't already in use. */
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_int_funcs(
|
||||
prop, "rna_Frame_frame_number_get", nullptr, "rna_Frame_frame_number_index_range");
|
||||
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
|
||||
RNA_def_property_ui_text(prop, "Frame Number", "The frame number in the scene");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
|
||||
|
||||
/* Selection status. */
|
||||
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_FRAME_SELECTED);
|
||||
RNA_def_property_ui_text(prop, "Select", "Frame Selection in the Dope Sheet");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "GreasePencilFrames");
|
||||
srna = RNA_def_struct(brna, "GreasePencilFrames", nullptr);
|
||||
RNA_def_struct_sdna(srna, "GreasePencilLayer");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of Grease Pencil frames");
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_Frames_frame_new");
|
||||
RNA_def_function_ui_description(func, "Add a new Grease Pencil frame");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
parm = RNA_def_int(func,
|
||||
"frame_number",
|
||||
1,
|
||||
MINAFRAME,
|
||||
MAXFRAME,
|
||||
"Frame Number",
|
||||
"The frame on which the drawing appears",
|
||||
MINAFRAME,
|
||||
MAXFRAME);
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
parm = RNA_def_pointer(func, "frame", "GreasePencilFrame", "", "The newly created frame");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_Frames_frame_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a Grease Pencil frame");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
parm = RNA_def_int(func,
|
||||
"frame_number",
|
||||
1,
|
||||
MINAFRAME,
|
||||
MAXFRAME,
|
||||
"Frame Number",
|
||||
"The frame number of the frame to remove",
|
||||
MINAFRAME,
|
||||
MAXFRAME);
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
|
||||
func = RNA_def_function(srna, "copy", "rna_Frames_frame_copy");
|
||||
RNA_def_function_ui_description(func, "Copy a Grease Pencil frame");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
parm = RNA_def_int(func,
|
||||
"from_frame_number",
|
||||
1,
|
||||
MINAFRAME,
|
||||
MAXFRAME,
|
||||
"Source Frame Number",
|
||||
"The frame number of the source frame",
|
||||
MINAFRAME,
|
||||
MAXFRAME);
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
parm = RNA_def_int(func,
|
||||
"to_frame_number",
|
||||
2,
|
||||
filedescriptor marked this conversation as resolved
Outdated
Bastien Montagne
commented
Usually API definition should go into its own RNA file ( Usually API definition should go into its own RNA file (`rna_grease_pencil_api.cc`)?
Falk David
commented
Does this mean I should add a file+function for Does this mean I should add a file+function for `frames`, `layer`, `layers`, `layer_mask`, `layer_group` ?
Bastien Montagne
commented
yes, one new file, and then move all the These API definition functions are also declared in the yes, one new file, and then move all the `rna_def_xxx_api()` functions there (they are also usually name `RNA_api_xxx`, see e.g. `rna_mesh_api.cc` and its `RNA_api_mesh()` definition function.
These API definition functions are also declared in the `rna_internal.hh` file.
|
||||
MINAFRAME,
|
||||
MAXFRAME,
|
||||
"Frame Number of Copy",
|
||||
"The frame number to copy the frame to",
|
||||
MINAFRAME,
|
||||
MAXFRAME);
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
parm = RNA_def_boolean(func,
|
||||
"instance_drawing",
|
||||
false,
|
||||
"Instance Drawing",
|
||||
"Let the copied frame use the same drawing as the source");
|
||||
parm = RNA_def_pointer(func, "copy", "GreasePencilFrame", "", "The newly copied frame");
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_layers_mask_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -595,6 +904,20 @@ static void rna_def_grease_pencil_layer_mask(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_layer_api(StructRNA *srna)
|
||||
{
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
func = RNA_def_function(srna, "get_frame_at", "rna_GreasePencilLayer_get_frame_at");
|
||||
RNA_def_function_ui_description(func, "Get the frame at given frame number");
|
||||
parm = RNA_def_int(
|
||||
func, "frame_number", 1, MINAFRAME, MAXFRAME, "Frame Number", "", MINAFRAME, MAXFRAME);
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
parm = RNA_def_pointer(func, "frame", "GreasePencilFrame", "Frame", "");
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_layer(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -626,6 +949,21 @@ static void rna_def_grease_pencil_layer(BlenderRNA *brna)
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_RENAME, "rna_grease_pencil_update");
|
||||
|
||||
/* Frames. */
|
||||
prop = RNA_def_property(srna, "frames", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GreasePencilFrame");
|
||||
RNA_def_property_ui_text(prop, "Frames", "Grease Pencil frames");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_GreasePencilLayer_frames_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_GreasePencilLayer_frames_get",
|
||||
"rna_GreasePencilLayer_frames_length",
|
||||
"rna_GreasePencilLayer_frames_lookup_int",
|
||||
nullptr,
|
||||
nullptr);
|
||||
rna_def_grease_pencil_frames_api(brna, prop);
|
||||
|
||||
/* Mask Layers */
|
||||
prop = RNA_def_property(srna, "mask_layers", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, nullptr, "masks", nullptr);
|
||||
@ -794,6 +1132,8 @@ static void rna_def_grease_pencil_layer(BlenderRNA *brna)
|
||||
prop, "rna_GreasePencilLayer_parent_layer_group_get", nullptr, nullptr, nullptr);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Parent Layer Group", "The parent layer group this layer is part of");
|
||||
|
||||
rna_def_grease_pencil_layer_api(srna);
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
@ -1274,6 +1614,8 @@ void RNA_def_grease_pencil(BlenderRNA *brna)
|
||||
rna_def_grease_pencil_layer(brna);
|
||||
rna_def_grease_pencil_layer_mask(brna);
|
||||
rna_def_grease_pencil_layer_group(brna);
|
||||
rna_def_grease_pencil_frame(brna);
|
||||
rna_def_grease_pencil_drawing(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user
Not sure I understand why you need to define and use this callback?