Files
test/source/blender/makesrna/intern/rna_attribute.cc
Dalai Felinto 1584cd9aa5 Cleanup: Rename point cloud to pointcloud / POINT_CLOUD to POINTCLOUD
Though "Point Cloud" written as two words is technically correct and should be used in the UI, as one word it's typically easier to write and parse when reading. We had a mix of both before this patch, so better to unify this as well.

This commit also renames the editor/intern/ files to remove pointcloud_ prefix.
point_cloud was only preserved on the user facing strings:

* is_type_point_cloud
* use_new_point_cloud_type

Pull Request: https://projects.blender.org/blender/blender/pulls/134803
2025-02-19 17:11:08 +01:00

1861 lines
75 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup RNA
*/
#include <cstdlib>
#include "RNA_define.hh"
#include "RNA_enum_types.hh"
#include "rna_internal.hh"
#include "DNA_customdata_types.h"
#include "BKE_attribute.hh"
#include "WM_types.hh"
using blender::bke::AttrDomain;
const EnumPropertyItem rna_enum_attribute_type_items[] = {
{CD_PROP_FLOAT, "FLOAT", 0, "Float", "Floating-point value"},
{CD_PROP_INT32, "INT", 0, "Integer", "32-bit integer"},
{CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating-point values"},
{CD_PROP_COLOR, "FLOAT_COLOR", 0, "Color", "RGBA color with 32-bit floating-point values"},
{CD_PROP_BYTE_COLOR,
"BYTE_COLOR",
0,
"Byte Color",
"RGBA color with 8-bit positive integer values"},
{CD_PROP_STRING, "STRING", 0, "String", "Text string"},
{CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"},
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
{CD_PROP_INT8, "INT8", 0, "8-Bit Integer", "Smaller integer with a range from -128 to 127"},
{CD_PROP_INT16_2D, "INT16_2D", 0, "2D 16-Bit Integer Vector", "16-bit signed integer vector"},
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
{CD_PROP_QUATERNION, "QUATERNION", 0, "Quaternion", "Floating point quaternion rotation"},
{CD_PROP_FLOAT4X4, "FLOAT4X4", 0, "4x4 Matrix", "Floating point matrix"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_color_attribute_type_items[] = {
{CD_PROP_COLOR, "FLOAT_COLOR", 0, "Color", "RGBA color 32-bit floating-point values"},
{CD_PROP_BYTE_COLOR,
"BYTE_COLOR",
0,
"Byte Color",
"RGBA color with 8-bit positive integer values"},
{0, nullptr, 0, nullptr, nullptr}};
const EnumPropertyItem rna_enum_attribute_type_with_auto_items[] = {
{CD_AUTO_FROM_NAME, "AUTO", 0, "Auto", ""},
{CD_PROP_FLOAT, "FLOAT", 0, "Float", "Floating-point value"},
{CD_PROP_INT32, "INT", 0, "Integer", "32-bit integer"},
{CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating-point values"},
{CD_PROP_COLOR, "FLOAT_COLOR", 0, "Color", "RGBA color with 32-bit floating-point values"},
{CD_PROP_BYTE_COLOR,
"BYTE_COLOR",
0,
"Byte Color",
"RGBA color with 8-bit positive integer values"},
{CD_PROP_STRING, "STRING", 0, "String", "Text string"},
{CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"},
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
{CD_PROP_INT16_2D, "INT16_2D", 0, "2D 16-Bit Integer Vector", "16-bit signed integer vector"},
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
{CD_PROP_QUATERNION, "QUATERNION", 0, "Quaternion", "Floating point quaternion rotation"},
{CD_PROP_FLOAT4X4, "FLOAT4X4", 0, "4x4 Matrix", "Floating point matrix"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_items[] = {
/* Not implement yet */
// {ATTR_DOMAIN_GEOMETRY, "GEOMETRY", 0, "Geometry", "Attribute on (whole) geometry"},
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Corner), "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
/* Not implement yet */
// {ATTR_DOMAIN_GRIDS, "GRIDS", 0, "Grids", "Attribute on mesh multires grids"},
{int(AttrDomain::Curve), "CURVE", 0, "Spline", "Attribute on spline"},
{int(AttrDomain::Instance), "INSTANCE", 0, "Instance", "Attribute on instance"},
{int(AttrDomain::Layer), "LAYER", 0, "Layer", "Attribute on Grease Pencil layer"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_only_mesh_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Corner), "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_only_mesh_no_edge_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Corner), "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_only_mesh_no_corner_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_point_face_curve_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Curve), "CURVE", 0, "Spline", "Attribute on spline"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_point_edge_face_curve_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Curve), "CURVE", 0, "Spline", "Attribute on spline"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_edge_face_items[] = {
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_without_corner_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Curve), "CURVE", 0, "Spline", "Attribute on spline"},
{int(AttrDomain::Instance), "INSTANCE", 0, "Instance", "Attribute on instance"},
{int(AttrDomain::Layer), "LAYER", 0, "Layer", "Attribute on Grease Pencil layer"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_attribute_domain_with_auto_items[] = {
{int(AttrDomain::Auto), "AUTO", 0, "Auto", ""},
{int(AttrDomain::Point), "POINT", 0, "Point", "Attribute on point"},
{int(AttrDomain::Edge), "EDGE", 0, "Edge", "Attribute on mesh edge"},
{int(AttrDomain::Face), "FACE", 0, "Face", "Attribute on mesh faces"},
{int(AttrDomain::Corner), "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
{int(AttrDomain::Curve), "CURVE", 0, "Spline", "Attribute on spline"},
{int(AttrDomain::Instance), "INSTANCE", 0, "Instance", "Attribute on instance"},
{int(AttrDomain::Layer), "LAYER", 0, "Layer", "Attribute on Grease Pencil layer"},
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_color_attribute_domain_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Vertex", ""},
{int(AttrDomain::Corner), "CORNER", 0, "Face Corner", ""},
{0, nullptr, 0, nullptr, nullptr}};
const EnumPropertyItem rna_enum_attribute_curves_domain_items[] = {
{int(AttrDomain::Point), "POINT", 0, "Control Point", ""},
{int(AttrDomain::Curve), "CURVE", 0, "Curve", ""},
{0, nullptr, 0, nullptr, nullptr}};
#ifdef RNA_RUNTIME
# include <fmt/format.h>
# include "DNA_customdata_types.h"
# include "DNA_grease_pencil_types.h"
# include "DNA_mesh_types.h"
# include "DNA_meshdata_types.h"
# include "BLI_string.h"
# include "BKE_customdata.hh"
# include "DEG_depsgraph.hh"
# include "BLT_translation.hh"
# include "WM_api.hh"
using blender::StringRef;
/* Attribute */
static AttributeOwner owner_from_attribute_pointer_rna(PointerRNA *ptr)
{
ID *owner_id = ptr->owner_id;
const CustomDataLayer *layer = static_cast<const CustomDataLayer *>(ptr->data);
/* TODO: Because we don't know the path to the `ptr`, we need to look though all possible
* candidates and search for the `layer` currently. This should be just a simple lookup. */
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(owner_id);
}
static AttributeOwner owner_from_pointer_rna(PointerRNA *ptr)
{
/* For non-ID attribute owners, check the `ptr->type` to derive the `AttributeOwnerType`
* and construct an `AttributeOwner` from that type and `ptr->data`. */
if (ptr->type == &RNA_GreasePencilDrawing) {
return AttributeOwner(AttributeOwnerType::GreasePencilDrawing, ptr->data);
}
return AttributeOwner::from_id(ptr->owner_id);
}
static std::optional<std::string> rna_Attribute_path(const PointerRNA *ptr)
{
const CustomDataLayer *layer = static_cast<const CustomDataLayer *>(ptr->data);
char layer_name_esc[sizeof(layer->name) * 2];
BLI_str_escape(layer_name_esc, layer->name, sizeof(layer_name_esc));
return fmt::format("attributes[\"{}\"]", layer_name_esc);
}
static StructRNA *srna_by_custom_data_layer_type(const eCustomDataType type)
{
switch (type) {
case CD_PROP_FLOAT:
return &RNA_FloatAttribute;
case CD_PROP_INT32:
return &RNA_IntAttribute;
case CD_PROP_FLOAT3:
return &RNA_FloatVectorAttribute;
case CD_PROP_COLOR:
return &RNA_FloatColorAttribute;
case CD_PROP_BYTE_COLOR:
return &RNA_ByteColorAttribute;
case CD_PROP_STRING:
return &RNA_StringAttribute;
case CD_PROP_BOOL:
return &RNA_BoolAttribute;
case CD_PROP_FLOAT2:
return &RNA_Float2Attribute;
case CD_PROP_INT8:
return &RNA_ByteIntAttribute;
case CD_PROP_INT16_2D:
return &RNA_Short2Attribute;
case CD_PROP_INT32_2D:
return &RNA_Int2Attribute;
case CD_PROP_QUATERNION:
return &RNA_QuaternionAttribute;
case CD_PROP_FLOAT4X4:
return &RNA_Float4x4Attribute;
default:
return nullptr;
}
}
static StructRNA *rna_Attribute_refine(PointerRNA *ptr)
{
CustomDataLayer *layer = static_cast<CustomDataLayer *>(ptr->data);
return srna_by_custom_data_layer_type(eCustomDataType(layer->type));
}
static void rna_Attribute_name_set(PointerRNA *ptr, const char *value)
{
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
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 = 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;
}
return true;
}
static int rna_Attribute_type_get(PointerRNA *ptr)
{
CustomDataLayer *layer = static_cast<CustomDataLayer *>(ptr->data);
return layer->type;
}
const EnumPropertyItem *rna_enum_attribute_domain_itemf(const AttributeOwner &owner,
bool include_instances,
bool *r_free)
{
EnumPropertyItem *item = nullptr;
const EnumPropertyItem *domain_item = nullptr;
int totitem = 0, a;
static EnumPropertyItem mesh_vertex_domain_item = {
int(AttrDomain::Point), "POINT", 0, N_("Vertex"), N_("Attribute per point/vertex")};
for (a = 0; rna_enum_attribute_domain_items[a].identifier; a++) {
domain_item = &rna_enum_attribute_domain_items[a];
if (owner.type() == AttributeOwnerType::PointCloud &&
!ELEM(domain_item->value, int(AttrDomain::Point)))
{
continue;
}
if (owner.type() == AttributeOwnerType::Curves &&
!ELEM(domain_item->value, int(AttrDomain::Point), int(AttrDomain::Curve)))
{
continue;
}
if (owner.type() == AttributeOwnerType::Mesh &&
ELEM(domain_item->value, int(AttrDomain::Curve)))
{
continue;
}
if (owner.type() == AttributeOwnerType::GreasePencil &&
!ELEM(domain_item->value, int(AttrDomain::Layer)))
{
continue;
}
if (!include_instances && domain_item->value == int(AttrDomain::Instance)) {
continue;
}
if (domain_item->value == int(AttrDomain::Point) && owner.type() == AttributeOwnerType::Mesh) {
RNA_enum_item_add(&item, &totitem, &mesh_vertex_domain_item);
}
else {
RNA_enum_item_add(&item, &totitem, domain_item);
}
}
RNA_enum_item_end(&item, &totitem);
*r_free = true;
return item;
}
static const EnumPropertyItem *rna_Attribute_domain_itemf(bContext * /*C*/,
PointerRNA *ptr,
PropertyRNA * /*prop*/,
bool *r_free)
{
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
return rna_enum_attribute_domain_itemf(owner, true, r_free);
}
static int rna_Attribute_domain_get(PointerRNA *ptr)
{
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
return int(BKE_attribute_domain(owner, static_cast<const CustomDataLayer *>(ptr->data)));
}
static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
{
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
return !blender::bke::allow_procedural_attribute_access(layer->name);
}
static bool rna_Attribute_is_required_get(PointerRNA *ptr)
{
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
return BKE_attribute_required(owner, layer->name);
}
static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
if (!(CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL)) {
iter->valid = false;
}
const int length = BKE_attribute_data_length(owner, layer);
const size_t struct_size = CustomData_get_elem_size(layer);
CustomData_ensure_data_is_mutable(layer, length);
rna_iterator_array_begin(iter, ptr, layer->data, struct_size, length, 0, nullptr);
}
static int rna_Attribute_data_length(PointerRNA *ptr)
{
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
return BKE_attribute_data_length(owner, layer);
}
static void rna_Attribute_update_data(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
{
ID *id = ptr->owner_id;
/* cheating way for importers to avoid slow updates */
if (id->us > 0) {
DEG_id_tag_update(id, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
}
/* Color Attribute */
static void rna_ByteColorAttributeValue_color_get(PointerRNA *ptr, float *values)
{
MLoopCol *mlcol = (MLoopCol *)ptr->data;
srgb_to_linearrgb_uchar4(values, &mlcol->r);
}
static void rna_ByteColorAttributeValue_color_set(PointerRNA *ptr, const float *values)
{
MLoopCol *mlcol = (MLoopCol *)ptr->data;
linearrgb_to_srgb_uchar4(&mlcol->r, values);
}
static void rna_ByteColorAttributeValue_color_srgb_get(PointerRNA *ptr, float *values)
{
MLoopCol *col = (MLoopCol *)ptr->data;
values[0] = col->r / 255.0f;
values[1] = col->g / 255.0f;
values[2] = col->b / 255.0f;
values[3] = col->a / 255.0f;
}
static void rna_ByteColorAttributeValue_color_srgb_set(PointerRNA *ptr, const float *values)
{
MLoopCol *col = (MLoopCol *)ptr->data;
col->r = round_fl_to_uchar_clamp(values[0] * 255.0f);
col->g = round_fl_to_uchar_clamp(values[1] * 255.0f);
col->b = round_fl_to_uchar_clamp(values[2] * 255.0f);
col->a = round_fl_to_uchar_clamp(values[3] * 255.0f);
}
static void rna_FloatColorAttributeValue_color_srgb_get(PointerRNA *ptr, float *values)
{
MPropCol *col = (MPropCol *)ptr->data;
linearrgb_to_srgb_v4(values, col->color);
}
static void rna_FloatColorAttributeValue_color_srgb_set(PointerRNA *ptr, const float *values)
{
MPropCol *col = (MPropCol *)ptr->data;
srgb_to_linearrgb_v4(col->color, values);
}
/* String Attribute */
static void rna_StringAttributeValue_s_get(PointerRNA *ptr, char *value)
{
const MStringProperty *mstring = static_cast<const MStringProperty *>(ptr->data);
const int len = std::min<int>(mstring->s_len, sizeof(mstring->s) - 1);
memcpy(value, mstring->s, len);
/* RNA accessors require this. */
value[len] = '\0';
}
static int rna_StringAttributeValue_s_length(PointerRNA *ptr)
{
const MStringProperty *mstring = static_cast<const MStringProperty *>(ptr->data);
const int len = std::min<int>(mstring->s_len, sizeof(mstring->s) - 1);
return len;
}
static void rna_StringAttributeValue_s_set(PointerRNA *ptr, const char *value)
{
/* NOTE: RNA does not support byte-strings which contain null bytes.
* If `PROP_BYTESTRING` supported this then a value & length could be passed in
* and `MStringProperty` could be set with values to include null bytes. */
MStringProperty *mstring = static_cast<MStringProperty *>(ptr->data);
mstring->s_len = BLI_strnlen(value, sizeof(MStringProperty::s));
memcpy(mstring->s, value, mstring->s_len);
}
/* Attribute Group */
static PointerRNA rna_AttributeGroupID_new(
ID *id, ReportList *reports, const char *name, const int type, const int domain)
{
AttributeOwner owner = AttributeOwner::from_id(id);
CustomDataLayer *layer = BKE_attribute_new(
owner, name, eCustomDataType(type), AttrDomain(domain), reports);
if (!layer) {
return PointerRNA_NULL;
}
if ((GS(id->name) == ID_ME) && ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
Mesh *mesh = (Mesh *)id;
if (!mesh->active_color_attribute) {
mesh->active_color_attribute = BLI_strdup(layer->name);
}
if (!mesh->default_color_attribute) {
mesh->default_color_attribute = BLI_strdup(layer->name);
}
}
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_Attribute, layer);
return ptr;
}
static void rna_AttributeGroupID_remove(ID *id, ReportList *reports, PointerRNA *attribute_ptr)
{
AttributeOwner owner = AttributeOwner::from_id(id);
const CustomDataLayer *layer = (const CustomDataLayer *)attribute_ptr->data;
BKE_attribute_remove(owner, layer->name, reports);
attribute_ptr->invalidate();
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
static bool rna_Attributes_layer_skip(CollectionPropertyIterator * /*iter*/, void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
return !(CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL);
}
static bool rna_Attributes_noncolor_layer_skip(CollectionPropertyIterator *iter, void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
/* Check valid domain here, too, keep in line with rna_AttributeGroup_color_length(). */
AttributeOwner owner = AttributeOwner::from_id(iter->parent.owner_id);
const AttrDomain domain = BKE_attribute_domain(owner, layer);
if (!(ATTR_DOMAIN_AS_MASK(domain) & ATTR_DOMAIN_MASK_COLOR)) {
return true;
}
return !(CD_TYPE_AS_MASK(layer->type) & CD_MASK_COLOR_ALL) || (layer->flag & CD_FLAG_TEMPORARY);
}
/* Attributes are spread over multiple domains in separate CustomData, we use repeated
* array iterators to loop over all. */
static void rna_AttributeGroup_next_domain(AttributeOwner &owner,
CollectionPropertyIterator *iter,
PointerRNA *ptr,
bool(skip)(CollectionPropertyIterator *iter,
void *data))
{
do {
CustomDataLayer *prev_layers = (iter->internal.array.endptr == nullptr) ?
nullptr :
(CustomDataLayer *)iter->internal.array.endptr -
iter->internal.array.length;
CustomData *customdata = BKE_attributes_iterator_next_domain(owner, prev_layers);
if (customdata == nullptr) {
return;
}
rna_iterator_array_begin(
iter, ptr, customdata->layers, sizeof(CustomDataLayer), customdata->totlayer, false, skip);
} while (!iter->valid);
}
void rna_AttributeGroup_iterator_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
memset(&iter->internal.array, 0, sizeof(iter->internal.array));
AttributeOwner owner = owner_from_pointer_rna(ptr);
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_layer_skip);
}
void rna_AttributeGroup_iterator_next(CollectionPropertyIterator *iter)
{
rna_iterator_array_next(iter);
if (!iter->valid) {
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
rna_AttributeGroup_next_domain(owner, iter, &iter->parent, rna_Attributes_layer_skip);
}
}
PointerRNA rna_AttributeGroup_iterator_get(CollectionPropertyIterator *iter)
{
/* Refine to the proper type. */
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
}
void rna_AttributeGroup_color_iterator_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
memset(&iter->internal.array, 0, sizeof(iter->internal.array));
AttributeOwner owner = owner_from_pointer_rna(ptr);
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_noncolor_layer_skip);
}
void rna_AttributeGroup_color_iterator_next(CollectionPropertyIterator *iter)
{
rna_iterator_array_next(iter);
if (!iter->valid) {
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
rna_AttributeGroup_next_domain(owner, iter, &iter->parent, rna_Attributes_noncolor_layer_skip);
}
}
PointerRNA rna_AttributeGroup_color_iterator_get(CollectionPropertyIterator *iter)
{
/* Refine to the proper type. */
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
}
int rna_AttributeGroup_color_length(PointerRNA *ptr)
{
AttributeOwner owner = owner_from_pointer_rna(ptr);
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
int rna_AttributeGroup_length(PointerRNA *ptr)
{
AttributeOwner owner = owner_from_pointer_rna(ptr);
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
}
bool rna_AttributeGroup_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
{
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, key, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL))
{
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, layer, *r_ptr);
return true;
}
/* Support retrieving UV seam name convention with older name. To be removed as part of 5.0
* breaking changes. */
if (STREQ(key, ".uv_seam")) {
if (CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, "uv_seam", CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL))
{
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, layer, *r_ptr);
return true;
}
}
*r_ptr = PointerRNA_NULL;
return false;
}
static int rna_AttributeGroupID_active_index_get(PointerRNA *ptr)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
return *BKE_attributes_active_index_p(owner);
}
static PointerRNA rna_AttributeGroupID_active_get(PointerRNA *ptr)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
CustomDataLayer *layer = BKE_attributes_active_get(owner);
PointerRNA attribute_ptr = RNA_pointer_create_with_parent(*ptr, &RNA_Attribute, layer);
return attribute_ptr;
}
static void rna_AttributeGroupID_active_set(PointerRNA *ptr,
PointerRNA attribute_ptr,
ReportList * /*reports*/)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
if (layer) {
BKE_attributes_active_set(owner, layer->name);
}
else {
BKE_attributes_active_clear(owner);
}
}
static void rna_AttributeGroupID_active_index_set(PointerRNA *ptr, int value)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
*BKE_attributes_active_index_p(owner) = std::max(-1, value);
}
static void rna_AttributeGroupID_active_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
*min = -1;
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
*softmin = *min;
*softmax = *max;
}
static void rna_AttributeGroup_update_active(Main *bmain, Scene *scene, PointerRNA *ptr)
{
rna_Attribute_update_data(bmain, scene, ptr);
}
static void rna_AttributeGroup_update_active_color(Main * /*bmain*/,
Scene * /*scene*/,
PointerRNA *ptr)
{
ID *id = ptr->owner_id;
/* Cheating way for importers to avoid slow updates. */
if (id->us > 0) {
DEG_id_tag_update(id, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
}
static int rna_AttributeGroupID_domain_size(ID *id, const int domain)
{
AttributeOwner owner = AttributeOwner::from_id(id);
return BKE_attribute_domain_size(owner, domain);
}
static PointerRNA rna_AttributeGroupMesh_active_color_get(PointerRNA *ptr)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
CustomDataLayer *layer = BKE_attribute_search_for_write(
owner,
BKE_id_attributes_active_color_name(ptr->owner_id).value_or(""),
CD_MASK_COLOR_ALL,
ATTR_DOMAIN_MASK_COLOR);
PointerRNA attribute_ptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_Attribute, layer);
return attribute_ptr;
}
static void rna_AttributeGroupMesh_active_color_set(PointerRNA *ptr,
PointerRNA attribute_ptr,
ReportList * /*reports*/)
{
ID *id = ptr->owner_id;
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
if (layer) {
BKE_id_attributes_active_color_set(id, layer->name);
}
else {
BKE_id_attributes_active_color_clear(id);
}
}
static int rna_AttributeGroupMesh_active_color_index_get(PointerRNA *ptr)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
const CustomDataLayer *layer = BKE_attribute_search(
owner,
BKE_id_attributes_active_color_name(ptr->owner_id).value_or(""),
CD_MASK_COLOR_ALL,
ATTR_DOMAIN_MASK_COLOR);
return BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
static void rna_AttributeGroupMesh_active_color_index_set(PointerRNA *ptr, int value)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
CustomDataLayer *layer = BKE_attribute_from_index(
owner, value, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
if (!layer) {
fprintf(stderr, "%s: error setting active color index to %d\n", __func__, value);
return;
}
BKE_id_attributes_active_color_set(ptr->owner_id, layer->name);
}
static void rna_AttributeGroupMesh_active_color_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
*min = 0;
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
*softmin = *min;
*softmax = *max;
}
static int rna_AttributeGroupMesh_render_color_index_get(PointerRNA *ptr)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
const CustomDataLayer *layer = BKE_id_attributes_color_find(
ptr->owner_id, BKE_id_attributes_default_color_name(ptr->owner_id).value_or(""));
return BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
static void rna_AttributeGroupMesh_render_color_index_set(PointerRNA *ptr, int value)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
CustomDataLayer *layer = BKE_attribute_from_index(
owner, value, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
if (!layer) {
fprintf(stderr, "%s: error setting render color index to %d\n", __func__, value);
return;
}
BKE_id_attributes_default_color_set(ptr->owner_id, layer->name);
}
static void rna_AttributeGroupMesh_render_color_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
*min = 0;
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
*softmin = *min;
*softmax = *max;
}
static void rna_AttributeGroupMesh_default_color_name_get(PointerRNA *ptr, char *value)
{
const ID *id = ptr->owner_id;
const StringRef name = BKE_id_attributes_default_color_name(id).value_or("");
name.copy_unsafe(value);
}
static int rna_AttributeGroupMesh_default_color_name_length(PointerRNA *ptr)
{
const ID *id = ptr->owner_id;
const StringRef name = BKE_id_attributes_default_color_name(id).value_or("");
return name.size();
}
static void rna_AttributeGroupMesh_default_color_name_set(PointerRNA *ptr, const char *value)
{
ID *id = ptr->owner_id;
if (GS(id->name) == ID_ME) {
Mesh *mesh = (Mesh *)id;
MEM_SAFE_FREE(mesh->default_color_attribute);
if (value[0]) {
mesh->default_color_attribute = BLI_strdup(value);
}
}
}
static void rna_AttributeGroupMesh_active_color_name_get(PointerRNA *ptr, char *value)
{
const ID *id = ptr->owner_id;
const StringRef name = BKE_id_attributes_active_color_name(id).value_or("");
name.copy_unsafe(value);
}
static int rna_AttributeGroupMesh_active_color_name_length(PointerRNA *ptr)
{
const ID *id = ptr->owner_id;
const StringRef name = BKE_id_attributes_active_color_name(id).value_or("");
return name.size();
}
static void rna_AttributeGroupMesh_active_color_name_set(PointerRNA *ptr, const char *value)
{
ID *id = ptr->owner_id;
if (GS(id->name) == ID_ME) {
Mesh *mesh = (Mesh *)id;
MEM_SAFE_FREE(mesh->active_color_attribute);
if (value[0]) {
mesh->active_color_attribute = BLI_strdup(value);
}
}
}
static PointerRNA rna_AttributeGroupGreasePencilDrawing_new(ID *grease_pencil_id,
GreasePencilDrawing *drawing,
ReportList *reports,
const char *name,
const int type,
const int domain)
{
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
CustomDataLayer *layer = BKE_attribute_new(
owner, name, eCustomDataType(type), AttrDomain(domain), reports);
if (!layer) {
return PointerRNA_NULL;
}
DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
PointerRNA ptr = RNA_pointer_create_discrete(grease_pencil_id, &RNA_Attribute, layer);
return ptr;
}
static void rna_AttributeGroupGreasePencilDrawing_remove(ID *grease_pencil_id,
GreasePencilDrawing *drawing,
ReportList *reports,
PointerRNA *attribute_ptr)
{
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
const CustomDataLayer *layer = (const CustomDataLayer *)attribute_ptr->data;
BKE_attribute_remove(owner, layer->name, reports);
attribute_ptr->invalidate();
DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
}
static PointerRNA rna_AttributeGroupGreasePencilDrawing_active_get(PointerRNA *ptr)
{
GreasePencilDrawing *drawing = static_cast<GreasePencilDrawing *>(ptr->data);
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
CustomDataLayer *layer = BKE_attributes_active_get(owner);
PointerRNA attribute_ptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_Attribute, layer);
return attribute_ptr;
}
static void rna_AttributeGroupGreasePencilDrawing_active_set(PointerRNA *ptr,
PointerRNA attribute_ptr,
ReportList * /*reports*/)
{
GreasePencilDrawing *drawing = static_cast<GreasePencilDrawing *>(ptr->data);
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
if (layer) {
BKE_attributes_active_set(owner, layer->name);
}
else {
BKE_attributes_active_clear(owner);
}
}
static bool rna_AttributeGroupGreasePencilDrawing_active_poll(PointerRNA *ptr,
const PointerRNA value)
{
AttributeOwner owner = owner_from_attribute_pointer_rna(const_cast<PointerRNA *>(&value));
return owner.is_valid() && owner.type() == AttributeOwnerType::GreasePencilDrawing &&
owner.get_grease_pencil_drawing() == static_cast<GreasePencilDrawing *>(ptr->data);
}
static int rna_AttributeGroupGreasePencilDrawing_active_index_get(PointerRNA *ptr)
{
GreasePencilDrawing *drawing = static_cast<GreasePencilDrawing *>(ptr->data);
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
return *BKE_attributes_active_index_p(owner);
}
static void rna_AttributeGroupGreasePencilDrawing_active_index_set(PointerRNA *ptr, int value)
{
GreasePencilDrawing *drawing = static_cast<GreasePencilDrawing *>(ptr->data);
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
*BKE_attributes_active_index_p(owner) = std::max(-1, value);
}
static void rna_AttributeGroupGreasePencilDrawing_active_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
GreasePencilDrawing *drawing = static_cast<GreasePencilDrawing *>(ptr->data);
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
*min = -1;
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
*softmin = *min;
*softmax = *max;
}
static int rna_AttributeGroupGreasePencilDrawing_domain_size(GreasePencilDrawing *drawing,
const int domain)
{
AttributeOwner owner = AttributeOwner(AttributeOwnerType::GreasePencilDrawing, drawing);
return BKE_attribute_domain_size(owner, domain);
}
#else
static void rna_def_attribute_float(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "FloatAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "Float Attribute", "Geometry attribute that stores floating-point values");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "FloatAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "FloatAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MFloatProperty");
RNA_def_struct_ui_text(
srna, "Float Attribute Value", "Floating-point value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, nullptr, "f");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_float_vector(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
/* Float Vector Attribute */
srna = RNA_def_struct(brna, "FloatVectorAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "Float Vector Attribute", "Geometry attribute that stores floating-point 3D vectors");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "FloatVectorAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
/* Float Vector Attribute Value */
srna = RNA_def_struct(brna, "FloatVectorAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "vec3f");
RNA_def_struct_ui_text(
srna, "Float Vector Attribute Value", "Vector value in geometry attribute");
prop = RNA_def_property(srna, "vector", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_ui_text(prop, "Vector", "3D vector");
RNA_def_property_float_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 3);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_float_color(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
/* Float Color Attribute */
srna = RNA_def_struct(brna, "FloatColorAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna,
"Float Color Attribute",
"Geometry attribute that stores RGBA colors as floating-point values "
"using 32-bits per channel");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "FloatColorAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
/* Float Color Attribute Value */
srna = RNA_def_struct(brna, "FloatColorAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MPropCol");
RNA_def_struct_ui_text(srna, "Float Color Attribute Value", "Color value in geometry attribute");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_ui_text(prop, "Color", "RGBA color in scene linear color space");
RNA_def_property_float_sdna(prop, nullptr, "color");
RNA_def_property_array(prop, 4);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
prop = RNA_def_property(srna, "color_srgb", PROP_FLOAT, PROP_COLOR);
RNA_def_property_ui_text(prop, "Color", "RGBA color in sRGB color space");
RNA_def_property_float_sdna(prop, nullptr, "color");
RNA_def_property_array(prop, 4);
RNA_def_property_float_funcs(prop,
"rna_FloatColorAttributeValue_color_srgb_get",
"rna_FloatColorAttributeValue_color_srgb_set",
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_byte_color(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
/* Byte Color Attribute */
srna = RNA_def_struct(brna, "ByteColorAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna,
"Byte Color Attribute",
"Geometry attribute that stores RGBA colors as positive integer values "
"using 8-bits per channel");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "ByteColorAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
/* Byte Color Attribute Value */
srna = RNA_def_struct(brna, "ByteColorAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MLoopCol");
RNA_def_struct_ui_text(srna, "Byte Color Attribute Value", "Color value in geometry attribute");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop,
"rna_ByteColorAttributeValue_color_get",
"rna_ByteColorAttributeValue_color_set",
nullptr);
RNA_def_property_ui_text(prop, "Color", "RGBA color in scene linear color space");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
prop = RNA_def_property(srna, "color_srgb", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop,
"rna_ByteColorAttributeValue_color_srgb_get",
"rna_ByteColorAttributeValue_color_srgb_set",
nullptr);
RNA_def_property_ui_text(prop, "Color", "RGBA color in sRGB color space");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_int(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "IntAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "Integer Attribute", "Geometry attribute that stores integer values");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "IntAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "IntAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MIntProperty");
RNA_def_struct_ui_text(srna, "Integer Attribute Value", "Integer value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, nullptr, "i");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_string(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "StringAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "String Attribute", "Geometry attribute that stores strings");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "StringAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "StringAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MStringProperty");
RNA_def_struct_ui_text(srna, "String Attribute Value", "String value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
RNA_def_property_string_sdna(prop, nullptr, "s");
RNA_def_property_string_funcs(prop,
"rna_StringAttributeValue_s_get",
"rna_StringAttributeValue_s_length",
"rna_StringAttributeValue_s_set");
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_bool(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "BoolAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Bool Attribute", "Geometry attribute that stores booleans");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "BoolAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "BoolAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MBoolProperty");
RNA_def_struct_ui_text(srna, "Bool Attribute Value", "Bool value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "b", 0);
}
static void rna_def_attribute_int8(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ByteIntAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "8-bit Integer Attribute", "Geometry attribute that stores 8-bit integers");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "ByteIntAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "ByteIntAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "MInt8Property");
RNA_def_struct_ui_text(
srna, "8-bit Integer Attribute Value", "8-bit value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, nullptr, "i");
}
static void rna_def_attribute_short2(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "Short2Attribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna,
"2D 16-Bit Integer Vector Attribute",
"Geometry attribute that stores 2D integer vectors");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Short2AttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "Short2AttributeValue", nullptr);
RNA_def_struct_sdna(srna, "vec2s");
RNA_def_struct_ui_text(
srna, "2D 16-Bit Integer Vector Attribute Value", "2D value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Vector", "2D vector");
RNA_def_property_int_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 2);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_int2(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "Int2Attribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "2D Integer Vector Attribute", "Geometry attribute that stores 2D integer vectors");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Int2AttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "Int2AttributeValue", nullptr);
RNA_def_struct_sdna(srna, "vec2i");
RNA_def_struct_ui_text(
srna, "2D Integer Vector Attribute Value", "2D value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Vector", "2D vector");
RNA_def_property_int_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 2);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_quaternion(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "QuaternionAttribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Quaternion Attribute", "Geometry attribute that stores rotation");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "QuaternionAttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "QuaternionAttributeValue", nullptr);
RNA_def_struct_sdna(srna, "vec4f");
RNA_def_struct_ui_text(
srna, "Quaternion Attribute Value", "Rotation value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Value", "Quaternion");
RNA_def_property_float_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 4);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_float4x4(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "Float4x4Attribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "4x4 Matrix Attribute", "Geometry attribute that stores a 4 by 4 float matrix");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Float4x4AttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
srna = RNA_def_struct(brna, "Float4x4AttributeValue", nullptr);
RNA_def_struct_sdna(srna, "mat4x4f");
RNA_def_struct_ui_text(srna, "Matrix Attribute Value", "Matrix value in geometry attribute");
prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_ui_text(prop, "Value", "Matrix");
RNA_def_property_float_sdna(prop, nullptr, "value");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute_float2(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
/* Float2 Attribute */
srna = RNA_def_struct(brna, "Float2Attribute", "Attribute");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(
srna, "Float2 Attribute", "Geometry attribute that stores floating-point 2D vectors");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Float2AttributeValue");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_collection_funcs(prop,
"rna_Attribute_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_Attribute_data_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
/* Float2 Attribute Value */
srna = RNA_def_struct(brna, "Float2AttributeValue", nullptr);
RNA_def_struct_sdna(srna, "vec2f");
RNA_def_struct_ui_text(srna, "Float2 Attribute Value", "2D Vector value in geometry attribute");
prop = RNA_def_property(srna, "vector", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_ui_text(prop, "Vector", "2D vector");
RNA_def_property_float_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 2);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
static void rna_def_attribute(BlenderRNA *brna)
{
PropertyRNA *prop;
StructRNA *srna;
srna = RNA_def_struct(brna, "Attribute", nullptr);
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Attribute", "Geometry attribute");
RNA_def_struct_path_func(srna, "rna_Attribute_path");
RNA_def_struct_refine_func(srna, "rna_Attribute_refine");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_Attribute_name_set");
RNA_def_property_editable_func(prop, "rna_Attribute_name_editable");
RNA_def_property_ui_text(prop, "Name", "Name of the Attribute");
RNA_def_struct_name_property(srna, prop);
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, nullptr, "type");
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
RNA_def_property_enum_funcs(prop, "rna_Attribute_type_get", nullptr, nullptr);
RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items);
RNA_def_property_enum_funcs(
prop, "rna_Attribute_domain_get", nullptr, "rna_Attribute_domain_itemf");
RNA_def_property_ui_text(prop, "Domain", "Domain of the Attribute");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_internal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Attribute_is_internal_get", nullptr);
RNA_def_property_ui_text(
prop, "Is Internal", "The attribute is meant for internal use by Blender");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_required", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Attribute_is_required_get", nullptr);
RNA_def_property_ui_text(prop, "Is Required", "Whether the attribute can be removed or renamed");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
/* types */
rna_def_attribute_float(brna);
rna_def_attribute_float_vector(brna);
rna_def_attribute_float_color(brna);
rna_def_attribute_byte_color(brna);
rna_def_attribute_int(brna);
rna_def_attribute_short2(brna);
rna_def_attribute_int2(brna);
rna_def_attribute_quaternion(brna);
rna_def_attribute_float4x4(brna);
rna_def_attribute_string(brna);
rna_def_attribute_bool(brna);
rna_def_attribute_float2(brna);
rna_def_attribute_int8(brna);
}
static void rna_def_attribute_group_id_common(StructRNA *srna)
{
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
/* API */
func = RNA_def_function(srna, "new", "rna_AttributeGroupID_new");
RNA_def_function_ui_description(func, "Add attribute to geometry");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_string(func, "name", "Attribute", 0, "Name", "Name of geometry attribute");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_enum(
func, "type", rna_enum_attribute_type_items, CD_PROP_FLOAT, "Type", "Attribute type");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_enum(func,
"domain",
rna_enum_attribute_domain_items,
int(AttrDomain::Point),
"Domain",
"Type of element that attribute is stored on");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "attribute", "Attribute", "", "New geometry attribute");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_AttributeGroupID_remove");
RNA_def_function_ui_description(func, "Remove attribute from geometry");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "attribute", "Attribute", "", "Geometry Attribute");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, ParameterFlag(0));
/* Active */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Attribute");
RNA_def_property_ui_text(prop, "Active Attribute", "Active attribute");
RNA_def_property_pointer_funcs(prop,
"rna_AttributeGroupID_active_get",
"rna_AttributeGroupID_active_set",
nullptr,
nullptr);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(
prop, "Active Attribute Index", "Active attribute index or -1 when none are active");
RNA_def_property_range(prop, -1, INT_MAX);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_funcs(prop,
"rna_AttributeGroupID_active_index_get",
"rna_AttributeGroupID_active_index_set",
"rna_AttributeGroupID_active_index_range");
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active");
/* Domain Size */
func = RNA_def_function(srna, "domain_size", "rna_AttributeGroupID_domain_size");
RNA_def_function_ui_description(func, "Get the size of a given domain");
parm = RNA_def_enum(func,
"domain",
rna_enum_attribute_domain_items,
int(AttrDomain::Point),
"Domain",
"Type of element that attribute is stored on");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_int(func, "size", 0, 0, INT_MAX, "Size", "Size of the domain", 0, INT_MAX);
RNA_def_function_return(func, parm);
}
static void rna_def_attribute_group_mesh(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "AttributeGroupMesh", nullptr);
RNA_def_struct_ui_text(srna, "Attribute Group", "Group of geometry attributes");
/* Define `AttributeGroupMesh` to be of type `ID` so we can reuse the generic ID `AttributeGroup`
* functions. */
RNA_def_struct_sdna(srna, "ID");
rna_def_attribute_group_id_common(srna);
prop = RNA_def_property(srna, "active_color", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Attribute");
RNA_def_property_ui_text(prop, "Active Color", "Active color attribute for display and editing");
RNA_def_property_pointer_funcs(prop,
"rna_AttributeGroupMesh_active_color_get",
"rna_AttributeGroupMesh_active_color_set",
nullptr,
nullptr);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color");
prop = RNA_def_property(srna, "active_color_index", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Active Color Index", "Active color attribute index");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_funcs(prop,
"rna_AttributeGroupMesh_active_color_index_get",
"rna_AttributeGroupMesh_active_color_index_set",
"rna_AttributeGroupMesh_active_color_index_range");
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color");
prop = RNA_def_property(srna, "render_color_index", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop,
"Active Render Color Index",
"The index of the color attribute used as a fallback for rendering");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_funcs(prop,
"rna_AttributeGroupMesh_render_color_index_get",
"rna_AttributeGroupMesh_render_color_index_set",
"rna_AttributeGroupMesh_render_color_index_range");
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color");
prop = RNA_def_property(srna, "default_color_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX);
RNA_def_property_string_funcs(prop,
"rna_AttributeGroupMesh_default_color_name_get",
"rna_AttributeGroupMesh_default_color_name_length",
"rna_AttributeGroupMesh_default_color_name_set");
RNA_def_property_ui_text(
prop,
"Default Color Attribute",
"The name of the default color attribute used as a fallback for rendering");
prop = RNA_def_property(srna, "active_color_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX);
RNA_def_property_string_funcs(prop,
"rna_AttributeGroupMesh_active_color_name_get",
"rna_AttributeGroupMesh_active_color_name_length",
"rna_AttributeGroupMesh_active_color_name_set");
RNA_def_property_ui_text(prop,
"Active Color Attribute",
"The name of the active color attribute for display and editing");
}
static void rna_def_attribute_group_pointcloud(BlenderRNA *brna)
{
StructRNA *srna;
srna = RNA_def_struct(brna, "AttributeGroupPointCloud", nullptr);
RNA_def_struct_ui_text(srna, "Attribute Group", "Group of geometry attributes");
RNA_def_struct_sdna(srna, "ID");
rna_def_attribute_group_id_common(srna);
}
static void rna_def_attribute_group_curves(BlenderRNA *brna)
{
StructRNA *srna;
srna = RNA_def_struct(brna, "AttributeGroupCurves", nullptr);
RNA_def_struct_ui_text(srna, "Attribute Group", "Group of geometry attributes");
RNA_def_struct_sdna(srna, "ID");
rna_def_attribute_group_id_common(srna);
}
static void rna_def_attribute_group_grease_pencil(BlenderRNA *brna)
{
StructRNA *srna;
srna = RNA_def_struct(brna, "AttributeGroupGreasePencil", nullptr);
RNA_def_struct_ui_text(srna, "Attribute Group", "Group of geometry attributes");
RNA_def_struct_sdna(srna, "ID");
rna_def_attribute_group_id_common(srna);
}
static void rna_def_attribute_group_grease_pencil_drawing(BlenderRNA *brna)
{
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
StructRNA *srna;
srna = RNA_def_struct(brna, "AttributeGroupGreasePencilDrawing", nullptr);
RNA_def_struct_ui_text(srna, "Attribute Group", "Group of geometry attributes");
RNA_def_struct_sdna(srna, "GreasePencilDrawing");
/* API */
func = RNA_def_function(srna, "new", "rna_AttributeGroupGreasePencilDrawing_new");
RNA_def_function_ui_description(func, "Add attribute to geometry");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
parm = RNA_def_string(func, "name", "Attribute", 0, "Name", "Name of geometry attribute");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_enum(
func, "type", rna_enum_attribute_type_items, CD_PROP_FLOAT, "Type", "Attribute type");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_enum(func,
"domain",
rna_enum_attribute_domain_items,
int(AttrDomain::Point),
"Domain",
"Type of element that attribute is stored on");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "attribute", "Attribute", "", "New geometry attribute");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_AttributeGroupGreasePencilDrawing_remove");
RNA_def_function_ui_description(func, "Remove attribute from geometry");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "attribute", "Attribute", "", "Geometry Attribute");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, ParameterFlag(0));
/* Active */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Attribute");
RNA_def_property_ui_text(prop, "Active Attribute", "Active attribute");
RNA_def_property_pointer_funcs(prop,
"rna_AttributeGroupGreasePencilDrawing_active_get",
"rna_AttributeGroupGreasePencilDrawing_active_set",
nullptr,
"rna_AttributeGroupGreasePencilDrawing_active_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(
prop, "Active Attribute Index", "Active attribute index or -1 when none are active");
RNA_def_property_range(prop, -1, INT_MAX);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_funcs(prop,
"rna_AttributeGroupGreasePencilDrawing_active_index_get",
"rna_AttributeGroupGreasePencilDrawing_active_index_set",
"rna_AttributeGroupGreasePencilDrawing_active_index_range");
RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active");
/* Domain Size */
func = RNA_def_function(
srna, "domain_size", "rna_AttributeGroupGreasePencilDrawing_domain_size");
RNA_def_function_ui_description(func, "Get the size of a given domain");
parm = RNA_def_enum(func,
"domain",
rna_enum_attribute_domain_items,
int(AttrDomain::Point),
"Domain",
"Type of element that attribute is stored on");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_int(func, "size", 0, 0, INT_MAX, "Size", "Size of the domain", 0, INT_MAX);
RNA_def_function_return(func, parm);
}
void rna_def_attributes_common(StructRNA *srna, const AttributeOwnerType type)
{
PropertyRNA *prop;
/* Attributes */
prop = RNA_def_property(srna, "attributes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop,
"rna_AttributeGroup_iterator_begin",
"rna_AttributeGroup_iterator_next",
"rna_iterator_array_end",
"rna_AttributeGroup_iterator_get",
"rna_AttributeGroup_length",
nullptr,
"rna_AttributeGroup_lookup_string",
nullptr);
RNA_def_property_struct_type(prop, "Attribute");
RNA_def_property_ui_text(prop, "Attributes", "Geometry attributes");
switch (type) {
case AttributeOwnerType::Mesh:
RNA_def_property_srna(prop, "AttributeGroupMesh");
break;
case AttributeOwnerType::PointCloud:
RNA_def_property_srna(prop, "AttributeGroupPointCloud");
break;
case AttributeOwnerType::Curves:
RNA_def_property_srna(prop, "AttributeGroupCurves");
break;
case AttributeOwnerType::GreasePencil:
RNA_def_property_srna(prop, "AttributeGroupGreasePencil");
break;
case AttributeOwnerType::GreasePencilDrawing:
RNA_def_property_srna(prop, "AttributeGroupGreasePencilDrawing");
break;
}
prop = RNA_def_property(srna, "color_attributes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop,
"rna_AttributeGroup_color_iterator_begin",
"rna_AttributeGroup_color_iterator_next",
"rna_iterator_array_end",
"rna_AttributeGroup_color_iterator_get",
"rna_AttributeGroup_color_length",
nullptr,
nullptr,
nullptr);
RNA_def_property_struct_type(prop, "Attribute");
RNA_def_property_ui_text(prop, "Color Attributes", "Geometry color attributes");
switch (type) {
case AttributeOwnerType::Mesh:
RNA_def_property_srna(prop, "AttributeGroupMesh");
break;
case AttributeOwnerType::PointCloud:
RNA_def_property_srna(prop, "AttributeGroupPointCloud");
break;
case AttributeOwnerType::Curves:
RNA_def_property_srna(prop, "AttributeGroupCurves");
break;
case AttributeOwnerType::GreasePencil:
RNA_def_property_srna(prop, "AttributeGroupGreasePencil");
break;
case AttributeOwnerType::GreasePencilDrawing:
RNA_def_property_srna(prop, "AttributeGroupGreasePencilDrawing");
break;
}
}
void RNA_def_attribute(BlenderRNA *brna)
{
rna_def_attribute(brna);
rna_def_attribute_group_mesh(brna);
rna_def_attribute_group_pointcloud(brna);
rna_def_attribute_group_curves(brna);
rna_def_attribute_group_grease_pencil(brna);
rna_def_attribute_group_grease_pencil_drawing(brna);
}
#endif