Refactor: Extract BMesh attribute lookup function
This is the second time I've needed a function to find an attribute by name on all attribute domains, with a third time coming soon. It seems time to put this in a BMesh header. Pull Request: https://projects.blender.org/blender/blender/pulls/144039
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
#include "BLI_task.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_attribute_legacy_convert.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_multires.hh"
|
||||
|
||||
@@ -1067,6 +1069,40 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float
|
||||
}
|
||||
}
|
||||
|
||||
BMDataLayerLookup BM_data_layer_lookup(const BMesh &bm, const blender::StringRef name)
|
||||
{
|
||||
using namespace blender;
|
||||
for (const CustomDataLayer &layer : Span(bm.vdata.layers, bm.vdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Point,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.edata.layers, bm.edata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Edge,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.pdata.layers, bm.pdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Face,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.ldata.layers, bm.ldata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Corner,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_***
|
||||
*
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
struct LinkNode;
|
||||
struct MemArena;
|
||||
|
||||
namespace blender::bke {
|
||||
enum class AttrDomain : int8_t;
|
||||
enum class AttrType : int16_t;
|
||||
} // namespace blender::bke
|
||||
|
||||
void BM_loop_interp_multires_ex(BMesh *bm,
|
||||
BMLoop *l_dst,
|
||||
const BMFace *f_src,
|
||||
@@ -88,6 +93,24 @@ bool BM_data_layer_free_named(BMesh *bm, CustomData *data, blender::StringRef na
|
||||
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
|
||||
void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n);
|
||||
|
||||
/* See #BM_data_layer_lookup. */
|
||||
struct BMDataLayerLookup {
|
||||
const int offset = -1;
|
||||
blender::bke::AttrDomain domain;
|
||||
blender::bke::AttrType type;
|
||||
operator bool() const
|
||||
{
|
||||
return offset != -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Search for a named custom data layer on all attribute domains and return the domain and type.
|
||||
* This is roughly analogous to #Mesh::attributes().lookup(...), but keep in mind that certain
|
||||
* attributes stored on #Mesh are not stored as attributes on #BMesh.
|
||||
*/
|
||||
BMDataLayerLookup BM_data_layer_lookup(const BMesh &bm, const blender::StringRef name);
|
||||
|
||||
float BM_elem_float_data_get(CustomData *cd, void *element, int type);
|
||||
void BM_elem_float_data_set(CustomData *cd, void *element, int type, float val);
|
||||
|
||||
|
||||
@@ -1054,49 +1054,6 @@ BLI_NOINLINE static void update_face_sets_bmesh(const Object &object,
|
||||
}
|
||||
}
|
||||
|
||||
struct BMeshAttributeLookup {
|
||||
const int offset = -1;
|
||||
bke::AttrDomain domain;
|
||||
bke::AttrType type;
|
||||
operator bool() const
|
||||
{
|
||||
return offset != -1;
|
||||
}
|
||||
};
|
||||
|
||||
static BMeshAttributeLookup lookup_bmesh_attribute(const BMesh &bm, const StringRef name)
|
||||
{
|
||||
for (const CustomDataLayer &layer : Span(bm.vdata.layers, bm.vdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Point,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.edata.layers, bm.edata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Edge,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.pdata.layers, bm.pdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Face,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.ldata.layers, bm.ldata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Corner,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
BLI_NOINLINE static void update_generic_attribute_bmesh(const Object &object,
|
||||
const OrigMeshData &orig_mesh_data,
|
||||
const IndexMask &node_mask,
|
||||
@@ -1106,7 +1063,7 @@ BLI_NOINLINE static void update_generic_attribute_bmesh(const Object &object,
|
||||
const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
|
||||
const Span<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
|
||||
const BMesh &bm = *object.sculpt->bm;
|
||||
const BMeshAttributeLookup attr = lookup_bmesh_attribute(bm, name);
|
||||
const BMDataLayerLookup attr = BM_data_layer_lookup(bm, name);
|
||||
if (!attr || attr.domain == bke::AttrDomain::Edge) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -171,51 +171,8 @@ static void extract_data_bmesh_loop(const BMesh &bm, const int cd_offset, gpu::V
|
||||
}
|
||||
}
|
||||
|
||||
struct BMeshAttributeLookup {
|
||||
const int offset = -1;
|
||||
bke::AttrDomain domain;
|
||||
bke::AttrType type;
|
||||
operator bool() const
|
||||
{
|
||||
return offset != -1;
|
||||
}
|
||||
};
|
||||
|
||||
static BMeshAttributeLookup lookup_bmesh_attribute(const BMesh &bm, const StringRef name)
|
||||
{
|
||||
for (const CustomDataLayer &layer : Span(bm.vdata.layers, bm.vdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Point,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.edata.layers, bm.edata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Edge,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.pdata.layers, bm.pdata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Face,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
for (const CustomDataLayer &layer : Span(bm.ldata.layers, bm.ldata.totlayer)) {
|
||||
if (layer.name == name) {
|
||||
return {layer.offset,
|
||||
bke::AttrDomain::Corner,
|
||||
*bke::custom_data_type_to_attr_type(eCustomDataType(layer.type))};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static void extract_attribute_data(const MeshRenderData &mr,
|
||||
const BMeshAttributeLookup &attr,
|
||||
const BMDataLayerLookup &attr,
|
||||
gpu::VertBuf &vbo)
|
||||
{
|
||||
bke::attribute_math::convert_to_static_type(attr.type, [&](auto dummy) {
|
||||
@@ -272,7 +229,7 @@ gpu::VertBufPtr extract_attribute(const MeshRenderData &mr, const StringRef name
|
||||
{
|
||||
gpu::VertBuf *vbo = GPU_vertbuf_calloc();
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
const BMeshAttributeLookup attr = lookup_bmesh_attribute(*mr.bm, name);
|
||||
const BMDataLayerLookup attr = BM_data_layer_lookup(*mr.bm, name);
|
||||
if (!attr) {
|
||||
return {};
|
||||
}
|
||||
@@ -313,7 +270,7 @@ gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr,
|
||||
gpu::VertBufPtr coarse_vbo;
|
||||
bke::AttrType type;
|
||||
if (mr.extract_type == MeshExtractType::BMesh) {
|
||||
const BMeshAttributeLookup attr = lookup_bmesh_attribute(*mr.bm, name);
|
||||
const BMDataLayerLookup attr = BM_data_layer_lookup(*mr.bm, name);
|
||||
if (!attr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user