Refactor: Attribute API: Remove ID owner dependency
The attribute API defined in `attribute.cc` was dependent on the assumption that `ID`s are always the "direct" owners of attributes. For Grease Pencil drawings, this is not the case. The Grease Pencil ID stores the attributes for layers, and the attributes for drawings are stored in `CurvesGeometry` on the drawings themselves. In order to make use of `rna_attribute.cc`, we need that API to handle other types of attribute owners. This adds an `AttributeOwner` which is basically just a type and a pointer. We replace the `ID` pointers and pass `AttributeOwner`s instead. For cases where we have to do a switch based on the type, all the types are handled and the `default` statment is left out. This ensures that we get a compiler warning when a new `AttributeOwnerType` is added. No functional changes expected. Pull Request: https://projects.blender.org/blender/blender/pulls/122765
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "DNA_customdata_types.h"
|
||||
@@ -22,6 +23,10 @@ struct CustomData;
|
||||
struct CustomDataLayer;
|
||||
struct ID;
|
||||
struct ReportList;
|
||||
struct Mesh;
|
||||
struct PointCloud;
|
||||
struct Curves;
|
||||
struct GreasePencil;
|
||||
|
||||
typedef enum AttrDomainMask {
|
||||
ATTR_DOMAIN_MASK_POINT = (1 << 0),
|
||||
@@ -34,6 +39,33 @@ typedef enum AttrDomainMask {
|
||||
} AttrDomainMask;
|
||||
ENUM_OPERATORS(AttrDomainMask, ATTR_DOMAIN_MASK_ALL);
|
||||
|
||||
enum class AttributeOwnerType {
|
||||
None = 0,
|
||||
Mesh,
|
||||
PointCloud,
|
||||
Curves,
|
||||
GreasePencil,
|
||||
};
|
||||
|
||||
class AttributeOwner {
|
||||
AttributeOwnerType type_ = AttributeOwnerType::None;
|
||||
void *ptr_ = nullptr;
|
||||
|
||||
public:
|
||||
AttributeOwner(){};
|
||||
AttributeOwner(AttributeOwnerType type, void *ptr) : type_(type), ptr_(ptr){};
|
||||
|
||||
static AttributeOwner from_id(ID *id);
|
||||
|
||||
AttributeOwnerType type() const;
|
||||
bool is_valid() const;
|
||||
|
||||
Mesh *get_mesh() const;
|
||||
PointCloud *get_pointcloud() const;
|
||||
Curves *get_curves() const;
|
||||
GreasePencil *get_grease_pencil() const;
|
||||
};
|
||||
|
||||
#define ATTR_DOMAIN_AS_MASK(domain) ((AttrDomainMask)((1 << (int)(domain))))
|
||||
|
||||
/* All domains that support color attributes. */
|
||||
@@ -42,69 +74,70 @@ ENUM_OPERATORS(AttrDomainMask, ATTR_DOMAIN_MASK_ALL);
|
||||
|
||||
/* Attributes. */
|
||||
|
||||
bool BKE_id_attributes_supported(const struct ID *id);
|
||||
bool BKE_attributes_supported(const AttributeOwner &owner);
|
||||
bool BKE_attribute_allow_procedural_access(const char *attribute_name);
|
||||
|
||||
/**
|
||||
* Create a new attribute layer.
|
||||
*/
|
||||
struct CustomDataLayer *BKE_id_attribute_new(struct ID *id,
|
||||
const char *name,
|
||||
eCustomDataType type,
|
||||
blender::bke::AttrDomain domain,
|
||||
struct ReportList *reports);
|
||||
bool BKE_id_attribute_remove(struct ID *id, const char *name, struct ReportList *reports);
|
||||
struct CustomDataLayer *BKE_attribute_new(AttributeOwner &owner,
|
||||
const char *name,
|
||||
eCustomDataType type,
|
||||
blender::bke::AttrDomain domain,
|
||||
struct ReportList *reports);
|
||||
bool BKE_attribute_remove(AttributeOwner &owner, const char *name, struct ReportList *reports);
|
||||
|
||||
/**
|
||||
* Creates a duplicate attribute layer.
|
||||
*/
|
||||
struct CustomDataLayer *BKE_id_attribute_duplicate(struct ID *id,
|
||||
struct CustomDataLayer *BKE_attribute_duplicate(AttributeOwner &owner,
|
||||
const char *name,
|
||||
struct ReportList *reports);
|
||||
|
||||
struct CustomDataLayer *BKE_attribute_find(const AttributeOwner &owner,
|
||||
const char *name,
|
||||
eCustomDataType type,
|
||||
blender::bke::AttrDomain domain);
|
||||
|
||||
const struct CustomDataLayer *BKE_attribute_search(const AttributeOwner &owner,
|
||||
const char *name,
|
||||
struct ReportList *reports);
|
||||
eCustomDataMask type,
|
||||
AttrDomainMask domain_mask);
|
||||
|
||||
struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id,
|
||||
const char *name,
|
||||
eCustomDataType type,
|
||||
blender::bke::AttrDomain domain);
|
||||
struct CustomDataLayer *BKE_attribute_search_for_write(AttributeOwner &owner,
|
||||
const char *name,
|
||||
eCustomDataMask type,
|
||||
AttrDomainMask domain_mask);
|
||||
|
||||
const struct CustomDataLayer *BKE_id_attribute_search(const struct ID *id,
|
||||
const char *name,
|
||||
eCustomDataMask type,
|
||||
AttrDomainMask domain_mask);
|
||||
blender::bke::AttrDomain BKE_attribute_domain(const AttributeOwner &owner,
|
||||
const struct CustomDataLayer *layer);
|
||||
int BKE_attribute_data_length(AttributeOwner &owner, struct CustomDataLayer *layer);
|
||||
bool BKE_attribute_required(const AttributeOwner &owner, const char *name);
|
||||
bool BKE_attribute_rename(AttributeOwner &owner,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
struct ReportList *reports);
|
||||
|
||||
struct CustomDataLayer *BKE_id_attribute_search_for_write(struct ID *id,
|
||||
const char *name,
|
||||
eCustomDataMask type,
|
||||
AttrDomainMask domain_mask);
|
||||
int BKE_attributes_length(const AttributeOwner &owner,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask mask);
|
||||
|
||||
blender::bke::AttrDomain BKE_id_attribute_domain(const struct ID *id,
|
||||
const struct CustomDataLayer *layer);
|
||||
int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer);
|
||||
bool BKE_id_attribute_required(const struct ID *id, const char *name);
|
||||
bool BKE_id_attribute_rename(struct ID *id,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
struct ReportList *reports);
|
||||
struct CustomDataLayer *BKE_attributes_active_get(AttributeOwner &owner);
|
||||
void BKE_attributes_active_set(AttributeOwner &owner, const char *name);
|
||||
int *BKE_attributes_active_index_p(AttributeOwner &owner);
|
||||
|
||||
int BKE_id_attributes_length(const struct ID *id,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask mask);
|
||||
|
||||
struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id);
|
||||
void BKE_id_attributes_active_set(struct ID *id, const char *name);
|
||||
int *BKE_id_attributes_active_index_p(struct ID *id);
|
||||
|
||||
CustomData *BKE_id_attributes_iterator_next_domain(struct ID *id, struct CustomDataLayer *layers);
|
||||
CustomDataLayer *BKE_id_attribute_from_index(struct ID *id,
|
||||
int lookup_index,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask);
|
||||
CustomData *BKE_attributes_iterator_next_domain(AttributeOwner &owner,
|
||||
struct CustomDataLayer *layers);
|
||||
CustomDataLayer *BKE_attribute_from_index(AttributeOwner &owner,
|
||||
int lookup_index,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask);
|
||||
|
||||
/** Layer is allowed to be nullptr; if so -1 (layer not found) will be returned. */
|
||||
int BKE_id_attribute_to_index(const struct ID *id,
|
||||
const CustomDataLayer *layer,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask);
|
||||
int BKE_attribute_to_index(const AttributeOwner &owner,
|
||||
const CustomDataLayer *layer,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask);
|
||||
|
||||
const char *BKE_id_attributes_active_color_name(const struct ID *id);
|
||||
const char *BKE_id_attributes_default_color_name(const struct ID *id);
|
||||
@@ -114,7 +147,8 @@ void BKE_id_attributes_default_color_set(struct ID *id, const char *name);
|
||||
const struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const char *name);
|
||||
bool BKE_color_attribute_supported(const struct Mesh &mesh, const blender::StringRef name);
|
||||
|
||||
std::string BKE_id_attribute_calc_unique_name(const struct ID &id, const blender::StringRef name);
|
||||
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner,
|
||||
const blender::StringRef name);
|
||||
|
||||
const char *BKE_uv_map_vert_select_name_get(const char *uv_map_name, char *buffer);
|
||||
const char *BKE_uv_map_edge_select_name_get(const char *uv_map_name, char *buffer);
|
||||
|
||||
@@ -40,24 +40,82 @@
|
||||
using blender::IndexRange;
|
||||
using blender::bke::AttrDomain;
|
||||
|
||||
AttributeOwner AttributeOwner::from_id(ID *id)
|
||||
{
|
||||
if (id == nullptr) {
|
||||
return {};
|
||||
}
|
||||
switch (GS(id->name)) {
|
||||
case ID_ME:
|
||||
return AttributeOwner(AttributeOwnerType::Mesh, id);
|
||||
case ID_PT:
|
||||
return AttributeOwner(AttributeOwnerType::PointCloud, id);
|
||||
case ID_CV:
|
||||
return AttributeOwner(AttributeOwnerType::Curves, id);
|
||||
case ID_GP:
|
||||
return AttributeOwner(AttributeOwnerType::GreasePencil, id);
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AttributeOwnerType AttributeOwner::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
bool AttributeOwner::is_valid() const
|
||||
{
|
||||
return ptr_ != nullptr && type_ != AttributeOwnerType::None;
|
||||
}
|
||||
|
||||
Mesh *AttributeOwner::get_mesh() const
|
||||
{
|
||||
BLI_assert(ptr_ != nullptr);
|
||||
BLI_assert(type_ == AttributeOwnerType::Mesh);
|
||||
return reinterpret_cast<Mesh *>(ptr_);
|
||||
}
|
||||
|
||||
PointCloud *AttributeOwner::get_pointcloud() const
|
||||
{
|
||||
BLI_assert(ptr_ != nullptr);
|
||||
BLI_assert(type_ == AttributeOwnerType::PointCloud);
|
||||
return reinterpret_cast<PointCloud *>(ptr_);
|
||||
}
|
||||
|
||||
Curves *AttributeOwner::get_curves() const
|
||||
{
|
||||
BLI_assert(ptr_ != nullptr);
|
||||
BLI_assert(type_ == AttributeOwnerType::Curves);
|
||||
return reinterpret_cast<Curves *>(ptr_);
|
||||
}
|
||||
|
||||
GreasePencil *AttributeOwner::get_grease_pencil() const
|
||||
{
|
||||
BLI_assert(ptr_ != nullptr);
|
||||
BLI_assert(type_ == AttributeOwnerType::GreasePencil);
|
||||
return reinterpret_cast<GreasePencil *>(ptr_);
|
||||
}
|
||||
|
||||
struct DomainInfo {
|
||||
CustomData *customdata = nullptr;
|
||||
int length = 0;
|
||||
};
|
||||
|
||||
static std::array<DomainInfo, ATTR_DOMAIN_NUM> get_domains(const ID *id)
|
||||
static std::array<DomainInfo, ATTR_DOMAIN_NUM> get_domains(const AttributeOwner &owner)
|
||||
{
|
||||
std::array<DomainInfo, ATTR_DOMAIN_NUM> info;
|
||||
|
||||
switch (GS(id->name)) {
|
||||
case ID_PT: {
|
||||
PointCloud *pointcloud = (PointCloud *)id;
|
||||
switch (owner.type()) {
|
||||
case AttributeOwnerType::PointCloud: {
|
||||
PointCloud *pointcloud = owner.get_pointcloud();
|
||||
info[int(AttrDomain::Point)].customdata = &pointcloud->pdata;
|
||||
info[int(AttrDomain::Point)].length = pointcloud->totpoint;
|
||||
break;
|
||||
}
|
||||
case ID_ME: {
|
||||
Mesh *mesh = (Mesh *)id;
|
||||
case AttributeOwnerType::Mesh: {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
|
||||
BMesh *bm = em->bm;
|
||||
info[int(AttrDomain::Point)].customdata = &bm->vdata;
|
||||
@@ -81,22 +139,20 @@ static std::array<DomainInfo, ATTR_DOMAIN_NUM> get_domains(const ID *id)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ID_CV: {
|
||||
Curves *curves = (Curves *)id;
|
||||
case AttributeOwnerType::Curves: {
|
||||
Curves *curves = owner.get_curves();
|
||||
info[int(AttrDomain::Point)].customdata = &curves->geometry.point_data;
|
||||
info[int(AttrDomain::Point)].length = curves->geometry.point_num;
|
||||
info[int(AttrDomain::Curve)].customdata = &curves->geometry.curve_data;
|
||||
info[int(AttrDomain::Curve)].length = curves->geometry.curve_num;
|
||||
break;
|
||||
}
|
||||
case ID_GP: {
|
||||
GreasePencil *grease_pencil = (GreasePencil *)id;
|
||||
case AttributeOwnerType::GreasePencil: {
|
||||
GreasePencil *grease_pencil = owner.get_grease_pencil();
|
||||
info[int(AttrDomain::Layer)].customdata = &grease_pencil->layers_data;
|
||||
info[int(AttrDomain::Layer)].length = grease_pencil->layers().size();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -105,40 +161,37 @@ static std::array<DomainInfo, ATTR_DOMAIN_NUM> get_domains(const ID *id)
|
||||
namespace blender::bke {
|
||||
|
||||
static std::optional<blender::bke::MutableAttributeAccessor> get_attribute_accessor_for_write(
|
||||
ID &id)
|
||||
AttributeOwner &owner)
|
||||
{
|
||||
switch (GS(id.name)) {
|
||||
case ID_ME: {
|
||||
Mesh &mesh = reinterpret_cast<Mesh &>(id);
|
||||
switch (owner.type()) {
|
||||
case AttributeOwnerType::Mesh: {
|
||||
Mesh &mesh = *owner.get_mesh();
|
||||
/* The attribute API isn't implemented for BMesh, so edit mode meshes are not supported. */
|
||||
BLI_assert(mesh.runtime->edit_mesh == nullptr);
|
||||
return mesh.attributes_for_write();
|
||||
}
|
||||
case ID_PT: {
|
||||
PointCloud &pointcloud = reinterpret_cast<PointCloud &>(id);
|
||||
case AttributeOwnerType::PointCloud: {
|
||||
PointCloud &pointcloud = *owner.get_pointcloud();
|
||||
return pointcloud.attributes_for_write();
|
||||
}
|
||||
case ID_CV: {
|
||||
Curves &curves_id = reinterpret_cast<Curves &>(id);
|
||||
case AttributeOwnerType::Curves: {
|
||||
Curves &curves_id = *owner.get_curves();
|
||||
CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
return curves.attributes_for_write();
|
||||
}
|
||||
case ID_GP: {
|
||||
GreasePencil &grease_pencil = reinterpret_cast<GreasePencil &>(id);
|
||||
case AttributeOwnerType::GreasePencil: {
|
||||
GreasePencil &grease_pencil = *owner.get_grease_pencil();
|
||||
return grease_pencil.attributes_for_write();
|
||||
}
|
||||
default: {
|
||||
BLI_assert_unreachable();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
bool BKE_id_attributes_supported(const ID *id)
|
||||
bool BKE_attributes_supported(const AttributeOwner &owner)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
if (info[domain].customdata) {
|
||||
return true;
|
||||
@@ -152,17 +205,17 @@ bool BKE_attribute_allow_procedural_access(const char *attribute_name)
|
||||
return blender::bke::allow_procedural_attribute_access(attribute_name);
|
||||
}
|
||||
|
||||
static bool bke_id_attribute_rename_if_exists(ID *id,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
ReportList *reports)
|
||||
static bool bke_attribute_rename_if_exists(AttributeOwner &owner,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
ReportList *reports)
|
||||
{
|
||||
CustomDataLayer *layer = BKE_id_attribute_search_for_write(
|
||||
id, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
CustomDataLayer *layer = BKE_attribute_search_for_write(
|
||||
owner, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
if (layer == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return BKE_id_attribute_rename(id, old_name, new_name, reports);
|
||||
return BKE_attribute_rename(owner, old_name, new_name, reports);
|
||||
}
|
||||
|
||||
static bool mesh_edit_mode_attribute_valid(const blender::StringRef name,
|
||||
@@ -195,13 +248,13 @@ static bool mesh_edit_mode_attribute_valid(const blender::StringRef name,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BKE_id_attribute_rename(ID *id,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
ReportList *reports)
|
||||
bool BKE_attribute_rename(AttributeOwner &owner,
|
||||
const char *old_name,
|
||||
const char *new_name,
|
||||
ReportList *reports)
|
||||
{
|
||||
using namespace blender;
|
||||
if (BKE_id_attribute_required(id, old_name)) {
|
||||
if (BKE_attribute_required(owner, old_name)) {
|
||||
BLI_assert_msg(0, "Required attribute name is not editable");
|
||||
return false;
|
||||
}
|
||||
@@ -223,51 +276,55 @@ bool BKE_id_attribute_rename(ID *id,
|
||||
}
|
||||
}
|
||||
|
||||
CustomDataLayer *layer = BKE_id_attribute_search_for_write(
|
||||
id, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
CustomDataLayer *layer = BKE_attribute_search_for_write(
|
||||
owner, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
if (layer == nullptr) {
|
||||
BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GS(id->name) == ID_ME) {
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(id);
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (mesh->runtime->edit_mesh) {
|
||||
if (!mesh_edit_mode_attribute_valid(
|
||||
new_name, BKE_id_attribute_domain(id, layer), eCustomDataType(layer->type), reports))
|
||||
new_name, BKE_attribute_domain(owner, layer), eCustomDataType(layer->type), reports))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result_name = BKE_id_attribute_calc_unique_name(*id, new_name);
|
||||
std::string result_name = BKE_attribute_calc_unique_name(owner, new_name);
|
||||
|
||||
if (layer->type == CD_PROP_FLOAT2 && GS(id->name) == ID_ME) {
|
||||
if (layer->type == CD_PROP_FLOAT2 && owner.type() == AttributeOwnerType::Mesh) {
|
||||
/* Rename UV sub-attributes. */
|
||||
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
bke_id_attribute_rename_if_exists(
|
||||
id,
|
||||
bke_attribute_rename_if_exists(
|
||||
owner,
|
||||
BKE_uv_map_vert_select_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_vert_select_name_get(result_name.c_str(), buffer_dst),
|
||||
reports);
|
||||
bke_id_attribute_rename_if_exists(
|
||||
id,
|
||||
bke_attribute_rename_if_exists(
|
||||
owner,
|
||||
BKE_uv_map_edge_select_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_edge_select_name_get(result_name.c_str(), buffer_dst),
|
||||
reports);
|
||||
bke_id_attribute_rename_if_exists(id,
|
||||
BKE_uv_map_pin_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(result_name.c_str(), buffer_dst),
|
||||
reports);
|
||||
bke_attribute_rename_if_exists(owner,
|
||||
BKE_uv_map_pin_name_get(layer->name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(result_name.c_str(), buffer_dst),
|
||||
reports);
|
||||
}
|
||||
if (StringRef(old_name) == BKE_id_attributes_active_color_name(id)) {
|
||||
BKE_id_attributes_active_color_set(id, result_name.c_str());
|
||||
}
|
||||
if (StringRef(old_name) == BKE_id_attributes_default_color_name(id)) {
|
||||
BKE_id_attributes_default_color_set(id, result_name.c_str());
|
||||
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (StringRef(old_name) == BKE_id_attributes_active_color_name(&mesh->id)) {
|
||||
BKE_id_attributes_active_color_set(&mesh->id, result_name.c_str());
|
||||
}
|
||||
if (StringRef(old_name) == BKE_id_attributes_default_color_name(&mesh->id)) {
|
||||
BKE_id_attributes_default_color_set(&mesh->id, result_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
STRNCPY_UTF8(layer->name, result_name.c_str());
|
||||
@@ -275,9 +332,9 @@ bool BKE_id_attribute_rename(ID *id,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool attribute_name_exists(const ID &id, const blender::StringRef name)
|
||||
static bool attribute_name_exists(const AttributeOwner &owner, const blender::StringRef name)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(&id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
if (!info[domain].customdata) {
|
||||
@@ -297,22 +354,23 @@ static bool attribute_name_exists(const ID &id, const blender::StringRef name)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string BKE_id_attribute_calc_unique_name(const ID &id, const blender::StringRef name)
|
||||
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner,
|
||||
const blender::StringRef name)
|
||||
{
|
||||
return BLI_uniquename_cb(
|
||||
[&](const blender::StringRef new_name) { return attribute_name_exists(id, new_name); },
|
||||
[&](const blender::StringRef new_name) { return attribute_name_exists(owner, new_name); },
|
||||
'.',
|
||||
name.is_empty() ? DATA_("Attribute") : name);
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attribute_new(ID *id,
|
||||
const char *name,
|
||||
const eCustomDataType type,
|
||||
const AttrDomain domain,
|
||||
ReportList *reports)
|
||||
CustomDataLayer *BKE_attribute_new(AttributeOwner &owner,
|
||||
const char *name,
|
||||
const eCustomDataType type,
|
||||
const AttrDomain domain,
|
||||
ReportList *reports)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
CustomData *customdata = info[int(domain)].customdata;
|
||||
if (customdata == nullptr) {
|
||||
@@ -320,10 +378,10 @@ CustomDataLayer *BKE_id_attribute_new(ID *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string uniquename = BKE_id_attribute_calc_unique_name(*id, name);
|
||||
std::string uniquename = BKE_attribute_calc_unique_name(owner, name);
|
||||
|
||||
if (GS(id->name) == ID_ME) {
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(id);
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
|
||||
if (!mesh_edit_mode_attribute_valid(name, domain, type, reports)) {
|
||||
return nullptr;
|
||||
@@ -334,7 +392,7 @@ CustomDataLayer *BKE_id_attribute_new(ID *id,
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(owner);
|
||||
if (!attributes) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -349,11 +407,13 @@ CustomDataLayer *BKE_id_attribute_new(ID *id,
|
||||
return (index == -1) ? nullptr : &(customdata->layers[index]);
|
||||
}
|
||||
|
||||
static void bke_id_attribute_copy_if_exists(ID *id, const char *srcname, const char *dstname)
|
||||
static void bke_attribute_copy_if_exists(AttributeOwner &owner,
|
||||
const char *srcname,
|
||||
const char *dstname)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(owner);
|
||||
if (!attributes) {
|
||||
return;
|
||||
}
|
||||
@@ -367,20 +427,22 @@ static void bke_id_attribute_copy_if_exists(ID *id, const char *srcname, const c
|
||||
attributes->add(dstname, src.domain, type, AttributeInitVArray(src.varray));
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList *reports)
|
||||
CustomDataLayer *BKE_attribute_duplicate(AttributeOwner &owner,
|
||||
const char *name,
|
||||
ReportList *reports)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
std::string uniquename = BKE_id_attribute_calc_unique_name(*id, name);
|
||||
std::string uniquename = BKE_attribute_calc_unique_name(owner, name);
|
||||
|
||||
if (GS(id->name) == ID_ME) {
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(id);
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (mesh->runtime->edit_mesh) {
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(owner);
|
||||
if (!attributes) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -394,49 +456,47 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList
|
||||
const eCustomDataType type = cpp_type_to_custom_data_type(src.varray.type());
|
||||
attributes->add(uniquename, src.domain, type, AttributeInitVArray(src.varray));
|
||||
|
||||
if (GS(id->name) == ID_ME && type == CD_PROP_FLOAT2) {
|
||||
if (owner.type() == AttributeOwnerType::Mesh && type == CD_PROP_FLOAT2) {
|
||||
/* Duplicate UV sub-attributes. */
|
||||
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
bke_id_attribute_copy_if_exists(
|
||||
id,
|
||||
BKE_uv_map_vert_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_vert_select_name_get(uniquename.c_str(), buffer_dst));
|
||||
bke_id_attribute_copy_if_exists(
|
||||
id,
|
||||
BKE_uv_map_edge_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_edge_select_name_get(uniquename.c_str(), buffer_dst));
|
||||
bke_id_attribute_copy_if_exists(id,
|
||||
BKE_uv_map_pin_name_get(name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(uniquename.c_str(), buffer_dst));
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_vert_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_vert_select_name_get(uniquename.c_str(), buffer_dst));
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_edge_select_name_get(name, buffer_src),
|
||||
BKE_uv_map_edge_select_name_get(uniquename.c_str(), buffer_dst));
|
||||
bke_attribute_copy_if_exists(owner,
|
||||
BKE_uv_map_pin_name_get(name, buffer_src),
|
||||
BKE_uv_map_pin_name_get(uniquename.c_str(), buffer_dst));
|
||||
}
|
||||
|
||||
return BKE_id_attribute_search_for_write(
|
||||
id, uniquename.c_str(), CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
return BKE_attribute_search_for_write(
|
||||
owner, uniquename.c_str(), CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
}
|
||||
|
||||
static int color_name_to_index(ID *id, const char *name)
|
||||
static int color_name_to_index(AttributeOwner &owner, const char *name)
|
||||
{
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
id, name, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
return BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner, name, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
return BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
}
|
||||
|
||||
static int color_clamp_index(ID *id, int index)
|
||||
static int color_clamp_index(AttributeOwner &owner, int index)
|
||||
{
|
||||
const int length = BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
const int length = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
return min_ii(index, length - 1);
|
||||
}
|
||||
|
||||
static const char *color_name_from_index(ID *id, int index)
|
||||
static const char *color_name_from_index(AttributeOwner &owner, int index)
|
||||
{
|
||||
const CustomDataLayer *layer = BKE_id_attribute_from_index(
|
||||
id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
const CustomDataLayer *layer = BKE_attribute_from_index(
|
||||
owner, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
return layer ? layer->name : nullptr;
|
||||
}
|
||||
|
||||
bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
bool BKE_attribute_remove(AttributeOwner &owner, const char *name, ReportList *reports)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
@@ -444,15 +504,15 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
BKE_report(reports, RPT_ERROR, "The attribute name must not be empty");
|
||||
return false;
|
||||
}
|
||||
if (BKE_id_attribute_required(id, name)) {
|
||||
if (BKE_attribute_required(owner, name)) {
|
||||
BKE_report(reports, RPT_ERROR, "Attribute is required and can't be removed");
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
if (GS(id->name) == ID_ME) {
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(id);
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
if (CustomData *data = info[domain].customdata) {
|
||||
@@ -467,8 +527,9 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
StringRef(mesh->active_color_attribute);
|
||||
const bool is_default_color_attribute = name_copy.c_str() ==
|
||||
StringRef(mesh->default_color_attribute);
|
||||
const int active_color_index = color_name_to_index(id, mesh->active_color_attribute);
|
||||
const int default_color_index = color_name_to_index(id, mesh->default_color_attribute);
|
||||
const int active_color_index = color_name_to_index(owner, mesh->active_color_attribute);
|
||||
const int default_color_index = color_name_to_index(owner,
|
||||
mesh->default_color_attribute);
|
||||
|
||||
if (!BM_data_layer_free_named(em->bm, data, name_copy.c_str())) {
|
||||
BLI_assert_unreachable();
|
||||
@@ -476,11 +537,13 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
|
||||
if (is_active_color_attribute) {
|
||||
BKE_id_attributes_active_color_set(
|
||||
id, color_name_from_index(id, color_clamp_index(id, active_color_index)));
|
||||
&mesh->id,
|
||||
color_name_from_index(owner, color_clamp_index(owner, active_color_index)));
|
||||
}
|
||||
if (is_default_color_attribute) {
|
||||
BKE_id_attributes_default_color_set(
|
||||
id, color_name_from_index(id, color_clamp_index(id, default_color_index)));
|
||||
&mesh->id,
|
||||
color_name_from_index(owner, color_clamp_index(owner, default_color_index)));
|
||||
}
|
||||
|
||||
if (type == CD_PROP_FLOAT2 && domain == int(AttrDomain::Corner)) {
|
||||
@@ -499,12 +562,12 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
|
||||
std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(owner);
|
||||
if (!attributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GS(id->name) == ID_ME) {
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
const std::string name_copy = name;
|
||||
std::optional<blender::bke::AttributeMetaData> metadata = attributes->lookup_meta_data(
|
||||
name_copy);
|
||||
@@ -512,11 +575,11 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
return false;
|
||||
}
|
||||
/* Update active and default color attributes. */
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(id);
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
const bool is_active_color_attribute = name_copy == StringRef(mesh->active_color_attribute);
|
||||
const bool is_default_color_attribute = name_copy == StringRef(mesh->default_color_attribute);
|
||||
const int active_color_index = color_name_to_index(id, mesh->active_color_attribute);
|
||||
const int default_color_index = color_name_to_index(id, mesh->default_color_attribute);
|
||||
const int active_color_index = color_name_to_index(owner, mesh->active_color_attribute);
|
||||
const int default_color_index = color_name_to_index(owner, mesh->default_color_attribute);
|
||||
|
||||
if (!attributes->remove(name_copy)) {
|
||||
BLI_assert_unreachable();
|
||||
@@ -524,11 +587,11 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
|
||||
if (is_active_color_attribute) {
|
||||
BKE_id_attributes_active_color_set(
|
||||
id, color_name_from_index(id, color_clamp_index(id, active_color_index)));
|
||||
&mesh->id, color_name_from_index(owner, color_clamp_index(owner, active_color_index)));
|
||||
}
|
||||
if (is_default_color_attribute) {
|
||||
BKE_id_attributes_default_color_set(
|
||||
id, color_name_from_index(id, color_clamp_index(id, default_color_index)));
|
||||
&mesh->id, color_name_from_index(owner, color_clamp_index(owner, default_color_index)));
|
||||
}
|
||||
|
||||
if (metadata->data_type == CD_PROP_FLOAT2 && metadata->domain == AttrDomain::Corner) {
|
||||
@@ -543,15 +606,15 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
|
||||
return attributes->remove(name);
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attribute_find(const ID *id,
|
||||
const char *name,
|
||||
const eCustomDataType type,
|
||||
const AttrDomain domain)
|
||||
CustomDataLayer *BKE_attribute_find(const AttributeOwner &owner,
|
||||
const char *name,
|
||||
const eCustomDataType type,
|
||||
const AttrDomain domain)
|
||||
{
|
||||
if (!name) {
|
||||
return nullptr;
|
||||
}
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
CustomData *customdata = info[int(domain)].customdata;
|
||||
if (customdata == nullptr) {
|
||||
@@ -568,15 +631,15 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CustomDataLayer *BKE_id_attribute_search(const ID *id,
|
||||
const char *name,
|
||||
const eCustomDataMask type_mask,
|
||||
const AttrDomainMask domain_mask)
|
||||
const CustomDataLayer *BKE_attribute_search(const AttributeOwner &owner,
|
||||
const char *name,
|
||||
const eCustomDataMask type_mask,
|
||||
const AttrDomainMask domain_mask)
|
||||
{
|
||||
if (!name) {
|
||||
return nullptr;
|
||||
}
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
for (AttrDomain domain = AttrDomain::Point; int(domain) < ATTR_DOMAIN_NUM;
|
||||
domain = AttrDomain(int(domain) + 1))
|
||||
@@ -601,30 +664,32 @@ const CustomDataLayer *BKE_id_attribute_search(const ID *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attribute_search_for_write(ID *id,
|
||||
const char *name,
|
||||
const eCustomDataMask type_mask,
|
||||
const AttrDomainMask domain_mask)
|
||||
CustomDataLayer *BKE_attribute_search_for_write(AttributeOwner &owner,
|
||||
const char *name,
|
||||
const eCustomDataMask type_mask,
|
||||
const AttrDomainMask domain_mask)
|
||||
{
|
||||
/* Reuse the implementation of the const version.
|
||||
* Implicit sharing for the layer's data is handled below. */
|
||||
CustomDataLayer *layer = const_cast<CustomDataLayer *>(
|
||||
BKE_id_attribute_search(id, name, type_mask, domain_mask));
|
||||
BKE_attribute_search(owner, name, type_mask, domain_mask));
|
||||
if (!layer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
const AttrDomain domain = BKE_id_attribute_domain(id, layer);
|
||||
const AttrDomain domain = BKE_attribute_domain(owner, layer);
|
||||
CustomData_ensure_data_is_mutable(layer, info[int(domain)].length);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
int BKE_id_attributes_length(const ID *id, AttrDomainMask domain_mask, eCustomDataMask mask)
|
||||
int BKE_attributes_length(const AttributeOwner &owner,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask mask)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
int length = 0;
|
||||
|
||||
@@ -642,9 +707,9 @@ int BKE_id_attributes_length(const ID *id, AttrDomainMask domain_mask, eCustomDa
|
||||
return length;
|
||||
}
|
||||
|
||||
AttrDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *layer)
|
||||
AttrDomain BKE_attribute_domain(const AttributeOwner &owner, const CustomDataLayer *layer)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
const CustomData *customdata = info[domain].customdata;
|
||||
@@ -660,24 +725,19 @@ AttrDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *layer)
|
||||
return AttrDomain(AttrDomain::Point);
|
||||
}
|
||||
|
||||
int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer)
|
||||
int BKE_attribute_data_length(AttributeOwner &owner, CustomDataLayer *layer)
|
||||
{
|
||||
/* When in mesh editmode, attributes point to bmesh customdata layers, the attribute data is
|
||||
* empty since custom data is stored per element instead of a single array there (same es UVs
|
||||
* etc.), see D11998. */
|
||||
switch (GS(id->name)) {
|
||||
case ID_ME: {
|
||||
Mesh *mesh = (Mesh *)id;
|
||||
if (mesh->runtime->edit_mesh != nullptr) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
if (owner.type() == AttributeOwnerType::Mesh) {
|
||||
Mesh *mesh = owner.get_mesh();
|
||||
if (mesh->runtime->edit_mesh != nullptr) {
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
const CustomData *customdata = info[domain].customdata;
|
||||
@@ -693,28 +753,29 @@ int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BKE_id_attribute_required(const ID *id, const char *name)
|
||||
bool BKE_attribute_required(const AttributeOwner &owner, const char *name)
|
||||
{
|
||||
switch (GS(id->name)) {
|
||||
case ID_PT:
|
||||
return BKE_pointcloud_attribute_required((const PointCloud *)id, name);
|
||||
case ID_CV:
|
||||
return BKE_curves_attribute_required((const Curves *)id, name);
|
||||
case ID_ME:
|
||||
switch (owner.type()) {
|
||||
case AttributeOwnerType::PointCloud:
|
||||
return BKE_pointcloud_attribute_required(owner.get_pointcloud(), name);
|
||||
case AttributeOwnerType::Curves:
|
||||
return BKE_curves_attribute_required(owner.get_curves(), name);
|
||||
case AttributeOwnerType::Mesh:
|
||||
return BKE_mesh_attribute_required(name);
|
||||
default:
|
||||
case AttributeOwnerType::GreasePencil:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attributes_active_get(ID *id)
|
||||
CustomDataLayer *BKE_attributes_active_get(AttributeOwner &owner)
|
||||
{
|
||||
int active_index = *BKE_id_attributes_active_index_p(id);
|
||||
if (active_index > BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) {
|
||||
int active_index = *BKE_attributes_active_index_p(owner);
|
||||
if (active_index > BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) {
|
||||
active_index = 0;
|
||||
}
|
||||
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
int index = 0;
|
||||
|
||||
@@ -740,39 +801,38 @@ CustomDataLayer *BKE_id_attributes_active_get(ID *id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BKE_id_attributes_active_set(ID *id, const char *name)
|
||||
void BKE_attributes_active_set(AttributeOwner &owner, const char *name)
|
||||
{
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
id, name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner, name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
BLI_assert(layer != nullptr);
|
||||
|
||||
const int index = BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
*BKE_id_attributes_active_index_p(id) = index;
|
||||
const int index = BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
*BKE_attributes_active_index_p(owner) = index;
|
||||
}
|
||||
|
||||
int *BKE_id_attributes_active_index_p(ID *id)
|
||||
int *BKE_attributes_active_index_p(AttributeOwner &owner)
|
||||
{
|
||||
switch (GS(id->name)) {
|
||||
case ID_PT: {
|
||||
return &((PointCloud *)id)->attributes_active_index;
|
||||
switch (owner.type()) {
|
||||
case AttributeOwnerType::PointCloud: {
|
||||
return &(owner.get_pointcloud())->attributes_active_index;
|
||||
}
|
||||
case ID_ME: {
|
||||
return &((Mesh *)id)->attributes_active_index;
|
||||
case AttributeOwnerType::Mesh: {
|
||||
return &(owner.get_mesh())->attributes_active_index;
|
||||
}
|
||||
case ID_CV: {
|
||||
return &((Curves *)id)->attributes_active_index;
|
||||
case AttributeOwnerType::Curves: {
|
||||
return &(owner.get_curves())->attributes_active_index;
|
||||
}
|
||||
case ID_GP: {
|
||||
return &((GreasePencil *)id)->attributes_active_index;
|
||||
case AttributeOwnerType::GreasePencil: {
|
||||
return &(owner.get_grease_pencil())->attributes_active_index;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *layers)
|
||||
CustomData *BKE_attributes_iterator_next_domain(AttributeOwner &owner, CustomDataLayer *layers)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
bool use_next = (layers == nullptr);
|
||||
|
||||
@@ -794,12 +854,12 @@ CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *laye
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomDataLayer *BKE_id_attribute_from_index(ID *id,
|
||||
int lookup_index,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask)
|
||||
CustomDataLayer *BKE_attribute_from_index(AttributeOwner &owner,
|
||||
int lookup_index,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask)
|
||||
{
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
int index = 0;
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
@@ -827,16 +887,16 @@ CustomDataLayer *BKE_id_attribute_from_index(ID *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int BKE_id_attribute_to_index(const ID *id,
|
||||
const CustomDataLayer *layer,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask)
|
||||
int BKE_attribute_to_index(const AttributeOwner &owner,
|
||||
const CustomDataLayer *layer,
|
||||
AttrDomainMask domain_mask,
|
||||
eCustomDataMask layer_mask)
|
||||
{
|
||||
if (!layer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(id);
|
||||
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
|
||||
|
||||
int index = 0;
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
@@ -915,8 +975,8 @@ void BKE_id_attributes_default_color_set(ID *id, const char *name)
|
||||
|
||||
const CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name)
|
||||
{
|
||||
return BKE_id_attribute_search(
|
||||
const_cast<ID *>(id), name, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
AttributeOwner owner = AttributeOwner::from_id(const_cast<ID *>(id));
|
||||
return BKE_attribute_search(owner, name, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
}
|
||||
|
||||
bool BKE_color_attribute_supported(const Mesh &mesh, const blender::StringRef name)
|
||||
|
||||
@@ -260,39 +260,39 @@ static void data_transfer_mesh_attributes_transfer_active_color_string(
|
||||
return;
|
||||
}
|
||||
|
||||
const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
|
||||
AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
|
||||
|
||||
const char *active_color_src = BKE_id_attributes_active_color_name(&mesh_src->id);
|
||||
|
||||
if ((data_type == CD_PROP_COLOR) && !BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
|
||||
active_color_src,
|
||||
CD_MASK_PROP_COLOR,
|
||||
ATTR_DOMAIN_MASK_COLOR))
|
||||
if ((data_type == CD_PROP_COLOR) &&
|
||||
!BKE_attribute_search(
|
||||
owner_src, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((data_type == CD_PROP_BYTE_COLOR) &&
|
||||
!BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
|
||||
active_color_src,
|
||||
CD_MASK_PROP_BYTE_COLOR,
|
||||
ATTR_DOMAIN_MASK_COLOR))
|
||||
!BKE_attribute_search(
|
||||
owner_src, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data_type == CD_PROP_COLOR) &&
|
||||
BKE_id_attribute_search(
|
||||
&mesh_dst->id, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
BKE_attribute_search(
|
||||
owner_dst, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
|
||||
}
|
||||
else if ((data_type == CD_PROP_BYTE_COLOR) &&
|
||||
BKE_id_attribute_search(
|
||||
&mesh_dst->id, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
BKE_attribute_search(
|
||||
owner_dst, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
|
||||
}
|
||||
else {
|
||||
CustomDataLayer *first_color_layer = BKE_id_attribute_from_index(
|
||||
&mesh_dst->id, 0, mask_domain, CD_MASK_COLOR_ALL);
|
||||
CustomDataLayer *first_color_layer = BKE_attribute_from_index(
|
||||
owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
|
||||
if (first_color_layer != nullptr) {
|
||||
mesh_dst->active_color_attribute = BLI_strdup(first_color_layer->name);
|
||||
}
|
||||
@@ -311,39 +311,39 @@ static void data_transfer_mesh_attributes_transfer_default_color_string(
|
||||
return;
|
||||
}
|
||||
|
||||
const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
|
||||
AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
|
||||
|
||||
const char *default_color_src = BKE_id_attributes_default_color_name(&mesh_src->id);
|
||||
|
||||
if ((data_type == CD_PROP_COLOR) && !BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
|
||||
default_color_src,
|
||||
CD_MASK_PROP_COLOR,
|
||||
ATTR_DOMAIN_MASK_COLOR))
|
||||
if ((data_type == CD_PROP_COLOR) &&
|
||||
!BKE_attribute_search(
|
||||
owner_src, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((data_type == CD_PROP_BYTE_COLOR) &&
|
||||
!BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
|
||||
default_color_src,
|
||||
CD_MASK_PROP_BYTE_COLOR,
|
||||
ATTR_DOMAIN_MASK_COLOR))
|
||||
!BKE_attribute_search(
|
||||
owner_src, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data_type == CD_PROP_COLOR) &&
|
||||
BKE_id_attribute_search(
|
||||
&mesh_dst->id, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
BKE_attribute_search(
|
||||
owner_dst, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
mesh_dst->default_color_attribute = BLI_strdup(default_color_src);
|
||||
}
|
||||
else if ((data_type == CD_PROP_BYTE_COLOR) &&
|
||||
BKE_id_attribute_search(
|
||||
&mesh_dst->id, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
BKE_attribute_search(
|
||||
owner_dst, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
|
||||
{
|
||||
mesh_dst->default_color_attribute = BLI_strdup(default_color_src);
|
||||
}
|
||||
else {
|
||||
CustomDataLayer *first_color_layer = BKE_id_attribute_from_index(
|
||||
&mesh_dst->id, 0, mask_domain, CD_MASK_COLOR_ALL);
|
||||
CustomDataLayer *first_color_layer = BKE_attribute_from_index(
|
||||
owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
|
||||
if (first_color_layer != nullptr) {
|
||||
mesh_dst->default_color_attribute = BLI_strdup(first_color_layer->name);
|
||||
}
|
||||
|
||||
@@ -3295,8 +3295,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
|
||||
float time_mult = fds->dx / (DT_DEFAULT * (25.0f / FPS));
|
||||
|
||||
if (use_speedvectors) {
|
||||
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
|
||||
&mesh->id, "velocity", CD_PROP_FLOAT3, AttrDomain::Point, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *velocity_layer = BKE_attribute_new(
|
||||
owner, "velocity", CD_PROP_FLOAT3, AttrDomain::Point, nullptr);
|
||||
velarray = static_cast<float(*)[3]>(velocity_layer->data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1766,7 +1766,8 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
||||
|
||||
CustomData_free_layer_named(&mesh->corner_data, uv_names[i], mesh->corners_num);
|
||||
|
||||
const std::string new_name = BKE_id_attribute_calc_unique_name(mesh->id, uv_names[i].c_str());
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const std::string new_name = BKE_attribute_calc_unique_name(owner, uv_names[i].c_str());
|
||||
uv_names[i] = new_name;
|
||||
|
||||
CustomData_add_layer_named_with_data(
|
||||
|
||||
@@ -1891,7 +1891,8 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object)
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string unique_name = BKE_id_attribute_calc_unique_name(orig_me->id, "Color");
|
||||
AttributeOwner owner = AttributeOwner::from_id(&orig_me->id);
|
||||
const std::string unique_name = BKE_attribute_calc_unique_name(owner, "Color");
|
||||
if (!orig_me->attributes_for_write().add(
|
||||
unique_name, AttrDomain::Point, CD_PROP_COLOR, AttributeInitDefaultValue()))
|
||||
{
|
||||
|
||||
@@ -1620,9 +1620,10 @@ IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
|
||||
|
||||
bool BKE_pbvh_get_color_layer(Mesh *mesh, CustomDataLayer **r_layer, AttrDomain *r_domain)
|
||||
{
|
||||
*r_layer = BKE_id_attribute_search_for_write(
|
||||
&mesh->id, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
*r_domain = *r_layer ? BKE_id_attribute_domain(&mesh->id, *r_layer) : AttrDomain::Point;
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
*r_layer = BKE_attribute_search_for_write(
|
||||
owner, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
|
||||
*r_domain = *r_layer ? BKE_attribute_domain(owner, *r_layer) : AttrDomain::Point;
|
||||
return *r_layer != nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -4279,8 +4279,9 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED;
|
||||
}
|
||||
LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
|
||||
BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr);
|
||||
BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&curves_id->id);
|
||||
BKE_attribute_rename(owner, ".selection_point_float", ".selection", nullptr);
|
||||
BKE_attribute_rename(owner, ".selection_curve_float", ".selection", nullptr);
|
||||
}
|
||||
|
||||
/* Toggle the Invert Vertex Group flag on Armature modifiers in some cases. */
|
||||
|
||||
@@ -589,8 +589,9 @@ static void bmo_get_loop_color_ref(BMesh *bm,
|
||||
me_query.corner_data = bm->ldata;
|
||||
*((short *)me_query.id.name) = ID_ME;
|
||||
|
||||
CustomDataLayer *layer = BKE_id_attribute_from_index(
|
||||
&me_query.id, index, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&me_query.id);
|
||||
CustomDataLayer *layer = BKE_attribute_from_index(
|
||||
owner, index, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
if (!layer) {
|
||||
*r_cd_color_offset = -1;
|
||||
return;
|
||||
|
||||
@@ -97,7 +97,8 @@ static int set_attribute_exec(bContext *C, wmOperator *op)
|
||||
Object *active_object = CTX_data_active_object(C);
|
||||
Curves &active_curves_id = *static_cast<Curves *>(active_object->data);
|
||||
|
||||
CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&active_curves_id.id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&active_curves_id.id);
|
||||
CustomDataLayer *active_attribute = BKE_attributes_active_get(owner);
|
||||
const eCustomDataType active_type = eCustomDataType(active_attribute->type);
|
||||
const CPPType &type = *bke::custom_data_type_to_cpp_type(active_type);
|
||||
|
||||
@@ -110,7 +111,7 @@ static int set_attribute_exec(bContext *C, wmOperator *op)
|
||||
|
||||
for (Curves *curves_id : get_unique_editable_curves(*C)) {
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
CustomDataLayer *layer = BKE_id_attributes_active_get(&curves_id->id);
|
||||
CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
@@ -151,7 +152,8 @@ static int set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
Object *active_object = CTX_data_active_object(C);
|
||||
Curves &active_curves_id = *static_cast<Curves *>(active_object->data);
|
||||
|
||||
CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&active_curves_id.id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&active_curves_id.id);
|
||||
CustomDataLayer *active_attribute = BKE_attributes_active_get(owner);
|
||||
const bke::CurvesGeometry &curves = active_curves_id.geometry.wrap();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
const bke::GAttributeReader attribute = attributes.lookup(active_attribute->name);
|
||||
@@ -193,7 +195,8 @@ static void set_attribute_ui(bContext *C, wmOperator *op)
|
||||
Object *object = CTX_data_active_object(C);
|
||||
Curves &curves_id = *static_cast<Curves *>(object->data);
|
||||
|
||||
CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&curves_id.id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&curves_id.id);
|
||||
CustomDataLayer *active_attribute = BKE_attributes_active_get(owner);
|
||||
const eCustomDataType active_type = eCustomDataType(active_attribute->type);
|
||||
const StringRefNull prop_name = geometry::rna_property_name_for_type(active_type);
|
||||
const char *name = active_attribute->name;
|
||||
|
||||
@@ -810,7 +810,8 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
|
||||
*
|
||||
* This would be unnecessary if the active attribute were stored as a string on the ID. */
|
||||
std::string active_attribute;
|
||||
const CustomDataLayer *layer = BKE_id_attributes_active_get(&curves_id->id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&curves_id->id);
|
||||
const CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (layer) {
|
||||
active_attribute = layer->name;
|
||||
}
|
||||
@@ -831,7 +832,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
if (!active_attribute.empty()) {
|
||||
BKE_id_attributes_active_set(&curves_id->id, active_attribute.c_str());
|
||||
BKE_attributes_active_set(owner, active_attribute.c_str());
|
||||
}
|
||||
|
||||
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
|
||||
|
||||
@@ -194,7 +194,8 @@ void rna_property_for_attribute_type_set_value(PointerRNA &ptr,
|
||||
|
||||
bool attribute_set_poll(bContext &C, const ID &object_data)
|
||||
{
|
||||
const CustomDataLayer *layer = BKE_id_attributes_active_get(&const_cast<ID &>(object_data));
|
||||
AttributeOwner owner = AttributeOwner::from_id(&const_cast<ID &>(object_data));
|
||||
const CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (!layer) {
|
||||
CTX_wm_operator_poll_msg_set(&C, "No active attribute");
|
||||
return false;
|
||||
@@ -212,9 +213,10 @@ static bool geometry_attributes_poll(bContext *C)
|
||||
{
|
||||
const Object *ob = object::context_object(C);
|
||||
const Main *bmain = CTX_data_main(C);
|
||||
const ID *data = (ob) ? static_cast<ID *>(ob->data) : nullptr;
|
||||
ID *data = (ob) ? static_cast<ID *>(ob->data) : nullptr;
|
||||
AttributeOwner owner = AttributeOwner::from_id(data);
|
||||
return (ob && BKE_id_is_editable(bmain, &ob->id) && data && BKE_id_is_editable(bmain, data)) &&
|
||||
BKE_id_attributes_supported(data);
|
||||
BKE_attributes_supported(owner);
|
||||
}
|
||||
|
||||
static bool geometry_attributes_remove_poll(bContext *C)
|
||||
@@ -225,7 +227,8 @@ static bool geometry_attributes_remove_poll(bContext *C)
|
||||
|
||||
Object *ob = object::context_object(C);
|
||||
ID *data = (ob) ? static_cast<ID *>(ob->data) : nullptr;
|
||||
if (BKE_id_attributes_active_get(data) != nullptr) {
|
||||
AttributeOwner owner = AttributeOwner::from_id(data);
|
||||
if (BKE_attributes_active_get(owner) != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -258,13 +261,14 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
|
||||
RNA_string_get(op->ptr, "name", name);
|
||||
eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type");
|
||||
bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
|
||||
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
|
||||
|
||||
if (layer == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_id_attributes_active_set(id, layer->name);
|
||||
BKE_attributes_active_set(owner, layer->name);
|
||||
|
||||
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
|
||||
@@ -328,13 +332,14 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = object::context_object(C);
|
||||
ID *id = static_cast<ID *>(ob->data);
|
||||
CustomDataLayer *layer = BKE_id_attributes_active_get(id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
|
||||
if (!BKE_id_attribute_remove(id, layer->name, op->reports)) {
|
||||
if (!BKE_attribute_remove(owner, layer->name, op->reports)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
int *active_index = BKE_id_attributes_active_index_p(id);
|
||||
int *active_index = BKE_attributes_active_index_p(owner);
|
||||
if (*active_index > 0) {
|
||||
*active_index -= 1;
|
||||
}
|
||||
@@ -369,7 +374,8 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op)
|
||||
RNA_string_get(op->ptr, "name", name);
|
||||
eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type");
|
||||
bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
|
||||
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
|
||||
|
||||
float color[4];
|
||||
RNA_float_get_array(op->ptr, "color", color);
|
||||
@@ -416,6 +422,7 @@ static bool geometry_attribute_convert_poll(bContext *C)
|
||||
|
||||
Object *ob = object::context_object(C);
|
||||
ID *data = static_cast<ID *>(ob->data);
|
||||
AttributeOwner owner = AttributeOwner::from_id(data);
|
||||
if (GS(data->name) != ID_ME) {
|
||||
return false;
|
||||
}
|
||||
@@ -423,7 +430,7 @@ static bool geometry_attribute_convert_poll(bContext *C)
|
||||
CTX_wm_operator_poll_msg_set(C, "Operation is not allowed in edit mode");
|
||||
return false;
|
||||
}
|
||||
if (BKE_id_attributes_active_get(data) == nullptr) {
|
||||
if (BKE_attributes_active_get(owner) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -433,7 +440,8 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = object::context_object(C);
|
||||
ID *ob_data = static_cast<ID *>(ob->data);
|
||||
CustomDataLayer *layer = BKE_id_attributes_active_get(ob_data);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ob_data);
|
||||
CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
const ConvertAttributeMode mode = static_cast<ConvertAttributeMode>(
|
||||
RNA_enum_get(op->ptr, "mode"));
|
||||
Mesh *mesh = reinterpret_cast<Mesh *>(ob_data);
|
||||
@@ -474,7 +482,8 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
|
||||
BKE_defvert_add_index_notest(dverts + i, defgroup_index, weight);
|
||||
}
|
||||
}
|
||||
int *active_index = BKE_id_attributes_active_index_p(&mesh->id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
int *active_index = BKE_attributes_active_index_p(owner);
|
||||
if (*active_index > 0) {
|
||||
*active_index -= 1;
|
||||
}
|
||||
@@ -596,8 +605,8 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
|
||||
if (active_name.empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (!BKE_id_attribute_remove(id, active_name.c_str(), op->reports)) {
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
if (!BKE_attribute_remove(owner, active_name.c_str(), op->reports)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -647,7 +656,8 @@ static int geometry_color_attribute_duplicate_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
CustomDataLayer *new_layer = BKE_id_attribute_duplicate(id, active_name, op->reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomDataLayer *new_layer = BKE_attribute_duplicate(owner, active_name, op->reports);
|
||||
if (new_layer == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
@@ -701,9 +711,10 @@ static int geometry_attribute_convert_invoke(bContext *C,
|
||||
{
|
||||
Object *ob = object::context_object(C);
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
|
||||
const bke::AttributeMetaData meta_data = *mesh->attributes().lookup_meta_data(
|
||||
BKE_id_attributes_active_get(&mesh->id)->name);
|
||||
BKE_attributes_active_get(owner)->name);
|
||||
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "domain");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
|
||||
@@ -149,7 +149,8 @@ static int mesh_set_attribute_exec(bContext *C, wmOperator *op)
|
||||
scene, view_layer, CTX_wm_view3d(C));
|
||||
|
||||
Mesh *mesh = ED_mesh_context(C);
|
||||
CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&mesh->id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *active_attribute = BKE_attributes_active_get(owner);
|
||||
const eCustomDataType active_type = eCustomDataType(active_attribute->type);
|
||||
const CPPType &type = *bke::custom_data_type_to_cpp_type(active_type);
|
||||
|
||||
@@ -166,7 +167,7 @@ static int mesh_set_attribute_exec(bContext *C, wmOperator *op)
|
||||
BMEditMesh *em = BKE_editmesh_from_object(object);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
CustomDataLayer *layer = BKE_id_attributes_active_get(&mesh->id);
|
||||
CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
@@ -181,7 +182,7 @@ static int mesh_set_attribute_exec(bContext *C, wmOperator *op)
|
||||
BLI_SCOPED_DEFER([&]() { dst_type.destruct(dst_buffer); });
|
||||
conversions.convert_to_uninitialized(type, dst_type, value.get(), dst_buffer);
|
||||
const GPointer dst_value(dst_type, dst_buffer);
|
||||
switch (BKE_id_attribute_domain(&mesh->id, layer)) {
|
||||
switch (BKE_attribute_domain(owner, layer)) {
|
||||
case bke::AttrDomain::Point:
|
||||
bmesh_vert_edge_face_layer_selected_values_set(
|
||||
*bm, BM_VERTS_OF_MESH, dst_value, layer->offset);
|
||||
@@ -217,10 +218,11 @@ static int mesh_set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
{
|
||||
Mesh *mesh = ED_mesh_context(C);
|
||||
BMesh *bm = mesh->runtime->edit_mesh->bm;
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
|
||||
const CustomDataLayer *layer = BKE_id_attributes_active_get(&mesh->id);
|
||||
const CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
const eCustomDataType data_type = eCustomDataType(layer->type);
|
||||
const bke::AttrDomain domain = BKE_id_attribute_domain(&mesh->id, layer);
|
||||
const bke::AttrDomain domain = BKE_attribute_domain(owner, layer);
|
||||
const BMElem *active_elem = BM_mesh_active_elem_get(bm);
|
||||
if (!active_elem) {
|
||||
return WM_operator_props_popup(C, op, event);
|
||||
@@ -250,7 +252,8 @@ static void mesh_set_attribute_ui(bContext *C, wmOperator *op)
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
Mesh *mesh = ED_mesh_context(C);
|
||||
CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&mesh->id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *active_attribute = BKE_attributes_active_get(owner);
|
||||
const eCustomDataType active_type = eCustomDataType(active_attribute->type);
|
||||
const StringRefNull prop_name = geometry::rna_property_name_for_type(active_type);
|
||||
const char *name = active_attribute->name;
|
||||
|
||||
@@ -5277,7 +5277,8 @@ static bool edbm_select_by_attribute_poll(bContext *C)
|
||||
}
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
const Mesh *mesh = static_cast<const Mesh *>(obedit->data);
|
||||
const CustomDataLayer *layer = BKE_id_attributes_active_get(&const_cast<ID &>(mesh->id));
|
||||
AttributeOwner owner = AttributeOwner::from_id(&const_cast<ID &>(mesh->id));
|
||||
const CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (!layer) {
|
||||
CTX_wm_operator_poll_msg_set(C, "There must be an active attribute");
|
||||
return false;
|
||||
@@ -5286,7 +5287,7 @@ static bool edbm_select_by_attribute_poll(bContext *C)
|
||||
CTX_wm_operator_poll_msg_set(C, "The active attribute must have a boolean type");
|
||||
return false;
|
||||
}
|
||||
if (BKE_id_attribute_domain(&mesh->id, layer) == bke::AttrDomain::Corner) {
|
||||
if (BKE_attribute_domain(owner, layer) == bke::AttrDomain::Corner) {
|
||||
CTX_wm_operator_poll_msg_set(
|
||||
C, "The active attribute must be on the vertex, edge, or face domain");
|
||||
return false;
|
||||
@@ -5320,19 +5321,19 @@ static int edbm_select_by_attribute_exec(bContext *C, wmOperator * /*op*/)
|
||||
Mesh *mesh = static_cast<Mesh *>(obedit->data);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
const CustomDataLayer *layer = BKE_id_attributes_active_get(&mesh->id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
if (layer->type != CD_PROP_BOOL) {
|
||||
continue;
|
||||
}
|
||||
if (BKE_id_attribute_domain(&mesh->id, layer) == bke::AttrDomain::Corner) {
|
||||
if (BKE_attribute_domain(owner, layer) == bke::AttrDomain::Corner) {
|
||||
continue;
|
||||
}
|
||||
const std::optional<BMIterType> iter_type = domain_to_iter_type(
|
||||
BKE_id_attribute_domain(&mesh->id, layer));
|
||||
BKE_attribute_domain(owner, layer));
|
||||
if (!iter_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3075,14 +3075,15 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
|
||||
BMOperator bmop;
|
||||
|
||||
Mesh *mesh = BKE_object_get_original_mesh(ob);
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
&mesh->id, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_CORNER);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_CORNER);
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int color_index = BKE_id_attribute_to_index(
|
||||
&mesh->id, layer, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
int color_index = BKE_attribute_to_index(
|
||||
owner, layer, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
EDBM_op_init(em,
|
||||
&bmop,
|
||||
op,
|
||||
@@ -3123,16 +3124,17 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
Mesh *mesh = BKE_object_get_original_mesh(obedit);
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
&mesh->id, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_CORNER);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner, mesh->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_CORNER);
|
||||
if (!layer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BMOperator bmop;
|
||||
|
||||
int color_index = BKE_id_attribute_to_index(
|
||||
&mesh->id, layer, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
int color_index = BKE_attribute_to_index(
|
||||
owner, layer, ATTR_DOMAIN_MASK_CORNER, CD_MASK_COLOR_ALL);
|
||||
EDBM_op_init(
|
||||
em, &bmop, op, "reverse_colors faces=%hf color_index=%i", BM_ELEM_SELECT, color_index);
|
||||
|
||||
|
||||
@@ -229,7 +229,8 @@ int ED_mesh_uv_add(
|
||||
name = DATA_("UVMap");
|
||||
}
|
||||
|
||||
const std::string unique_name = BKE_id_attribute_calc_unique_name(mesh->id, name);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const std::string unique_name = BKE_attribute_calc_unique_name(owner, name);
|
||||
bool is_init = false;
|
||||
|
||||
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
|
||||
@@ -386,8 +387,9 @@ int ED_mesh_color_add(
|
||||
name = "Col";
|
||||
}
|
||||
|
||||
CustomDataLayer *layer = BKE_id_attribute_new(
|
||||
&mesh->id, name, CD_PROP_BYTE_COLOR, bke::AttrDomain::Corner, reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *layer = BKE_attribute_new(
|
||||
owner, name, CD_PROP_BYTE_COLOR, bke::AttrDomain::Corner, reports);
|
||||
|
||||
if (do_init) {
|
||||
const char *active_name = mesh->active_color_attribute;
|
||||
@@ -426,7 +428,8 @@ bool ED_mesh_color_ensure(Mesh *mesh, const char *name)
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string unique_name = BKE_id_attribute_calc_unique_name(mesh->id, name);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const std::string unique_name = BKE_attribute_calc_unique_name(owner, name);
|
||||
if (!mesh->attributes_for_write().add(unique_name,
|
||||
bke::AttrDomain::Corner,
|
||||
CD_PROP_BYTE_COLOR,
|
||||
@@ -510,9 +513,10 @@ static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *op)
|
||||
Object *ob = blender::ed::object::context_object(C);
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomData *ldata = mesh_customdata_get_type(mesh, BM_LOOP, nullptr);
|
||||
const char *name = CustomData_get_active_layer_name(ldata, CD_PROP_FLOAT2);
|
||||
if (!BKE_id_attribute_remove(&mesh->id, name, op->reports)) {
|
||||
if (!BKE_attribute_remove(owner, name, op->reports)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -601,7 +605,8 @@ static int mesh_customdata_mask_clear_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *object = blender::ed::object::context_object(C);
|
||||
Mesh *mesh = static_cast<Mesh *>(object->data);
|
||||
const bool ret_a = BKE_id_attribute_remove(&mesh->id, ".sculpt_mask", op->reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const bool ret_a = BKE_attribute_remove(owner, ".sculpt_mask", op->reports);
|
||||
int ret_b = mesh_customdata_clear_exec__internal(C, BM_LOOP, CD_GRID_PAINT_MASK);
|
||||
|
||||
if (ret_a || ret_b == OPERATOR_FINISHED) {
|
||||
|
||||
@@ -1185,7 +1185,8 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
|
||||
const CustomDataLayer *active_color_layer = BKE_id_attributes_color_find(
|
||||
&mesh->id, mesh->active_color_attribute);
|
||||
BLI_assert(active_color_layer != nullptr);
|
||||
const bke::AttrDomain domain = BKE_id_attribute_domain(&mesh->id, active_color_layer);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const bke::AttrDomain domain = BKE_attribute_domain(owner, active_color_layer);
|
||||
|
||||
const int channels_num = targets->channels_num;
|
||||
const bool is_noncolor = targets->is_noncolor;
|
||||
|
||||
@@ -236,7 +236,8 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
|
||||
ED_mesh_color_add(static_cast<Mesh *>(ob->data), name, true, true, op->reports);
|
||||
}
|
||||
else {
|
||||
BKE_id_attribute_remove(static_cast<ID *>(ob->data), name, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(static_cast<ID *>(ob->data));
|
||||
BKE_attribute_remove(owner, name, nullptr);
|
||||
}
|
||||
}
|
||||
/* Vertex Weight Layer */
|
||||
|
||||
@@ -6560,7 +6560,8 @@ static const char *proj_paint_color_attribute_create(wmOperator *op, Object &ob)
|
||||
}
|
||||
|
||||
Mesh *mesh = static_cast<Mesh *>(ob.data);
|
||||
const CustomDataLayer *layer = BKE_id_attribute_new(&mesh->id, name, type, domain, op->reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
|
||||
if (!layer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2131,7 +2131,8 @@ static void fill_mesh_color(Mesh &mesh,
|
||||
BMesh *bm = em->bm;
|
||||
const std::string name = attribute_name;
|
||||
const CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh.id, name.c_str());
|
||||
const AttrDomain domain = BKE_id_attribute_domain(&mesh.id, layer);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh.id);
|
||||
const AttrDomain domain = BKE_attribute_domain(owner, layer);
|
||||
if (layer->type == CD_PROP_COLOR) {
|
||||
fill_bm_face_or_corner_attribute<ColorPaint4f>(
|
||||
*bm, color, domain, layer->offset, use_vert_sel);
|
||||
|
||||
@@ -1747,7 +1747,8 @@ static void set_active_layer(bContext *C, SculptAttrRef *attr)
|
||||
SculptAttrRef existing;
|
||||
save_active_attribute(*ob, &existing);
|
||||
|
||||
CustomDataLayer *layer = BKE_id_attribute_find(&mesh->id, attr->name, attr->type, attr->domain);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *layer = BKE_attribute_find(owner, attr->name, attr->type, attr->domain);
|
||||
|
||||
/* Temporary fix for #97408. This is a fundamental
|
||||
* bug in the undo stack; the operator code needs to push
|
||||
@@ -1758,13 +1759,13 @@ static void set_active_layer(bContext *C, SculptAttrRef *attr)
|
||||
* domain and just unconvert it.
|
||||
*/
|
||||
if (!layer) {
|
||||
layer = BKE_id_attribute_search_for_write(
|
||||
&mesh->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
layer = BKE_attribute_search_for_write(
|
||||
owner, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
|
||||
if (layer) {
|
||||
if (ED_geometry_attribute_convert(
|
||||
mesh, attr->name, eCustomDataType(attr->type), attr->domain, nullptr))
|
||||
{
|
||||
layer = BKE_id_attribute_find(&mesh->id, attr->name, attr->type, attr->domain);
|
||||
layer = BKE_attribute_find(owner, attr->name, attr->type, attr->domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1773,7 +1774,7 @@ static void set_active_layer(bContext *C, SculptAttrRef *attr)
|
||||
/* Memfile undo killed the layer; re-create it. */
|
||||
mesh->attributes_for_write().add(
|
||||
attr->name, attr->domain, attr->type, bke::AttributeInitDefaultValue());
|
||||
layer = BKE_id_attribute_find(&mesh->id, attr->name, attr->type, attr->domain);
|
||||
layer = BKE_attribute_find(owner, attr->name, attr->type, attr->domain);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
|
||||
|
||||
@@ -364,8 +364,9 @@ bool ABCGenericMeshWriter::get_velocities(Mesh *mesh, std::vector<Imath::V3f> &v
|
||||
{
|
||||
/* Export velocity attribute output by fluid sim, sequence cache modifier
|
||||
* and geometry nodes. */
|
||||
const CustomDataLayer *velocity_layer = BKE_id_attribute_find(
|
||||
&mesh->id, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
const CustomDataLayer *velocity_layer = BKE_attribute_find(
|
||||
owner, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point);
|
||||
|
||||
if (velocity_layer == nullptr) {
|
||||
return false;
|
||||
|
||||
@@ -522,8 +522,9 @@ void read_velocity(const V3fArraySamplePtr &velocities,
|
||||
return;
|
||||
}
|
||||
|
||||
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
|
||||
&config.mesh->id, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&config.mesh->id);
|
||||
CustomDataLayer *velocity_layer = BKE_attribute_new(
|
||||
owner, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point, nullptr);
|
||||
float(*velocity)[3] = (float(*)[3])velocity_layer->data;
|
||||
|
||||
for (int i = 0; i < num_velocity_vectors; i++) {
|
||||
|
||||
@@ -759,8 +759,9 @@ void USDGenericMeshWriter::write_surface_velocity(const Mesh *mesh, pxr::UsdGeom
|
||||
{
|
||||
/* Export velocity attribute output by fluid sim, sequence cache modifier
|
||||
* and geometry nodes. */
|
||||
CustomDataLayer *velocity_layer = BKE_id_attribute_find(
|
||||
&mesh->id, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point);
|
||||
AttributeOwner owner = AttributeOwner::from_id(const_cast<ID *>(&mesh->id));
|
||||
CustomDataLayer *velocity_layer = BKE_attribute_find(
|
||||
owner, "velocity", CD_PROP_FLOAT3, bke::AttrDomain::Point);
|
||||
|
||||
if (velocity_layer == nullptr) {
|
||||
return;
|
||||
|
||||
@@ -400,8 +400,9 @@ void MeshFromGeometry::create_colors(Mesh *mesh)
|
||||
mesh_geometry_.vertex_index_max_ < block.start_vertex_index + block.colors.size())
|
||||
{
|
||||
/* This block is suitable, use colors from it. */
|
||||
CustomDataLayer *color_layer = BKE_id_attribute_new(
|
||||
&mesh->id, "Color", CD_PROP_COLOR, bke::AttrDomain::Point, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
CustomDataLayer *color_layer = BKE_attribute_new(
|
||||
owner, "Color", CD_PROP_COLOR, bke::AttrDomain::Point, nullptr);
|
||||
BKE_id_attributes_active_color_set(&mesh->id, color_layer->name);
|
||||
BKE_id_attributes_default_color_set(&mesh->id, color_layer->name);
|
||||
float4 *colors = (float4 *)color_layer->data;
|
||||
|
||||
@@ -232,13 +232,15 @@ 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;
|
||||
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
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);
|
||||
if (BKE_id_attribute_required(ptr->owner_id, layer->name)) {
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
if (BKE_attribute_required(owner, layer->name)) {
|
||||
*r_info = N_("Cannot modify name of required geometry attribute");
|
||||
return false;
|
||||
}
|
||||
@@ -309,8 +311,8 @@ static const EnumPropertyItem *rna_Attribute_domain_itemf(bContext * /*C*/,
|
||||
|
||||
static int rna_Attribute_domain_get(PointerRNA *ptr)
|
||||
{
|
||||
return int(
|
||||
BKE_id_attribute_domain(ptr->owner_id, static_cast<const CustomDataLayer *>(ptr->data)));
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
return int(BKE_attribute_domain(owner, static_cast<const CustomDataLayer *>(ptr->data)));
|
||||
}
|
||||
|
||||
static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
|
||||
@@ -322,18 +324,19 @@ static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
|
||||
static bool rna_Attribute_is_required_get(PointerRNA *ptr)
|
||||
{
|
||||
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
|
||||
return BKE_id_attribute_required(ptr->owner_id, layer->name);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
return BKE_attribute_required(owner, layer->name);
|
||||
}
|
||||
|
||||
static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
if (!(CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL)) {
|
||||
iter->valid = false;
|
||||
}
|
||||
|
||||
const int length = BKE_id_attribute_data_length(id, layer);
|
||||
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);
|
||||
|
||||
@@ -342,9 +345,9 @@ static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRN
|
||||
|
||||
static int rna_Attribute_data_length(PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
return BKE_id_attribute_data_length(id, layer);
|
||||
return BKE_attribute_data_length(owner, layer);
|
||||
}
|
||||
|
||||
static void rna_Attribute_update_data(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
|
||||
@@ -407,8 +410,9 @@ static void rna_FloatColorAttributeValue_color_srgb_set(PointerRNA *ptr, const f
|
||||
static PointerRNA rna_AttributeGroup_new(
|
||||
ID *id, ReportList *reports, const char *name, const int type, const int domain)
|
||||
{
|
||||
CustomDataLayer *layer = BKE_id_attribute_new(
|
||||
id, name, eCustomDataType(type), AttrDomain(domain), reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomDataLayer *layer = BKE_attribute_new(
|
||||
owner, name, eCustomDataType(type), AttrDomain(domain), reports);
|
||||
|
||||
if (!layer) {
|
||||
return PointerRNA_NULL;
|
||||
@@ -433,8 +437,9 @@ static PointerRNA rna_AttributeGroup_new(
|
||||
|
||||
static void rna_AttributeGroup_remove(ID *id, ReportList *reports, PointerRNA *attribute_ptr)
|
||||
{
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
const CustomDataLayer *layer = (const CustomDataLayer *)attribute_ptr->data;
|
||||
BKE_id_attribute_remove(id, layer->name, reports);
|
||||
BKE_attribute_remove(owner, layer->name, reports);
|
||||
RNA_POINTER_INVALIDATE(attribute_ptr);
|
||||
|
||||
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
|
||||
@@ -452,8 +457,8 @@ static bool rna_Attributes_noncolor_layer_skip(CollectionPropertyIterator *iter,
|
||||
CustomDataLayer *layer = (CustomDataLayer *)data;
|
||||
|
||||
/* Check valid domain here, too, keep in line with rna_AttributeGroup_color_length(). */
|
||||
ID *id = iter->parent.owner_id;
|
||||
const AttrDomain domain = BKE_id_attribute_domain(id, layer);
|
||||
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;
|
||||
}
|
||||
@@ -473,7 +478,8 @@ static void rna_AttributeGroup_next_domain(ID *id,
|
||||
nullptr :
|
||||
(CustomDataLayer *)iter->internal.array.endptr -
|
||||
iter->internal.array.length;
|
||||
CustomData *customdata = BKE_id_attributes_iterator_next_domain(id, prev_layers);
|
||||
AttributeOwner owner = AttributeOwner::from_id(id);
|
||||
CustomData *customdata = BKE_attributes_iterator_next_domain(owner, prev_layers);
|
||||
if (customdata == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -538,25 +544,28 @@ PointerRNA rna_AttributeGroup_color_iterator_get(CollectionPropertyIterator *ite
|
||||
|
||||
int rna_AttributeGroup_color_length(PointerRNA *ptr)
|
||||
{
|
||||
return BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
}
|
||||
|
||||
int rna_AttributeGroup_length(PointerRNA *ptr)
|
||||
{
|
||||
return BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
}
|
||||
|
||||
static int rna_AttributeGroup_active_index_get(PointerRNA *ptr)
|
||||
{
|
||||
return *BKE_id_attributes_active_index_p(ptr->owner_id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
return *BKE_attributes_active_index_p(owner);
|
||||
}
|
||||
|
||||
static PointerRNA rna_AttributeGroup_active_get(PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
CustomDataLayer *layer = BKE_id_attributes_active_get(id);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
CustomDataLayer *layer = BKE_attributes_active_get(owner);
|
||||
|
||||
PointerRNA attribute_ptr = RNA_pointer_create(id, &RNA_Attribute, layer);
|
||||
PointerRNA attribute_ptr = RNA_pointer_create(ptr->owner_id, &RNA_Attribute, layer);
|
||||
return attribute_ptr;
|
||||
}
|
||||
|
||||
@@ -564,21 +573,23 @@ static void rna_AttributeGroup_active_set(PointerRNA *ptr,
|
||||
PointerRNA attribute_ptr,
|
||||
ReportList * /*reports*/)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
|
||||
BKE_id_attributes_active_set(id, layer->name);
|
||||
BKE_attributes_active_set(owner, layer->name);
|
||||
}
|
||||
|
||||
static void rna_AttributeGroup_active_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
*BKE_id_attributes_active_index_p(ptr->owner_id) = value;
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
*BKE_attributes_active_index_p(owner) = value;
|
||||
}
|
||||
|
||||
static void rna_AttributeGroup_active_index_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
|
||||
{
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
*min = 0;
|
||||
*max = BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
@@ -591,14 +602,14 @@ static void rna_AttributeGroup_update_active(Main *bmain, Scene *scene, PointerR
|
||||
|
||||
static PointerRNA rna_AttributeGroup_active_color_get(PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
CustomDataLayer *layer = BKE_id_attribute_search_for_write(
|
||||
ptr->owner_id,
|
||||
BKE_id_attributes_active_color_name(id),
|
||||
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),
|
||||
CD_MASK_COLOR_ALL,
|
||||
ATTR_DOMAIN_MASK_COLOR);
|
||||
|
||||
PointerRNA attribute_ptr = RNA_pointer_create(id, &RNA_Attribute, layer);
|
||||
PointerRNA attribute_ptr = RNA_pointer_create(ptr->owner_id, &RNA_Attribute, layer);
|
||||
return attribute_ptr;
|
||||
}
|
||||
|
||||
@@ -613,20 +624,21 @@ static void rna_AttributeGroup_active_color_set(PointerRNA *ptr,
|
||||
|
||||
static int rna_AttributeGroup_active_color_index_get(PointerRNA *ptr)
|
||||
{
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
ptr->owner_id,
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner,
|
||||
BKE_id_attributes_active_color_name(ptr->owner_id),
|
||||
CD_MASK_COLOR_ALL,
|
||||
ATTR_DOMAIN_MASK_COLOR);
|
||||
|
||||
return BKE_id_attribute_to_index(
|
||||
ptr->owner_id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
return BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
}
|
||||
|
||||
static void rna_AttributeGroup_active_color_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
CustomDataLayer *layer = BKE_id_attribute_from_index(
|
||||
ptr->owner_id, value, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
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);
|
||||
@@ -639,8 +651,9 @@ static void rna_AttributeGroup_active_color_index_set(PointerRNA *ptr, int value
|
||||
static void rna_AttributeGroup_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_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
@@ -661,17 +674,18 @@ static void rna_AttributeGroup_update_active_color(Main * /*bmain*/,
|
||||
|
||||
static int rna_AttributeGroup_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));
|
||||
|
||||
return BKE_id_attribute_to_index(
|
||||
ptr->owner_id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
return BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
}
|
||||
|
||||
static void rna_AttributeGroup_render_color_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
CustomDataLayer *layer = BKE_id_attribute_from_index(
|
||||
ptr->owner_id, value, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
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);
|
||||
@@ -684,8 +698,9 @@ static void rna_AttributeGroup_render_color_index_set(PointerRNA *ptr, int value
|
||||
static void rna_AttributeGroup_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_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
*max = BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
|
||||
@@ -120,7 +120,8 @@ static void rna_MeshVertexLayer_name_set(PointerRNA *ptr, const char *value)
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
|
||||
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
BKE_attribute_rename(owner, layer->name, value, nullptr);
|
||||
}
|
||||
else {
|
||||
rna_cd_layer_name_set(rna_mesh_vdata(ptr), layer, value);
|
||||
@@ -132,7 +133,8 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value)
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
|
||||
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
BKE_attribute_rename(owner, layer->name, value, nullptr);
|
||||
}
|
||||
else {
|
||||
rna_cd_layer_name_set(rna_mesh_edata(ptr), layer, value);
|
||||
@@ -144,7 +146,8 @@ static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
|
||||
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, nullptr);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
BKE_attribute_rename(owner, layer->name, value, nullptr);
|
||||
}
|
||||
else {
|
||||
rna_cd_layer_name_set(rna_mesh_ldata(ptr), layer, value);
|
||||
@@ -1105,8 +1108,9 @@ DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_color, ldata, CD_PROP_BYTE_COLOR)
|
||||
static PointerRNA rna_Mesh_vertex_color_active_get(PointerRNA *ptr)
|
||||
{
|
||||
Mesh *mesh = (Mesh *)ptr->data;
|
||||
CustomDataLayer *layer = BKE_id_attribute_search_for_write(
|
||||
&mesh->id, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
CustomDataLayer *layer = BKE_attribute_search_for_write(
|
||||
owner, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_MeshLoopColorLayer, layer);
|
||||
}
|
||||
|
||||
@@ -1127,8 +1131,9 @@ static void rna_Mesh_vertex_color_active_set(PointerRNA *ptr,
|
||||
static int rna_Mesh_vertex_color_active_index_get(PointerRNA *ptr)
|
||||
{
|
||||
Mesh *mesh = (Mesh *)ptr->data;
|
||||
const CustomDataLayer *layer = BKE_id_attribute_search(
|
||||
&mesh->id, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
|
||||
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
|
||||
const CustomDataLayer *layer = BKE_attribute_search(
|
||||
owner, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER);
|
||||
if (!layer) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1890,7 +1895,8 @@ static PointerRNA rna_Mesh_vertex_color_new(Mesh *mesh,
|
||||
|
||||
static void rna_Mesh_vertex_color_remove(Mesh *mesh, ReportList *reports, CustomDataLayer *layer)
|
||||
{
|
||||
BKE_id_attribute_remove(&mesh->id, layer->name, reports);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
BKE_attribute_remove(owner, layer->name, reports);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Mesh_uv_layers_new(Mesh *mesh,
|
||||
@@ -1914,11 +1920,12 @@ static PointerRNA rna_Mesh_uv_layers_new(Mesh *mesh,
|
||||
static void rna_Mesh_uv_layers_remove(Mesh *mesh, ReportList *reports, CustomDataLayer *layer)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!BKE_id_attribute_find(&mesh->id, layer->name, CD_PROP_FLOAT2, bke::AttrDomain::Corner)) {
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
|
||||
if (!BKE_attribute_find(owner, layer->name, CD_PROP_FLOAT2, bke::AttrDomain::Corner)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "UV map '%s' not found", layer->name);
|
||||
return;
|
||||
}
|
||||
BKE_id_attribute_remove(&mesh->id, layer->name, reports);
|
||||
BKE_attribute_remove(owner, layer->name, reports);
|
||||
}
|
||||
|
||||
static bool rna_Mesh_is_editmode_get(PointerRNA *ptr)
|
||||
|
||||
@@ -102,7 +102,8 @@ static blender::bke::SpanAttributeWriter<blender::float2> get_uv_attribute(
|
||||
{
|
||||
return attribute;
|
||||
}
|
||||
const std::string name = BKE_id_attribute_calc_unique_name(mesh.id, md_name);
|
||||
AttributeOwner owner = AttributeOwner::from_id(&mesh.id);
|
||||
const std::string name = BKE_attribute_calc_unique_name(owner, md_name);
|
||||
return attributes.lookup_or_add_for_write_span<float2>(name, bke::AttrDomain::Corner);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user