38#include <fmt/format.h>
70 return ptr_ !=
nullptr;
77 return reinterpret_cast<Mesh *
>(ptr_);
91 return reinterpret_cast<Curves *
>(ptr_);
132 return this->
get_mesh()->attributes_for_write();
153 std::array<DomainInfo, ATTR_DOMAIN_NUM> info;
155 switch (owner.
type()) {
168 info[int(AttrDomain::Point)].customdata = &
bm->vdata;
169 info[int(AttrDomain::Point)].length =
bm->totvert;
170 info[int(AttrDomain::Edge)].customdata = &
bm->edata;
171 info[int(AttrDomain::Edge)].length =
bm->totedge;
172 info[int(AttrDomain::Corner)].customdata = &
bm->ldata;
173 info[int(AttrDomain::Corner)].length =
bm->totloop;
174 info[int(AttrDomain::Face)].customdata = &
bm->pdata;
175 info[int(AttrDomain::Face)].length =
bm->totface;
178 info[int(AttrDomain::Point)].customdata = &mesh->
vert_data;
179 info[int(AttrDomain::Point)].length = mesh->
verts_num;
180 info[int(AttrDomain::Edge)].customdata = &mesh->
edge_data;
181 info[int(AttrDomain::Edge)].length = mesh->
edges_num;
182 info[int(AttrDomain::Corner)].customdata = &mesh->
corner_data;
183 info[int(AttrDomain::Corner)].length = mesh->
corners_num;
184 info[int(AttrDomain::Face)].customdata = &mesh->
face_data;
185 info[int(AttrDomain::Face)].length = mesh->
faces_num;
201 if (layer ==
nullptr) {
215 if (domain != metadata->domain) {
218 "Domain unsupported for \"%s\" attribute",
219 std::string(
name).c_str());
222 if (data_type != metadata->data_type) {
224 reports,
RPT_ERROR,
"Type unsupported for \"%s\" attribute", std::string(
name).c_str());
268 if (!attributes.
lookup(old_name)) {
272 attributes.
rename(old_name, new_name);
284 if (old_name == new_name_clamped) {
291 if (layer ==
nullptr) {
310 curves->
geometry.wrap().attributes(),
350 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
353 if (!info[domain].customdata) {
357 const CustomData *cdata = info[domain].customdata;
389 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
391 CustomData *customdata = info[int(domain)].customdata;
392 if (customdata ==
nullptr) {
409 return (index == -1) ?
nullptr : &(customdata->
layers[index]);
413 std::optional<MutableAttributeAccessor> attributes = owner.
get_accessor();
426 return (index == -1) ?
nullptr : &(customdata->
layers[index]);
435 std::optional<MutableAttributeAccessor> attributes = owner.
get_accessor();
445 attributes->add(dstname,
460 if (
mesh->runtime->edit_mesh) {
466 std::optional<MutableAttributeAccessor> attributes = owner.
get_accessor();
509 return layer ? layer->
name :
"";
516 if (
name.is_empty()) {
526 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
531 const std::string name_copy =
name;
533 if (layer_index == -1) {
538 const bool is_active_color_attribute = name_copy.c_str() ==
540 const bool is_default_color_attribute = name_copy.c_str() ==
544 mesh->default_color_attribute);
550 if (is_active_color_attribute) {
555 if (is_default_color_attribute) {
572 std::optional<MutableAttributeAccessor> attributes = owner.
get_accessor();
578 const std::string name_copy =
name;
579 std::optional<blender::bke::AttributeMetaData> metadata = attributes->lookup_meta_data(
586 const bool is_active_color_attribute = name_copy ==
StringRef(
mesh->active_color_attribute);
587 const bool is_default_color_attribute = name_copy ==
StringRef(
mesh->default_color_attribute);
591 if (!attributes->remove(name_copy)) {
595 if (is_active_color_attribute) {
599 if (is_default_color_attribute) {
611 return attributes->remove(
name);
619 if (
name.is_empty()) {
622 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
624 CustomData *customdata = info[int(domain)].customdata;
625 if (customdata ==
nullptr) {
641 const eCustomDataMask type_mask,
644 if (
name.is_empty()) {
647 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
656 CustomData *customdata = info[int(domain)].customdata;
657 if (customdata ==
nullptr) {
674 const eCustomDataMask type_mask,
685 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
695 eCustomDataMask
mask)
697 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
702 const CustomData *customdata = info[domain].customdata;
703 if (customdata ==
nullptr) {
707 if ((1 <<
int(domain)) & domain_mask) {
717 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
720 const CustomData *customdata = info[domain].customdata;
721 if (customdata ==
nullptr) {
735 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
736 return info[domain].length;
746 if (
mesh->runtime->edit_mesh !=
nullptr) {
751 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
754 const CustomData *customdata = info[domain].customdata;
755 if (customdata ==
nullptr) {
759 return info[domain].length;
769 switch (owner.
type()) {
789 if (active_index == -1) {
804 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
809 CustomData *customdata = info[domain].customdata;
810 if (customdata ==
nullptr) {
816 if (index == active_index) {
854 switch (owner.
type()) {
876 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
878 bool use_next = (layers ==
nullptr);
881 CustomData *customdata = info[domain].customdata;
882 if (customdata ==
nullptr) {
886 if (customdata->
layers == layers) {
901 eCustomDataMask layer_mask)
903 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
907 CustomData *customdata = info[domain].customdata;
909 if (!customdata || !((1 <<
int(domain)) & domain_mask)) {
920 if (index == lookup_index) {
934 eCustomDataMask layer_mask)
940 const std::array<DomainInfo, ATTR_DOMAIN_NUM> info =
get_domains(owner);
944 const CustomData *customdata = info[domain].customdata;
946 if (!customdata || !((1 <<
int(domain)) & domain_mask)) {
958 if (layer == layer_iter) {
972 return reinterpret_cast<const Mesh *
>(
id)->active_color_attribute;
980 return reinterpret_cast<const Mesh *
>(
id)->default_color_attribute;
987 switch (
GS(
id->name)) {
1003 switch (
GS(
id->name)) {
1016 switch (
GS(
id->name)) {
1038 std::optional<blender::bke::AttributeMetaData> meta_data =
mesh.attributes().lookup_meta_data(
1056 const auto result = fmt::format_to_n(
blender::StringRef BKE_uv_map_pin_name_get(blender::StringRef uv_map_name, char *buffer)
blender::bke::AttrDomain BKE_attribute_domain(const AttributeOwner &owner, const struct CustomDataLayer *layer)
#define ATTR_DOMAIN_MASK_COLOR
#define ATTR_DOMAIN_AS_MASK(domain)
bool BKE_curves_attribute_required(const struct Curves *curves, blender::StringRef name)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_named_layer_index_notype(const CustomData *data, blender::StringRef name)
eCustomDataMask CD_TYPE_AS_MASK(eCustomDataType type)
int CustomData_number_of_layers_typemask(const CustomData *data, eCustomDataMask mask)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_name_maxncpy_calc(blender::StringRef name)
void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, int totelem)
Low-level operations for grease pencil.
bool BKE_grease_pencil_drawing_attribute_required(const GreasePencilDrawing *, blender::StringRef name)
bool BKE_mesh_attribute_required(blender::StringRef name)
General operations for point clouds.
bool BKE_pointcloud_attribute_required(const PointCloud *pointcloud, blender::StringRef name)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE int min_ii(int a, int b)
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
ID and Library types, which are fundamental for SDNA.
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_COLOR_ALL
Read Guarded memory(de)allocation.
bool BKE_color_attribute_supported(const Mesh &mesh, const StringRef name)
static int color_name_to_index(AttributeOwner &owner, const StringRef name)
std::optional< StringRef > BKE_id_attributes_active_color_name(const ID *id)
bool BKE_attribute_rename(AttributeOwner &owner, const StringRef old_name, const StringRef new_name, ReportList *reports)
std::optional< blender::StringRefNull > BKE_attributes_active_name_get(AttributeOwner &owner)
CustomData * BKE_attributes_iterator_next_domain(AttributeOwner &owner, CustomDataLayer *layers)
static int color_clamp_index(AttributeOwner &owner, int index)
int BKE_attribute_to_index(const AttributeOwner &owner, const CustomDataLayer *layer, AttrDomainMask domain_mask, eCustomDataMask layer_mask)
CustomDataLayer * BKE_attribute_new(AttributeOwner &owner, const StringRef name, const eCustomDataType type, const AttrDomain domain, ReportList *reports)
AttrDomain BKE_attribute_domain(const AttributeOwner &owner, const CustomDataLayer *layer)
StringRef BKE_uv_map_pin_name_get(const StringRef uv_map_name, char *buffer)
CustomDataLayer * BKE_attribute_search_for_write(AttributeOwner &owner, const StringRef name, const eCustomDataMask type_mask, const AttrDomainMask domain_mask)
static void bke_attribute_copy_if_exists(AttributeOwner &owner, const StringRef srcname, const StringRef dstname)
const CustomDataLayer * BKE_attribute_search(const AttributeOwner &owner, const StringRef name, const eCustomDataMask type_mask, const AttrDomainMask domain_mask)
void BKE_id_attributes_default_color_set(ID *id, const std::optional< StringRef > name)
CustomDataLayer * BKE_attribute_from_index(AttributeOwner &owner, int lookup_index, AttrDomainMask domain_mask, eCustomDataMask layer_mask)
void BKE_attributes_active_set(AttributeOwner &owner, const StringRef name)
static bool attribute_name_exists(const AttributeOwner &owner, const StringRef name)
int * BKE_attributes_active_index_p(AttributeOwner &owner)
bool BKE_attribute_remove(AttributeOwner &owner, const StringRef name, ReportList *reports)
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, const StringRef name)
CustomDataLayer * BKE_attribute_duplicate(AttributeOwner &owner, const StringRef name, ReportList *reports)
void BKE_id_attributes_active_color_set(ID *id, const std::optional< StringRef > name)
const CustomDataLayer * BKE_id_attributes_color_find(const ID *id, const StringRef name)
void BKE_id_attributes_active_color_clear(ID *id)
static bool mesh_attribute_valid(const Mesh &mesh, const StringRef name, const AttrDomain domain, const blender::bke::AttrType data_type, ReportList *reports)
static StringRef color_name_from_index(AttributeOwner &owner, int index)
static bool bke_attribute_rename_if_exists(AttributeOwner &owner, const StringRef old_name, const StringRef new_name, ReportList *reports)
CustomDataLayer * BKE_attribute_find(const AttributeOwner &owner, const StringRef name, const eCustomDataType type, const AttrDomain domain)
std::optional< StringRef > BKE_id_attributes_default_color_name(const ID *id)
static std::array< DomainInfo, ATTR_DOMAIN_NUM > get_domains(const AttributeOwner &owner)
bool BKE_attribute_required(const AttributeOwner &owner, const StringRef name)
int BKE_attribute_data_length(AttributeOwner &owner, CustomDataLayer *layer)
int BKE_attributes_length(const AttributeOwner &owner, AttrDomainMask domain_mask, eCustomDataMask mask)
static bool name_valid_for_builtin_domain_and_type(const blender::bke::AttributeAccessor attributes, const StringRef name, const AttrDomain domain, const blender::bke::AttrType data_type, ReportList *reports)
int BKE_attribute_domain_size(const AttributeOwner &owner, const int domain)
void BKE_attributes_active_clear(AttributeOwner &owner)
bool BM_data_layer_free_named(BMesh *bm, CustomData *data, StringRef name)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const StringRef name)
BMesh const char void * data
bool BM_attribute_stored_in_bmesh_builtin(const StringRef name)
AttributeOwnerType type() const
std::optional< blender::bke::MutableAttributeAccessor > get_accessor() const
static AttributeOwner from_id(ID *id)
GreasePencil * get_grease_pencil() const
PointCloud * get_pointcloud() const
Curves * get_curves() const
GreasePencilDrawing * get_grease_pencil_drawing() const
blender::bke::AttributeStorage * get_storage() const
const CPPType & type() const
constexpr bool contains(int64_t value) const
constexpr bool contains_ptr(const T *ptr) const
constexpr bool is_empty() const
constexpr int64_t size() const
void copy_utf8_truncated(char *dst, int64_t dst_size) const
std::optional< AttributeDomainAndType > get_builtin_domain_and_type(const StringRef name) const
void rename(StringRef old_name, std::string new_name)
Attribute * lookup(StringRef name)
Attribute & at_index(int index)
std::string unique_name_calc(StringRef name) const
int index_of(StringRef name) const
StringRefNull name() const
float length(VecOp< float, D >) RET
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
std::optional< eCustomDataType > attr_type_to_custom_data_type(AttrType attr_type)
bool allow_procedural_attribute_access(StringRef attribute_name)
std::optional< AttrType > custom_data_type_to_attr_type(eCustomDataType data_type)
AttrType cpp_type_to_attribute_type(const CPPType &type)
int attributes_active_index
struct AttributeStorage attribute_storage
int attributes_active_index
struct AttributeStorage attribute_storage
struct AttributeStorage attribute_storage
MeshRuntimeHandle * runtime
int attributes_active_index
int attributes_active_index
struct AttributeStorage attribute_storage