Cleanup: Use C++ attribute API instead of CustomData API

This gives better asserts in debug builds through use of Span, more
safety when name convention attributes happen to have different types
or domains, and simpler code in some cases. But the main reasoning is to
avoid relying on the specifics of CustomData more to allow us to replace
it in the future.
This commit is contained in:
Hans Goudey 2023-12-12 17:49:51 -05:00
parent 1d0179adbb
commit c53e220aef
42 changed files with 322 additions and 328 deletions

View File

@ -155,6 +155,8 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
*
* \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on
* each side of the edge.
* \param sharp_faces: Optional array of sharp face tags, used to split the evaluated normals on
* the face's edges.
* \param r_lnors_spacearr: Optional return data filled with information about the custom
* normals spaces for each grouped fan of face corners.
*/
@ -166,12 +168,15 @@ void normals_calc_loop(Span<float3> vert_positions,
Span<int> loop_to_face_map,
Span<float3> vert_normals,
Span<float3> face_normals,
const bool *sharp_edges,
const bool *sharp_faces,
Span<bool> sharp_edges,
Span<bool> sharp_faces,
const short2 *clnors_data,
CornerNormalSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals);
/**
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void normals_loop_custom_set(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
@ -179,11 +184,14 @@ void normals_loop_custom_set(Span<float3> vert_positions,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
const bool *sharp_faces,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
MutableSpan<short2> r_clnors_data);
/**
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
*/
void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<int2> edges,
OffsetIndices<int> faces,
@ -191,7 +199,7 @@ void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
const bool *sharp_faces,
Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
MutableSpan<short2> r_clnors_data);
@ -209,7 +217,7 @@ void edges_sharp_from_angle_set(OffsetIndices<int> faces,
Span<int> corner_edges,
Span<float3> face_normals,
Span<int> loop_to_face,
const bool *sharp_faces,
Span<bool> sharp_faces,
const float split_angle,
MutableSpan<bool> sharp_edges);

View File

@ -248,6 +248,8 @@ bool BKE_mesh_calc_islands_loop_face_uvmap(float (*vert_positions)[3],
/**
* Calculate smooth groups from sharp edges.
*
* \param sharp_edges: Optional (possibly empty) span.
* \param sharp_faces: Optional (possibly empty) span.
* \param r_totgroup: The total number of groups, 1 or more.
* \return Polygon aligned array of group index values (bitflags if use_bitflags is true),
* starting at 1 (0 being used as 'invalid' flag).
@ -256,8 +258,8 @@ bool BKE_mesh_calc_islands_loop_face_uvmap(float (*vert_positions)[3],
int *BKE_mesh_calc_smoothgroups(int edges_num,
blender::OffsetIndices<int> faces,
blender::Span<int> corner_edges,
const bool *sharp_edges,
const bool *sharp_faces,
blender::Span<bool> sharp_edges,
blender::Span<bool> sharp_faces,
int *r_totgroup,
bool use_bitflags);

View File

@ -51,7 +51,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const MLoopTri *looptri,
const int *looptri_faces,
uint looptri_len,
const bool *sharp_faces,
const blender::Span<bool> sharp_faces,
CustomData *loopdata,
bool calc_active_tangent,

View File

@ -244,7 +244,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
float (*origco)[3],
bool use_origco,
blender::Span<int> corner_verts,
const bool *hide_poly,
blender::Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@ -284,7 +284,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
float (*origco)[3],
bool use_origco,
blender::Span<int> corner_verts,
const bool *hide_poly,
blender::Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,

View File

@ -378,8 +378,7 @@ static void data_transfer_dtdata_type_postprocess(Mesh *me_dst,
bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write();
bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&me_dst->face_data, CD_PROP_BOOL, "sharp_face"));
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
/* Note loop_nors_dst contains our custom normals as transferred from source... */
blender::bke::mesh::normals_loop_custom_set(me_dst->vert_positions(),
me_dst->edges(),

View File

@ -24,6 +24,7 @@
/* Allow using deprecated functionality for .blend file I/O. */
#define DNA_DEPRECATED_ALLOW
#include "BKE_attribute.hh"
#include "DNA_ID.h"
#include "DNA_anim_types.h"
#include "DNA_key_types.h"
@ -2224,6 +2225,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
float (*r_face_normals)[3],
float (*r_loop_normals)[3])
{
using namespace blender;
if (r_vert_normals == nullptr && r_face_normals == nullptr && r_loop_normals == nullptr) {
return;
}
@ -2274,10 +2276,9 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (loop_normals_needed) {
const blender::short2 *clnors = static_cast<const blender::short2 *>(
CustomData_get_layer(&mesh->loop_data, CD_CUSTOMLOOPNORMAL));
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edge_data, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
blender::bke::mesh::normals_calc_loop(
positions,
edges,

View File

@ -1069,8 +1069,7 @@ void BKE_mesh_sharp_edges_set_from_angle(Mesh *mesh, const float angle)
}
bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
const VArraySpan<bool> sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
bke::mesh::edges_sharp_from_angle_set(mesh->faces(),
mesh->corner_verts(),
mesh->corner_edges(),

View File

@ -663,14 +663,14 @@ static void face_edge_loop_islands_calc(const int totedge,
int *BKE_mesh_calc_smoothgroups(int edges_num,
const blender::OffsetIndices<int> faces,
const blender::Span<int> corner_edges,
const bool *sharp_edges,
const bool *sharp_faces,
const blender::Span<bool> sharp_edges,
const blender::Span<bool> sharp_faces,
int *r_totgroup,
bool use_bitflags)
{
int *face_groups = nullptr;
auto face_is_smooth = [&](const int i) { return !(sharp_faces && sharp_faces[i]); };
auto face_is_smooth = [&](const int i) { return sharp_faces.is_empty() || !sharp_faces[i]; };
auto face_is_island_boundary_smooth = [&](const int face_index,
const int /*loop_index*/,
@ -679,7 +679,7 @@ int *BKE_mesh_calc_smoothgroups(int edges_num,
const blender::Span<int> edge_face_map_elem) {
/* Edge is sharp if one of its faces is flat, or edge itself is sharp,
* or edge is not used by exactly two faces. */
if (face_is_smooth(face_index) && !(sharp_edges && sharp_edges[edge_index]) &&
if (face_is_smooth(face_index) && !(!sharp_edges.is_empty() && sharp_edges[edge_index]) &&
(edge_user_count == 2))
{
/* In that case, edge appears to be smooth, but we need to check its other face too. */

View File

@ -124,6 +124,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
int **r_vert_merge_map,
int *r_vert_merge_map_len)
{
using namespace blender;
const float tolerance_sq = mmd->tolerance * mmd->tolerance;
const bool do_vtargetmap = (mmd->flag & MOD_MIR_NO_MERGE) == 0 && r_vert_merge_map != nullptr;
@ -405,11 +406,9 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
transpose_m4(mtx_nor);
/* calculate custom normals into loop_normals, then mirror first half into second half */
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&result->edge_data, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&result->face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
blender::bke::mesh::normals_calc_loop(result->vert_positions(),
result_edges,
result_faces,

View File

@ -291,10 +291,9 @@ blender::Span<blender::float3> Mesh::corner_normals() const
break;
}
case MeshNormalDomain::Corner: {
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&this->edge_data, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&this->face_data, CD_PROP_BOOL, "sharp_face"));
const AttributeAccessor attributes = this->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
const short2 *custom_normals = static_cast<const short2 *>(
CustomData_get_layer(&this->loop_data, CD_CUSTOMLOOPNORMAL));
mesh::normals_calc_loop(this->vert_positions(),
@ -781,7 +780,7 @@ void edges_sharp_from_angle_set(const OffsetIndices<int> faces,
const Span<int> corner_edges,
const Span<float3> face_normals,
const Span<int> loop_to_face,
const bool *sharp_faces,
const Span<bool> sharp_faces,
const float split_angle,
MutableSpan<bool> sharp_edges)
{
@ -798,7 +797,7 @@ void edges_sharp_from_angle_set(const OffsetIndices<int> faces,
corner_edges,
loop_to_face,
face_normals,
Span<bool>(sharp_faces, sharp_faces ? faces.size() : 0),
sharp_faces,
sharp_edges,
true,
split_angle,
@ -1190,8 +1189,8 @@ void normals_calc_loop(const Span<float3> vert_positions,
const Span<int> loop_to_face_map,
const Span<float3> vert_normals,
const Span<float3> face_normals,
const bool *sharp_edges,
const bool *sharp_faces,
const Span<bool> sharp_edges,
const Span<bool> sharp_faces,
const short2 *clnors_data,
CornerNormalSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals)
@ -1244,12 +1243,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
/* This first loop check which edges are actually smooth, and compute edge vectors. */
build_edge_to_loop_map_with_flip_and_sharp(
faces,
corner_verts,
corner_edges,
Span<bool>(sharp_faces, sharp_faces ? faces.size() : 0),
Span<bool>(sharp_edges, sharp_edges ? edges.size() : 0),
edge_to_loops);
faces, corner_verts, corner_edges, sharp_faces, sharp_edges, edge_to_loops);
Vector<int> single_corners;
Vector<int> fan_corners;
@ -1301,7 +1295,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
Span<int> corner_edges,
Span<float3> vert_normals,
Span<float3> face_normals,
const bool *sharp_faces,
const Span<bool> sharp_faces,
const bool use_vertices,
MutableSpan<float3> r_custom_loop_normals,
MutableSpan<bool> sharp_edges,
@ -1327,7 +1321,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
loop_to_face,
vert_normals,
face_normals,
sharp_edges.data(),
sharp_edges,
sharp_faces,
r_clnors_data.data(),
&lnors_spacearr,
@ -1448,7 +1442,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
loop_to_face,
vert_normals,
face_normals,
sharp_edges.data(),
sharp_edges,
sharp_faces,
r_clnors_data.data(),
&lnors_spacearr,
@ -1506,7 +1500,7 @@ void normals_loop_custom_set(const Span<float3> vert_positions,
const Span<int> corner_edges,
const Span<float3> vert_normals,
const Span<float3> face_normals,
const bool *sharp_faces,
const Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
MutableSpan<short2> r_clnors_data)
@ -1532,7 +1526,7 @@ void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
const Span<int> corner_edges,
const Span<float3> vert_normals,
const Span<float3> face_normals,
const bool *sharp_faces,
const Span<bool> sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
MutableSpan<short2> r_clnors_data)
@ -1565,8 +1559,7 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
MutableAttributeAccessor attributes = mesh->attributes_for_write();
SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
mesh_normals_loop_custom_set(
mesh->vert_positions(),

View File

@ -237,7 +237,7 @@ struct SGLSLMeshToTangent {
if (precomputedLoopNormals) {
return mikk::float3(precomputedLoopNormals[loop_index]);
}
if (sharp_faces && sharp_faces[face_index]) { /* flat */
if (!sharp_faces.is_empty() && sharp_faces[face_index]) { /* flat */
if (precomputedFaceNormals) {
return mikk::float3(precomputedFaceNormals[face_index]);
}
@ -284,7 +284,7 @@ struct SGLSLMeshToTangent {
const float (*vert_normals)[3];
const float (*orco)[3];
float (*tangent)[4]; /* destination */
const bool *sharp_faces;
blender::Span<bool> sharp_faces;
int numTessFaces;
#ifdef USE_LOOPTRI_DETECT_QUADS
@ -397,7 +397,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const MLoopTri *looptri,
const int *looptri_faces,
const uint looptri_len,
const bool *sharp_faces,
const blender::Span<bool> sharp_faces,
CustomData *loopdata,
bool calc_active_tangent,
@ -581,7 +581,11 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
int tangent_names_len)
{
/* TODO(@ideasman42): store in Mesh.runtime to avoid recalculation. */
using namespace blender;
using namespace blender::bke;
const blender::Span<MLoopTri> looptris = me_eval->looptris();
const bke::AttributeAccessor attributes = me_eval->attributes();
const VArraySpan sharp_face = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(
reinterpret_cast<const float(*)[3]>(me_eval->vert_positions().data()),
@ -590,8 +594,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
looptris.data(),
me_eval->looptri_faces().data(),
uint(looptris.size()),
static_cast<const bool *>(
CustomData_get_layer_named(&me_eval->face_data, CD_PROP_BOOL, "sharp_face")),
sharp_face,
&me_eval->loop_data,
calc_active_tangent,
tangent_names,

View File

@ -149,17 +149,17 @@ static void update_node_vb(PBVH *pbvh, PBVHNode *node)
}
}
static bool face_materials_match(const int *material_indices,
const bool *sharp_faces,
static bool face_materials_match(const Span<int> material_indices,
const Span<bool> sharp_faces,
const int a,
const int b)
{
if (material_indices) {
if (!material_indices.is_empty()) {
if (material_indices[a] != material_indices[b]) {
return false;
}
}
if (sharp_faces) {
if (!sharp_faces.is_empty()) {
if (sharp_faces[a] != sharp_faces[b]) {
return false;
}
@ -204,8 +204,8 @@ static int partition_prim_indices(blender::MutableSpan<int> prim_indices,
/* Returns the index of the first element on the right of the partition */
static int partition_indices_material_faces(MutableSpan<int> indices,
const Span<int> prim_to_face_map,
const int *material_indices,
const bool *sharp_faces,
const Span<int> material_indices,
const Span<bool> sharp_faces,
const int lo,
const int hi)
{
@ -264,7 +264,7 @@ static int map_insert_vert(blender::Map<int, int> &map,
static void build_mesh_leaf_node(const Span<int> corner_verts,
const Span<MLoopTri> looptris,
const Span<int> looptri_faces,
const bool *hide_poly,
const Span<bool> hide_poly,
MutableSpan<bool> vert_bitmap,
PBVHNode *node)
{
@ -305,11 +305,11 @@ static void build_mesh_leaf_node(const Span<int> corner_verts,
}
}
const bool fully_hidden = hide_poly && std::all_of(prim_indices.begin(),
prim_indices.end(),
[&](const int tri) {
return hide_poly[looptri_faces[tri]];
});
const bool fully_hidden = !hide_poly.is_empty() &&
std::all_of(
prim_indices.begin(), prim_indices.end(), [&](const int tri) {
return hide_poly[looptri_faces[tri]];
});
BKE_pbvh_node_fully_hidden_set(node, fully_hidden);
BKE_pbvh_node_mark_rebuild_draw(node);
}
@ -378,7 +378,7 @@ static void build_leaf(PBVH *pbvh,
const Span<int> corner_verts,
const Span<MLoopTri> looptris,
const Span<int> looptri_faces,
const bool *hide_poly,
const Span<bool> hide_poly,
int node_index,
const Span<Bounds<float3>> prim_bounds,
int offset,
@ -405,8 +405,8 @@ static void build_leaf(PBVH *pbvh,
* same material (including flat/smooth shading), non-zero otherwise */
static bool leaf_needs_material_split(PBVH *pbvh,
const Span<int> prim_to_face_map,
const int *material_indices,
const bool *sharp_faces,
const Span<int> material_indices,
const Span<bool> sharp_faces,
int offset,
int count)
{
@ -488,9 +488,9 @@ static void build_sub(PBVH *pbvh,
const Span<int> corner_verts,
const Span<MLoopTri> looptris,
const Span<int> looptri_faces,
const bool *hide_poly,
const int *material_indices,
const bool *sharp_faces,
const Span<bool> hide_poly,
const Span<int> material_indices,
const Span<bool> sharp_faces,
int node_index,
const Bounds<float3> *cb,
const Span<Bounds<float3>> prim_bounds,
@ -613,9 +613,9 @@ static void pbvh_build(PBVH *pbvh,
const Span<int> corner_verts,
const Span<MLoopTri> looptris,
const Span<int> looptri_faces,
const bool *hide_poly,
const int *material_indices,
const bool *sharp_faces,
const Span<bool> hide_poly,
const Span<int> material_indices,
const Span<bool> sharp_faces,
const Bounds<float3> *cb,
const Span<Bounds<float3>> prim_bounds,
int totprim)
@ -731,6 +731,7 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh)
void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
const int totvert = mesh->totvert;
const int looptri_num = poly_to_tri_count(mesh->faces_num, mesh->totloop);
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
@ -784,19 +785,17 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh)
[](const Bounds<float3> &a, const Bounds<float3> &b) { return bounds::merge(a, b); });
if (looptri_num) {
const bool *hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, ".hide_poly"));
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_INT32, "material_index"));
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, "sharp_face");
const AttributeAccessor attributes = mesh->attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
const VArraySpan material_index = *attributes.lookup<int>("material_index", ATTR_DOMAIN_FACE);
const VArraySpan sharp_face = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
pbvh_build(pbvh,
corner_verts,
looptris,
looptri_faces,
hide_poly,
material_indices,
sharp_faces,
material_index,
sharp_face,
&cb,
prim_bounds,
looptri_num);
@ -819,6 +818,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh)
void BKE_pbvh_build_grids(PBVH *pbvh, const CCGKey *key, Mesh *mesh, SubdivCCG *subdiv_ccg)
{
using namespace blender;
using namespace blender::bke;
const int gridsize = key->grid_size;
const Span<CCGElem *> grids = subdiv_ccg->grids;
@ -866,12 +866,10 @@ void BKE_pbvh_build_grids(PBVH *pbvh, const CCGKey *key, Mesh *mesh, SubdivCCG *
[](const Bounds<float3> &a, const Bounds<float3> &b) { return bounds::merge(a, b); });
if (!grids.is_empty()) {
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_INT32, "material_index"));
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, "sharp_face");
pbvh_build(
pbvh, {}, {}, {}, nullptr, material_indices, sharp_faces, &cb, prim_bounds, grids.size());
const AttributeAccessor attributes = mesh->attributes();
const VArraySpan material_index = *attributes.lookup<int>("material_index", ATTR_DOMAIN_FACE);
const VArraySpan sharp_face = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
pbvh_build(pbvh, {}, {}, {}, {}, material_index, sharp_face, &cb, prim_bounds, grids.size());
#ifdef TEST_PBVH_FACE_SPLIT
test_face_boundaries(pbvh);
@ -2060,7 +2058,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const PBVHNode *node,
float (*origco)[3],
const Span<int> corner_verts,
const bool *hide_poly,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@ -2078,7 +2076,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (hide_poly && hide_poly[pbvh->looptri_faces[looptri_i]]) {
if (!hide_poly.is_empty() && hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2221,7 +2219,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const bool *hide_poly,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@ -2415,7 +2413,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const PBVHNode *node,
float (*origco)[3],
const Span<int> corner_verts,
const bool *hide_poly,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@ -2429,7 +2427,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (hide_poly && hide_poly[pbvh->looptri_faces[looptri_i]]) {
if (!hide_poly.is_empty() && hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2523,7 +2521,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const bool *hide_poly,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@ -2659,8 +2657,7 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
args.face_normals = pbvh.face_normals;
/* Retrieve data from the original mesh. Ideally that would be passed to this function to
* make it clearer when each is used. */
args.hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&pbvh.mesh->face_data, CD_PROP_BOOL, ".hide_poly"));
args.hide_poly = *pbvh.mesh->attributes().lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
args.prim_indices = node.prim_indices;
args.looptri_faces = mesh.looptri_faces();

View File

@ -212,6 +212,7 @@ static void mesh_attributes_copy_to_bmesh_block(CustomData &data,
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
{
using namespace blender;
if (!mesh) {
/* Sanity check. */
return;
@ -410,26 +411,17 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) :
-1;
const bool *select_vert = (const bool *)CustomData_get_layer_named(
&mesh->vert_data, CD_PROP_BOOL, ".select_vert");
const bool *select_edge = (const bool *)CustomData_get_layer_named(
&mesh->edge_data, CD_PROP_BOOL, ".select_edge");
const bool *select_poly = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, ".select_poly");
const bool *hide_vert = (const bool *)CustomData_get_layer_named(
&mesh->vert_data, CD_PROP_BOOL, ".hide_vert");
const bool *hide_edge = (const bool *)CustomData_get_layer_named(
&mesh->edge_data, CD_PROP_BOOL, ".hide_edge");
const bool *hide_poly = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, ".hide_poly");
const int *material_indices = (const int *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_INT32, "material_index");
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, "sharp_face");
const bool *sharp_edges = (const bool *)CustomData_get_layer_named(
&mesh->edge_data, CD_PROP_BOOL, "sharp_edge");
const bool *uv_seams = (const bool *)CustomData_get_layer_named(
&mesh->edge_data, CD_PROP_BOOL, ".uv_seam");
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan select_vert = *attributes.lookup<bool>(".select_vert", ATTR_DOMAIN_POINT);
const VArraySpan select_edge = *attributes.lookup<bool>(".select_edge", ATTR_DOMAIN_EDGE);
const VArraySpan select_poly = *attributes.lookup<bool>(".select_poly", ATTR_DOMAIN_FACE);
const VArraySpan hide_vert = *attributes.lookup<bool>(".hide_vert", ATTR_DOMAIN_POINT);
const VArraySpan hide_edge = *attributes.lookup<bool>(".hide_edge", ATTR_DOMAIN_EDGE);
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
const VArraySpan material_indices = *attributes.lookup<int>("material_index", ATTR_DOMAIN_FACE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan uv_seams = *attributes.lookup<bool>(".uv_seam", ATTR_DOMAIN_EDGE);
const Span<float3> positions = mesh->vert_positions();
Array<BMVert *> vtable(mesh->totvert);
@ -438,10 +430,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
bm, keyco ? keyco[i] : positions[i], nullptr, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
if (hide_vert && hide_vert[i]) {
if (!hide_vert.is_empty() && hide_vert[i]) {
BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
}
if (select_vert && select_vert[i]) {
if (!select_vert.is_empty() && select_vert[i]) {
BM_vert_select_set(bm, v, true);
}
@ -476,16 +468,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
BM_elem_index_set(e, i); /* set_ok */
e->head.hflag = 0;
if (uv_seams && uv_seams[i]) {
if (!uv_seams.is_empty() && uv_seams[i]) {
BM_elem_flag_enable(e, BM_ELEM_SEAM);
}
if (hide_edge && hide_edge[i]) {
if (!hide_edge.is_empty() && hide_edge[i]) {
BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
}
if (select_edge && select_edge[i]) {
if (!select_edge.is_empty() && select_edge[i]) {
BM_edge_select_set(bm, e, true);
}
if (!(sharp_edges && sharp_edges[i])) {
if (!(!sharp_edges.is_empty() && sharp_edges[i])) {
BM_elem_flag_enable(e, BM_ELEM_SMOOTH);
}
@ -529,17 +521,17 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
/* Transfer flag. */
if (!(sharp_faces && sharp_faces[i])) {
if (!(!sharp_faces.is_empty() && sharp_faces[i])) {
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
}
if (hide_poly && hide_poly[i]) {
if (!hide_poly.is_empty() && hide_poly[i]) {
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
}
if (select_poly && select_poly[i]) {
if (!select_poly.is_empty() && select_poly[i]) {
BM_face_select_set(bm, f, true);
}
f->mat_nr = material_indices == nullptr ? 0 : material_indices[i];
f->mat_nr = material_indices.is_empty() ? 0 : material_indices[i];
if (i == mesh->act_face) {
bm->act_face = f;
}

View File

@ -80,7 +80,7 @@ struct PBVH_GPU_Args {
Span<int> prim_indices;
const bool *hide_poly;
VArraySpan<bool> hide_poly;
Span<MLoopTri> mlooptri;
Span<int> looptri_faces;

View File

@ -191,9 +191,9 @@ static void accumululate_material_counts_mesh(
const MeshRenderData &mr, threading::EnumerableThreadSpecific<Array<int>> &all_tri_counts)
{
const OffsetIndices faces = mr.faces;
if (!mr.material_indices) {
if (mr.use_hide && mr.hide_poly) {
const Span hide_poly(mr.hide_poly, mr.face_len);
if (mr.material_indices.is_empty()) {
if (mr.use_hide && !mr.hide_poly.is_empty()) {
const Span hide_poly = mr.hide_poly;
all_tri_counts.local().first() = threading::parallel_reduce(
faces.index_range(),
4096,
@ -214,11 +214,11 @@ static void accumululate_material_counts_mesh(
return;
}
const Span material_indices(mr.material_indices, mr.face_len);
const Span material_indices = mr.material_indices;
threading::parallel_for(material_indices.index_range(), 1024, [&](const IndexRange range) {
Array<int> &tri_counts = all_tri_counts.local();
const int last_index = tri_counts.size() - 1;
if (mr.use_hide && mr.hide_poly) {
if (mr.use_hide && !mr.hide_poly.is_empty()) {
for (const int i : range) {
if (!mr.hide_poly[i]) {
const int mat = std::clamp(material_indices[i], 0, last_index);
@ -297,8 +297,10 @@ static void mesh_render_data_faces_sorted_build(MeshRenderData &mr, MeshBufferCa
}
else {
for (int i = 0; i < mr.face_len; i++) {
if (!(mr.use_hide && mr.hide_poly && mr.hide_poly[i])) {
const int mat = mr.material_indices ? clamp_i(mr.material_indices[i], 0, mat_last) : 0;
if (!(mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[i])) {
const int mat = mr.material_indices.is_empty() ?
0 :
clamp_i(mr.material_indices[i], 0, mat_last);
tri_first_index[i] = mat_tri_offs[mat];
mat_tri_offs[mat] += mr.faces[i].size() - 2;
}
@ -476,6 +478,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
const bool do_uvedit,
const ToolSettings *ts)
{
using namespace blender;
MeshRenderData *mr = MEM_new<MeshRenderData>(__func__);
mr->toolsettings = ts;
mr->mat_len = mesh_render_mat_len_get(object, mesh);
@ -599,25 +602,19 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->p_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->mesh->face_data, CD_ORIGINDEX));
mr->material_indices = static_cast<const int *>(
CustomData_get_layer_named(&mr->mesh->face_data, CD_PROP_INT32, "material_index"));
const bke::AttributeAccessor attributes = mr->mesh->attributes();
mr->hide_vert = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->vert_data, CD_PROP_BOOL, ".hide_vert"));
mr->hide_edge = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->edge_data, CD_PROP_BOOL, ".hide_edge"));
mr->hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->face_data, CD_PROP_BOOL, ".hide_poly"));
mr->material_indices = *attributes.lookup<int>("material_index", ATTR_DOMAIN_FACE);
mr->select_vert = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->vert_data, CD_PROP_BOOL, ".select_vert"));
mr->select_edge = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->edge_data, CD_PROP_BOOL, ".select_edge"));
mr->select_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->face_data, CD_PROP_BOOL, ".select_poly"));
mr->hide_vert = *attributes.lookup<bool>(".hide_vert", ATTR_DOMAIN_POINT);
mr->hide_edge = *attributes.lookup<bool>(".hide_edge", ATTR_DOMAIN_EDGE);
mr->hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
mr->sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mr->mesh->face_data, CD_PROP_BOOL, "sharp_face"));
mr->select_vert = *attributes.lookup<bool>(".select_vert", ATTR_DOMAIN_POINT);
mr->select_edge = *attributes.lookup<bool>(".select_edge", ATTR_DOMAIN_EDGE);
mr->select_poly = *attributes.lookup<bool>(".select_poly", ATTR_DOMAIN_FACE);
mr->sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
}
else {
/* #BMesh */

View File

@ -757,14 +757,14 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &
for (const int i : faces.index_range()) {
uint32_t flag = 0;
if (!(mr.normals_domain == blender::bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[i])))
(!mr.sharp_faces.is_empty() && mr.sharp_faces[i])))
{
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
if (mr.select_poly && mr.select_poly[i]) {
if (!mr.select_poly.is_empty() && mr.select_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
if (mr.hide_poly && mr.hide_poly[i]) {
if (!mr.hide_poly.is_empty() && mr.hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
flags_data[i] = uint(faces[i].start()) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
@ -788,7 +788,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
uint32_t flag = (f) ? compute_coarse_face_flag_bm(f, mr.efa_act) : 0;
/* Smooth from mesh. */
if (!(mr.normals_domain == blender::bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[i])))
(!mr.sharp_faces.is_empty() && mr.sharp_faces[i])))
{
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}

View File

@ -129,11 +129,11 @@ void extract_data_vert_faces(const PBVH_GPU_Args &args, const Span<T> attribute,
const Span<int> corner_verts = args.corner_verts;
const Span<MLoopTri> looptris = args.mlooptri;
const Span<int> looptri_faces = args.looptri_faces;
const bool *hide_poly = args.hide_poly;
const Span<bool> hide_poly = args.hide_poly;
VBOType *data = static_cast<VBOType *>(GPU_vertbuf_get_data(&vbo));
for (const int looptri_i : args.prim_indices) {
if (hide_poly && hide_poly[looptri_faces[looptri_i]]) {
if (!hide_poly.is_empty() && hide_poly[looptri_faces[looptri_i]]) {
continue;
}
for (int i : IndexRange(3)) {
@ -151,12 +151,12 @@ void extract_data_face_faces(const PBVH_GPU_Args &args, const Span<T> attribute,
using VBOType = typename Converter::VBOType;
const Span<int> looptri_faces = args.looptri_faces;
const bool *hide_poly = args.hide_poly;
const Span<bool> hide_poly = args.hide_poly;
VBOType *data = static_cast<VBOType *>(GPU_vertbuf_get_data(&vbo));
for (const int looptri_i : args.prim_indices) {
const int face = looptri_faces[looptri_i];
if (hide_poly && hide_poly[face]) {
if (!hide_poly.is_empty() && hide_poly[face]) {
continue;
}
std::fill_n(data, 3, Converter::convert(attribute[face]));
@ -172,11 +172,11 @@ void extract_data_corner_faces(const PBVH_GPU_Args &args, const Span<T> attribut
const Span<MLoopTri> looptris = args.mlooptri;
const Span<int> looptri_faces = args.looptri_faces;
const bool *hide_poly = args.hide_poly;
const Span<bool> hide_poly = args.hide_poly;
VBOType *data = static_cast<VBOType *>(GPU_vertbuf_get_data(&vbo));
for (const int looptri_i : args.prim_indices) {
if (hide_poly && hide_poly[looptri_faces[looptri_i]]) {
if (!hide_poly.is_empty() && hide_poly[looptri_faces[looptri_i]]) {
continue;
}
for (int i : IndexRange(3)) {
@ -338,7 +338,7 @@ struct PBVHBatches {
switch (args.pbvh_type) {
case PBVH_FACES: {
if (args.hide_poly) {
if (!args.hide_poly.is_empty()) {
for (const int looptri_i : args.prim_indices) {
if (!args.hide_poly[args.looptri_faces[looptri_i]]) {
count++;
@ -438,18 +438,19 @@ struct PBVHBatches {
void fill_vbo_normal_faces(const PBVH_GPU_Args &args, GPUVertBuf &vert_buf)
{
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(args.face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = args.mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
short4 *data = static_cast<short4 *>(GPU_vertbuf_get_data(&vert_buf));
short4 face_no;
int last_face = -1;
for (const int looptri_i : args.prim_indices) {
const int face_i = args.looptri_faces[looptri_i];
if (args.hide_poly && args.hide_poly[face_i]) {
if (!args.hide_poly.is_empty() && args.hide_poly[face_i]) {
continue;
}
if (sharp_faces && sharp_faces[face_i]) {
if (!sharp_faces.is_empty() && sharp_faces[face_i]) {
if (face_i != last_face) {
face_no = normal_float_to_short(args.face_normals[face_i]);
last_face = face_i;
@ -499,12 +500,14 @@ struct PBVHBatches {
}
case CustomRequest::Normal: {
const Span<int> grid_to_face_map = args.subdiv_ccg->grid_to_face_map;
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(args.face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = args.mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) {
float3 no(0.0f, 0.0f, 0.0f);
const bool smooth = !(sharp_faces && sharp_faces[grid_to_face_map[grid_index]]);
const bool smooth = !(!sharp_faces.is_empty() &&
sharp_faces[grid_to_face_map[grid_index]]);
if (smooth) {
no = CCG_elem_no(&args.ccg_key, elems[0]);
@ -684,10 +687,10 @@ struct PBVHBatches {
const Span<int> corner_verts = args.corner_verts;
const Span<MLoopTri> looptris = args.mlooptri;
const Span<int> looptri_faces = args.looptri_faces;
const bool *hide_poly = args.hide_poly;
const Span<bool> hide_poly = args.hide_poly;
for (const int looptri_i : args.prim_indices) {
if (hide_poly && hide_poly[looptri_faces[looptri_i]]) {
if (!hide_poly.is_empty() && hide_poly[looptri_faces[looptri_i]]) {
continue;
}
for (int i : IndexRange(3)) {
@ -711,7 +714,7 @@ struct PBVHBatches {
uchar4 fset_color(UCHAR_MAX);
for (const int looptri_i : args.prim_indices) {
if (args.hide_poly && args.hide_poly[args.looptri_faces[looptri_i]]) {
if (!args.hide_poly.is_empty() && args.hide_poly[args.looptri_faces[looptri_i]]) {
continue;
}
const int face_i = args.looptri_faces[looptri_i];
@ -1026,14 +1029,10 @@ struct PBVHBatches {
void create_index_faces(const PBVH_GPU_Args &args)
{
const int *mat_index = static_cast<const int *>(
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, "material_index"));
if (mat_index && !args.prim_indices.is_empty()) {
const int looptri_i = args.prim_indices[0];
const int face_i = args.looptri_faces[looptri_i];
material_index = mat_index[face_i];
}
const bke::AttributeAccessor attributes = args.mesh->attributes();
const VArray material_indices = *attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
material_index = material_indices[args.looptri_faces[args.prim_indices.first()]];
const Span<int2> edges = args.mesh->edges();
@ -1041,7 +1040,7 @@ struct PBVHBatches {
int edge_count = 0;
for (const int looptri_i : args.prim_indices) {
const int face_i = args.looptri_faces[looptri_i];
if (args.hide_poly && args.hide_poly[face_i]) {
if (!args.hide_poly.is_empty() && args.hide_poly[face_i]) {
continue;
}
@ -1065,7 +1064,7 @@ struct PBVHBatches {
int vertex_i = 0;
for (const int looptri_i : args.prim_indices) {
const int face_i = args.looptri_faces[looptri_i];
if (args.hide_poly && args.hide_poly[face_i]) {
if (!args.hide_poly.is_empty() && args.hide_poly[face_i]) {
continue;
}
@ -1114,18 +1113,15 @@ struct PBVHBatches {
void create_index_grids(const PBVH_GPU_Args &args, bool do_coarse)
{
const bke::AttributeAccessor attributes = args.mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
const VArray material_indices = *attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
const BitGroupVector<> &grid_hidden = args.subdiv_ccg->grid_hidden;
const Span<int> grid_to_face_map = args.subdiv_ccg->grid_to_face_map;
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(args.face_data, CD_PROP_BOOL, "sharp_face"));
const int *mat_index = static_cast<const int *>(
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, "material_index"));
if (mat_index && !args.grid_indices.is_empty()) {
int face_i = BKE_subdiv_ccg_grid_to_face_index(*args.subdiv_ccg, args.grid_indices[0]);
material_index = mat_index[face_i];
}
material_index = material_indices[BKE_subdiv_ccg_grid_to_face_index(
*args.subdiv_ccg, args.grid_indices.first())];
needs_tri_index = true;
int gridsize = args.ccg_key.grid_size;
@ -1141,7 +1137,7 @@ struct PBVHBatches {
}
for (const int grid_index : args.grid_indices) {
bool smooth = !(sharp_faces && sharp_faces[grid_to_face_map[grid_index]]);
bool smooth = !(!sharp_faces.is_empty() && sharp_faces[grid_to_face_map[grid_index]]);
if (!grid_hidden.is_empty()) {
const BoundedBitSpan gh = grid_hidden[grid_index];
for (int y = 0; y < gridsize - 1; y += skip) {

View File

@ -11,6 +11,7 @@
#pragma once
#include "BLI_math_vector_types.hh"
#include "BLI_virtual_array.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@ -89,20 +90,20 @@ struct MeshRenderData {
/* The triangulation of #Mesh faces, owned by the mesh. */
blender::Span<MLoopTri> looptris;
blender::Span<int> looptri_faces;
const int *material_indices;
blender::VArraySpan<int> material_indices;
blender::bke::MeshNormalDomain normals_domain;
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> face_normals;
blender::Span<blender::float3> loop_normals;
const bool *hide_vert;
const bool *hide_edge;
const bool *hide_poly;
const bool *select_vert;
const bool *select_edge;
const bool *select_poly;
const bool *sharp_faces;
blender::VArraySpan<bool> hide_vert;
blender::VArraySpan<bool> hide_edge;
blender::VArraySpan<bool> hide_poly;
blender::VArraySpan<bool> select_vert;
blender::VArraySpan<bool> select_edge;
blender::VArraySpan<bool> select_poly;
blender::VArraySpan<bool> sharp_faces;
blender::Span<int> loose_verts;
blender::Span<int> loose_edges;

View File

@ -217,8 +217,8 @@ static void extract_edituv_lines_iter_face_mesh(const MeshRenderData &mr,
mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
}
else {
mp_hidden = (mr.hide_poly) ? mr.hide_poly[face_index] : false;
mp_select = mr.select_poly && mr.select_poly[face_index];
mp_hidden = mr.hide_poly.is_empty() ? false : mr.hide_poly[face_index];
mp_select = !mr.select_poly.is_empty() && mr.select_poly[face_index];
}
for (const int ml_index : face) {
@ -295,8 +295,8 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache &subdiv_c
mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
}
else {
mp_hidden = (mr.hide_poly) ? mr.hide_poly[coarse_face_index] : false;
mp_select = mr.select_poly && mr.select_poly[coarse_face_index];
mp_hidden = mr.hide_poly.is_empty() ? false : mr.hide_poly[coarse_face_index];
mp_select = !mr.select_poly.is_empty() && mr.select_poly[coarse_face_index];
}
uint start_loop_idx = subdiv_quad_index * 4;

View File

@ -42,7 +42,7 @@ static void extract_fdots_iter_face_mesh(const MeshRenderData &mr,
const int face_index,
void *_userdata)
{
const bool hidden = mr.use_hide && mr.hide_poly && mr.hide_poly[face_index];
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
if (mr.use_subsurf_fdots) {

View File

@ -22,13 +22,13 @@ struct MeshExtract_LinesData {
GPUIndexBufBuilder elb;
BitSpan optimal_display_edges;
const int *e_origindex;
const bool *hide_edge;
Span<bool> hide_edge;
bool test_visibility;
};
BLI_INLINE bool is_edge_visible(const MeshExtract_LinesData *data, const int edge)
{
if (data->hide_edge && data->hide_edge[edge]) {
if (!data->hide_edge.is_empty() && data->hide_edge[edge]) {
return false;
}
if (data->e_origindex && data->e_origindex[edge] == ORIGINDEX_NONE) {
@ -55,10 +55,10 @@ static void extract_lines_init(const MeshRenderData &mr,
if (mr.extract_type == MR_EXTRACT_MESH) {
data->optimal_display_edges = mr.mesh->runtime->subsurf_optimal_display_edges;
data->e_origindex = mr.hide_unmapped_edges ? mr.e_origindex : nullptr;
data->hide_edge = mr.use_hide ? mr.hide_edge : nullptr;
data->hide_edge = mr.use_hide ? Span(mr.hide_edge) : Span<bool>();
data->test_visibility = !data->optimal_display_edges.is_empty() || data->e_origindex ||
data->hide_edge;
!data->hide_edge.is_empty();
}
}
@ -221,8 +221,8 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
case MR_EXTRACT_MESH: {
const int *e_origindex = (mr.hide_unmapped_edges) ? mr.e_origindex : nullptr;
if (e_origindex == nullptr) {
const bool *hide_edge = mr.hide_edge;
if (hide_edge) {
const Span<bool> hide_edge = mr.hide_edge;
if (!hide_edge.is_empty()) {
for (DRWSubdivLooseEdge edge : loose_edges) {
*flags_data++ = hide_edge[edge.coarse_edge_index];
}
@ -239,8 +239,8 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache &subdiv_cache,
}
}
else {
const bool *hide_edge = mr.hide_edge;
if (hide_edge) {
const Span<bool> hide_edge = mr.hide_edge;
if (!hide_edge.is_empty()) {
for (DRWSubdivLooseEdge edge : loose_edges) {
int e = edge.coarse_edge_index;

View File

@ -130,7 +130,7 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData &mr,
{
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
const int face_i = mr.looptri_faces[elt_index];
const bool hidden = mr.use_hide && mr.hide_poly && mr.hide_poly[face_i];
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_i];
if (hidden) {
return;
}

View File

@ -47,13 +47,13 @@ static void extract_lines_paint_mask_iter_face_mesh(const MeshRenderData &mr,
for (int ml_index = face.start(); ml_index < ml_index_end; ml_index += 1) {
const int e_index = mr.corner_edges[ml_index];
if (!((mr.use_hide && mr.hide_edge && mr.hide_edge[e_index]) ||
if (!((mr.use_hide && !mr.hide_edge.is_empty() && mr.hide_edge[e_index]) ||
((mr.e_origindex) && (mr.e_origindex[e_index] == ORIGINDEX_NONE))))
{
const int ml_index_last = face.size() + face.start() - 1;
const int ml_index_other = (ml_index == ml_index_last) ? face.start() : (ml_index + 1);
if (mr.select_poly && mr.select_poly[face_index]) {
if (!mr.select_poly.is_empty() && mr.select_poly[face_index]) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, e_index)) {
/* Hide edge as it has more than 2 selected loop. */
GPU_indexbuf_set_line_restart(&data->elb, e_index);
@ -121,12 +121,12 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache &subd
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
}
else {
if (!((mr.use_hide && mr.hide_edge && mr.hide_edge[coarse_edge_index]) ||
if (!((mr.use_hide && !mr.hide_edge.is_empty() && mr.hide_edge[coarse_edge_index]) ||
((mr.e_origindex) && (mr.e_origindex[coarse_edge_index] == ORIGINDEX_NONE))))
{
const uint ml_index_other = (loop_idx == (end_loop_idx - 1)) ? start_loop_idx :
loop_idx + 1;
if (mr.select_poly && mr.select_poly[coarse_quad_index]) {
if (!mr.select_poly.is_empty() && mr.select_poly[coarse_quad_index]) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, coarse_edge_index)) {
/* Hide edge as it has more than 2 selected loop. */
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);

View File

@ -44,7 +44,7 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
const int v_index,
const int l_index)
{
const bool hidden = mr.use_hide && mr.hide_vert && mr.hide_vert[v_index];
const bool hidden = mr.use_hide && !mr.hide_vert.is_empty() && mr.hide_vert[v_index];
if (!(hidden || ((mr.v_origindex) && (mr.v_origindex[v_index] == ORIGINDEX_NONE)))) {
GPU_indexbuf_set_point_vert(elb, v_index, l_index);
@ -176,7 +176,7 @@ static void extract_points_iter_subdiv_common(GPUIndexBufBuilder *elb,
}
}
else {
if (mr.use_hide && mr.hide_vert && mr.hide_vert[coarse_vertex_index]) {
if (mr.use_hide && !mr.hide_vert.is_empty() && mr.hide_vert[coarse_vertex_index]) {
GPU_indexbuf_set_point_restart(elb, coarse_vertex_index);
continue;
}

View File

@ -192,7 +192,7 @@ static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData &mr,
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
const int face_i = mr.looptri_faces[mlt_index];
const bool hidden = mr.use_hide && mr.hide_poly && mr.hide_poly[face_i];
const bool hidden = mr.use_hide && !mr.hide_poly.is_empty() && mr.hide_poly[face_i];
if (hidden) {
GPU_indexbuf_set_tri_restart(elb, mlt_index);
}

View File

@ -60,7 +60,7 @@ static void extract_lnor_iter_face_bm(const MeshRenderData &mr,
static void extract_lnor_iter_face_mesh(const MeshRenderData &mr, const int face_index, void *data)
{
const bool hidden = mr.hide_poly && mr.hide_poly[face_index];
const bool hidden = !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
for (const int ml_index : mr.faces[face_index]) {
const int vert = mr.corner_verts[ml_index];
@ -69,7 +69,7 @@ static void extract_lnor_iter_face_mesh(const MeshRenderData &mr, const int face
*lnor_data = GPU_normal_convert_i10_v3(mr.loop_normals[ml_index]);
}
else if (mr.normals_domain == bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[face_index]))
(!mr.sharp_faces.is_empty() && mr.sharp_faces[face_index]))
{
*lnor_data = GPU_normal_convert_i10_v3(mr.face_normals[face_index]);
}
@ -83,7 +83,7 @@ static void extract_lnor_iter_face_mesh(const MeshRenderData &mr, const int face
if (hidden || (mr.edit_bmesh && (mr.v_origindex) && mr.v_origindex[vert] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mr.select_poly && mr.select_poly[face_index]) {
else if (!mr.select_poly.is_empty() && mr.select_poly[face_index]) {
lnor_data->w = 1;
}
else {
@ -183,7 +183,7 @@ static void extract_lnor_hq_iter_face_mesh(const MeshRenderData &mr,
const int face_index,
void *data)
{
const bool hidden = mr.hide_poly && mr.hide_poly[face_index];
const bool hidden = !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
for (const int ml_index : mr.faces[face_index]) {
const int vert = mr.corner_verts[ml_index];
@ -192,7 +192,7 @@ static void extract_lnor_hq_iter_face_mesh(const MeshRenderData &mr,
normal_float_to_short_v3(&lnor_data->x, mr.loop_normals[ml_index]);
}
else if (mr.normals_domain == bke::MeshNormalDomain::Face ||
(mr.sharp_faces && mr.sharp_faces[face_index]))
(!mr.sharp_faces.is_empty() && mr.sharp_faces[face_index]))
{
normal_float_to_short_v3(&lnor_data->x, mr.face_normals[face_index]);
}
@ -206,7 +206,7 @@ static void extract_lnor_hq_iter_face_mesh(const MeshRenderData &mr,
if (hidden || (mr.edit_bmesh && (mr.v_origindex) && mr.v_origindex[vert] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mr.select_poly && mr.select_poly[face_index]) {
else if (!mr.select_poly.is_empty() && mr.select_poly[face_index]) {
lnor_data->w = 1;
}
else {

View File

@ -87,12 +87,12 @@ static void extract_pos_nor_iter_face_mesh(const MeshRenderData &mr,
void *_data)
{
MeshExtract_PosNor_Data *data = static_cast<MeshExtract_PosNor_Data *>(_data);
const bool poly_hidden = mr.hide_poly && mr.hide_poly[face_index];
const bool poly_hidden = !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
for (const int ml_index : mr.faces[face_index]) {
const int vert_i = mr.corner_verts[ml_index];
PosNorLoop *vert = &data->vbo_data[ml_index];
const bool vert_hidden = mr.hide_vert && mr.hide_vert[vert_i];
const bool vert_hidden = !mr.hide_vert.is_empty() && mr.hide_vert[vert_i];
copy_v3_v3(vert->pos, mr.vert_positions[vert_i]);
vert->nor = data->normals[vert_i].low;
/* Flag for paint mode overlay. */
@ -100,7 +100,7 @@ static void extract_pos_nor_iter_face_mesh(const MeshRenderData &mr,
((mr.v_origindex) && (mr.v_origindex[vert_i] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
else if (mr.select_vert && mr.select_vert[vert_i]) {
else if (!mr.select_vert.is_empty() && mr.select_vert[vert_i]) {
vert->nor.w = 1;
}
else {
@ -199,12 +199,12 @@ static void extract_vertex_flags(const MeshRenderData &mr, char *flags)
{
for (int i = 0; i < mr.vert_len; i++) {
char *flag = &flags[i];
const bool vert_hidden = mr.hide_vert && mr.hide_vert[i];
const bool vert_hidden = !mr.hide_vert.is_empty() && mr.hide_vert[i];
/* Flag for paint mode overlay. */
if (vert_hidden || ((mr.v_origindex) && (mr.v_origindex[i] == ORIGINDEX_NONE))) {
*flag = -1;
}
else if (mr.select_vert && mr.select_vert[i]) {
else if (!mr.select_vert.is_empty() && mr.select_vert[i]) {
*flag = 1;
}
else {
@ -457,12 +457,12 @@ static void extract_pos_nor_hq_iter_face_mesh(const MeshRenderData &mr,
void *_data)
{
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
const bool poly_hidden = mr.hide_poly && mr.hide_poly[face_index];
const bool poly_hidden = !mr.hide_poly.is_empty() && mr.hide_poly[face_index];
for (const int ml_index : mr.faces[face_index]) {
const int vert_i = mr.corner_verts[ml_index];
const bool vert_hidden = mr.hide_vert && mr.hide_vert[vert_i];
const bool vert_hidden = !mr.hide_vert.is_empty() && mr.hide_vert[vert_i];
PosNorHQLoop *vert = &data->vbo_data[ml_index];
copy_v3_v3(vert->pos, mr.vert_positions[vert_i]);
copy_v3_v3_short(vert->nor, data->normals[vert_i].high);
@ -472,7 +472,7 @@ static void extract_pos_nor_hq_iter_face_mesh(const MeshRenderData &mr,
((mr.v_origindex) && (mr.v_origindex[vert_i] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
}
else if (mr.select_vert && mr.select_vert[vert_i]) {
else if (!mr.select_vert.is_empty() && mr.select_vert[vert_i]) {
vert->nor[3] = 1;
}
else {

View File

@ -1302,7 +1302,7 @@ bool ED_mesh_pick_face_vert(
* \return boolean true == Found
*/
struct VertPickData {
const bool *hide_vert;
blender::VArraySpan<bool> hide_vert;
const float *mval_f; /* [2] */
ARegion *region;
@ -1317,7 +1317,7 @@ static void ed_mesh_pick_vert__mapFunc(void *user_data,
const float /*no*/[3])
{
VertPickData *data = static_cast<VertPickData *>(user_data);
if (data->hide_vert && data->hide_vert[index]) {
if (!data->hide_vert.is_empty() && data->hide_vert[index]) {
return;
}
float sco[2];
@ -1334,6 +1334,7 @@ static void ed_mesh_pick_vert__mapFunc(void *user_data,
bool ED_mesh_pick_vert(
bContext *C, Object *ob, const int mval[2], uint dist_px, bool use_zbuf, uint *r_index)
{
using namespace blender;
Mesh *mesh = static_cast<Mesh *>(ob->data);
BLI_assert(mesh && GS(mesh->id.name) == ID_ME);
@ -1381,13 +1382,14 @@ bool ED_mesh_pick_vert(
return false;
}
const bke::AttributeAccessor attributes = mesh->attributes();
/* setup data */
data.region = region;
data.mval_f = mval_f;
data.len_best = FLT_MAX;
data.v_idx_best = -1;
data.hide_vert = (const bool *)CustomData_get_layer_named(
&me_eval->vert_data, CD_PROP_BOOL, ".hide_vert");
data.hide_vert = *attributes.lookup<bool>(".hide_vert", ATTR_DOMAIN_POINT);
BKE_mesh_foreach_mapped_vert(me_eval, ed_mesh_pick_vert__mapFunc, &data, MESH_FOREACH_NOP);

View File

@ -405,6 +405,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot)
/* fills in the selected faces with the current weight and vertex group */
static bool weight_paint_set(Object *ob, float paintweight)
{
using namespace blender;
Mesh *mesh = static_cast<Mesh *>(ob->data);
MDeformWeight *dw, *dw_prev;
int vgroup_active, vgroup_mirror = -1;
@ -431,19 +432,19 @@ static bool weight_paint_set(Object *ob, float paintweight)
WPaintPrev wpp;
wpaint_prev_create(&wpp, dvert, mesh->totvert);
const bool *select_vert = (const bool *)CustomData_get_layer_named(
&mesh->vert_data, CD_PROP_BOOL, ".select_vert");
const bool *select_poly = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, ".select_poly");
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan select_vert = *attributes.lookup<bool>(".select_vert", ATTR_DOMAIN_POINT);
const VArraySpan select_poly = *attributes.lookup<bool>(".select_poly", ATTR_DOMAIN_FACE);
for (const int i : faces.index_range()) {
if ((paint_selmode == SCE_SELECT_FACE) && !(select_poly && select_poly[i])) {
if ((paint_selmode == SCE_SELECT_FACE) && !(!select_poly.is_empty() && select_poly[i])) {
continue;
}
for (const int vert : corner_verts.slice(faces[i])) {
if (!dvert[vert].flag) {
if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vert])) {
if ((paint_selmode == SCE_SELECT_VERTEX) &&
!(!select_vert.is_empty() && select_vert[vert])) {
continue;
}
@ -553,7 +554,7 @@ struct WPGradient_userData {
Scene *scene;
Mesh *mesh;
MDeformVert *dvert;
const bool *select_vert;
blender::VArraySpan<bool> select_vert;
blender::VArray<bool> hide_vert;
Brush *brush;
const float *sco_start; /* [2] */
@ -654,7 +655,8 @@ static void gradientVertInit__mapFunc(void *user_data,
WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index];
if (grad_data->hide_vert[index] ||
(grad_data->use_select && (grad_data->select_vert && !grad_data->select_vert[index])))
(grad_data->use_select &&
(!grad_data->select_vert.is_empty() && !grad_data->select_vert[index])))
{
copy_v2_fl(vs->sco, FLT_MAX);
return;
@ -797,8 +799,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.scene = scene;
data.mesh = mesh;
data.dvert = dverts;
data.select_vert = (const bool *)CustomData_get_layer_named(
&mesh->vert_data, CD_PROP_BOOL, ".select_vert");
data.select_vert = *attributes.lookup<bool>(".select_vert", ATTR_DOMAIN_POINT);
data.hide_vert = *attributes.lookup_or_default<bool>(".hide_vert", ATTR_DOMAIN_POINT, false);
data.sco_start = sco_start;
data.sco_end = sco_end;

View File

@ -294,12 +294,14 @@ void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex,
float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex)
{
using namespace blender;
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
const Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh);
const float *mask = static_cast<const float *>(
CustomData_get_layer_named(&mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask"));
return mask ? mask[vertex.i] : 0.0f;
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray mask = *attributes.lookup_or_default<float>(
".sculpt_mask", ATTR_DOMAIN_POINT, 0.0f);
return mask[vertex.i];
}
case PBVH_BMESH: {
BMVert *v;
@ -408,9 +410,10 @@ bool vert_visible_get(const SculptSession *ss, PBVHVertRef vertex)
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
const Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh);
const bool *hide_vert = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->vert_data, CD_PROP_BOOL, ".hide_vert"));
return hide_vert == nullptr || !hide_vert[vertex.i];
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray hide_vert = *attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
return !hide_vert[vertex.i];
}
case PBVH_BMESH:
return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN);
@ -2890,7 +2893,7 @@ struct SculptRaycastData {
float depth;
bool original;
Span<int> corner_verts;
const bool *hide_poly;
blender::VArraySpan<bool> hide_poly;
PBVHVertRef active_vertex;
float *face_normal;
@ -2908,7 +2911,7 @@ struct SculptFindNearestToRayData {
float dist_sq_to_ray;
bool original;
Span<int> corner_verts;
const bool *hide_poly;
blender::VArraySpan<bool> hide_poly;
};
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
@ -4883,6 +4886,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
const float mval[2],
bool use_sampled_normal)
{
using namespace blender;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Scene *scene = CTX_data_scene(C);
Sculpt *sd = scene->toolsettings->sculpt;
@ -4917,8 +4921,8 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
srd.corner_verts = mesh.corner_verts();
srd.hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly"));
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
}
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
@ -5027,6 +5031,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
bool check_closest,
bool limit_closest_radius)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Object *ob;
@ -5064,8 +5069,8 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
srd.corner_verts = mesh.corner_verts();
srd.hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly"));
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
}
srd.depth = depth;
srd.original = original;
@ -5092,8 +5097,8 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
srd.corner_verts = mesh.corner_verts();
srd.hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly"));
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", ATTR_DOMAIN_FACE);
}
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;

View File

@ -818,11 +818,11 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
break;
}
case InitMode::Creases: {
const float *creases = static_cast<const float *>(
CustomData_get_layer_named(&mesh->edge_data, CD_PROP_FLOAT, "crease_edge"));
const VArraySpan<float> creases = *attributes.lookup_or_default<float>(
"crease_edge", ATTR_DOMAIN_EDGE, 0.0f);
sculpt_face_sets_init_flood_fill(
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
return creases ? creases[edge] < threshold : true;
return creases[edge] < threshold;
});
break;
}
@ -836,11 +836,11 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
break;
}
case InitMode::BevelWeight: {
const float *bevel_weights = static_cast<const float *>(
CustomData_get_layer_named(&mesh->edge_data, CD_PROP_FLOAT, "bevel_weight_edge"));
const VArraySpan<float> bevel_weights = *attributes.lookup_or_default<float>(
"bevel_weight_edge", ATTR_DOMAIN_EDGE, 0.0f);
sculpt_face_sets_init_flood_fill(
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
return bevel_weights ? bevel_weights[edge] < threshold : true;
return bevel_weights[edge] < threshold;
});
break;
}

View File

@ -22,6 +22,7 @@
#include "BKE_DerivedMesh.hh"
#include "BKE_action.h"
#include "BKE_armature.hh"
#include "BKE_attribute.hh"
#include "BKE_curve.hh"
#include "BKE_displist.h"
#include "BKE_editmesh.hh"
@ -213,7 +214,7 @@ struct foreachScreenObjectVert_userData {
void (*func)(void *user_data, const float screen_co[2], int index);
void *user_data;
ViewContext vc;
const bool *hide_vert;
blender::VArraySpan<bool> hide_vert;
eV3DProjTest clip_flag;
};
@ -272,7 +273,7 @@ static void meshobject_foreachScreenVert__mapFunc(void *user_data,
{
foreachScreenObjectVert_userData *data = static_cast<foreachScreenObjectVert_userData *>(
user_data);
if (data->hide_vert && data->hide_vert[index]) {
if (!data->hide_vert.is_empty() && data->hide_vert[index]) {
return;
}
@ -299,6 +300,7 @@ void meshobject_foreachScreenVert(ViewContext *vc,
const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
const Mesh *mesh = BKE_object_get_evaluated_mesh(ob_eval);
const blender::bke::AttributeAccessor attributes = mesh->attributes();
ED_view3d_check_mats_rv3d(vc->rv3d);
@ -306,8 +308,7 @@ void meshobject_foreachScreenVert(ViewContext *vc,
data.func = func;
data.user_data = user_data;
data.clip_flag = clip_flag;
data.hide_vert = (const bool *)CustomData_get_layer_named(
&mesh->vert_data, CD_PROP_BOOL, ".hide_vert");
data.hide_vert = *attributes.lookup<bool>(".hide_vert", ATTR_DOMAIN_POINT);
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
ED_view3d_clipping_local(vc->rv3d, vc->obact->object_to_world);

View File

@ -1466,8 +1466,8 @@ static LineartTriangle *lineart_triangle_from_index(LineartData *ld,
struct EdgeFeatData {
LineartData *ld;
Mesh *mesh;
Object *ob_eval; /* For evaluated materials. */
const int *material_indices;
Object *ob_eval; /* For evaluated materials. */
blender::Span<int> material_indices; /* May be empty. */
blender::Span<blender::int2> edges;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
@ -1506,11 +1506,11 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
EdgeFeatData *e_feat_data = (EdgeFeatData *)userdata;
EdgeFeatReduceData *reduce_data = (EdgeFeatReduceData *)tls->userdata_chunk;
Mesh *mesh = e_feat_data->mesh;
const int *material_indices = e_feat_data->material_indices;
Object *ob_eval = e_feat_data->ob_eval;
LineartEdgeNeighbor *edge_nabr = e_feat_data->edge_nabr;
const blender::Span<MLoopTri> looptris = e_feat_data->looptris;
const blender::Span<int> looptri_faces = e_feat_data->looptri_faces;
const blender::Span<int> material_indices = e_feat_data->material_indices;
uint16_t edge_flag_result = 0;
@ -1656,8 +1656,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
}
}
int mat1 = material_indices ? material_indices[looptri_faces[f1]] : 0;
int mat2 = material_indices ? material_indices[looptri_faces[f2]] : 0;
int mat1 = material_indices.is_empty() ? 0 : material_indices[looptri_faces[f1]];
int mat2 = material_indices.is_empty() ? 0 : material_indices[looptri_faces[f2]];
if (mat1 != mat2) {
Material *m1 = BKE_object_material_get_eval(ob_eval, mat1 + 1);
@ -1791,7 +1791,7 @@ struct TriData {
blender::Span<int> corner_verts;
blender::Span<MLoopTri> looptris;
blender::Span<int> looptri_faces;
const int *material_indices;
blender::Span<int> material_indices;
LineartVert *vert_arr;
LineartTriangle *tri_arr;
int lineart_triangle_size;
@ -1808,7 +1808,8 @@ static void lineart_load_tri_task(void *__restrict userdata,
const blender::Span<int> corner_verts = tri_task_data->corner_verts;
const MLoopTri *looptri = &tri_task_data->looptris[i];
const int face_i = tri_task_data->looptri_faces[i];
const int *material_indices = tri_task_data->material_indices;
const blender::Span<int> material_indices = tri_task_data->material_indices;
LineartVert *vert_arr = tri_task_data->vert_arr;
LineartTriangle *tri = tri_task_data->tri_arr;
@ -1823,8 +1824,8 @@ static void lineart_load_tri_task(void *__restrict userdata,
tri->v[2] = &vert_arr[v3];
/* Material mask bits and occlusion effectiveness assignment. */
Material *mat = BKE_object_material_get(ob_info->original_ob_eval,
material_indices ? material_indices[face_i] + 1 : 1);
Material *mat = BKE_object_material_get(
ob_info->original_ob_eval, material_indices.is_empty() ? 1 : material_indices[face_i] + 1);
tri->material_mask_bits |= ((mat && (mat->lineart.flags & LRT_MATERIAL_MASK_ENABLED)) ?
mat->lineart.material_mask_bits :
0);
@ -1958,10 +1959,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
}
/* Triangulate. */
const blender::Span<MLoopTri> looptris = mesh->looptris();
const int *material_indices = (const int *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_INT32, "material_index");
const Span<MLoopTri> looptris = mesh->looptris();
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan material_indices = *attributes.lookup<int>("material_index", ATTR_DOMAIN_FACE);
/* Check if we should look for custom data tags like Freestyle edges or faces. */
bool can_find_freestyle_edge = false;
@ -2090,7 +2090,6 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData);
edge_feat_settings.func_reduce = feat_data_sum_reduce;
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<bool> sharp_edges = *attributes.lookup_or_default<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE, false);
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(

View File

@ -200,10 +200,9 @@ int OBJMesh::ith_smooth_group(const int face_index) const
void OBJMesh::calc_smooth_groups(const bool use_bitflags)
{
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&export_mesh_->edge_data, CD_PROP_BOOL, "sharp_edge"));
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&export_mesh_->face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = export_mesh_->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.size(),
mesh_faces_,
export_mesh_->corner_edges(),

View File

@ -183,12 +183,10 @@ static void rna_CurvePoint_location_set(PointerRNA *ptr, const float value[3])
static float rna_CurvePoint_radius_get(PointerRNA *ptr)
{
using namespace blender;
const Curves *curves = rna_curves(ptr);
const float *radii = static_cast<const float *>(
CustomData_get_layer_named(&curves->geometry.point_data, CD_PROP_FLOAT, "radius"));
if (radii == nullptr) {
return 0.0f;
}
const bke::AttributeAccessor attributes = curves->geometry.wrap().attributes();
const VArray radii = *attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 0.0f);
return radii[rna_CurvePoint_index_get_const(ptr)];
}

View File

@ -90,11 +90,11 @@ static void rna_Mesh_calc_looptri(Mesh *mesh)
static void rna_Mesh_calc_smooth_groups(
Mesh *mesh, bool use_bitflags, int **r_poly_group, int *r_poly_group_num, int *r_group_total)
{
using namespace blender;
*r_poly_group_num = mesh->faces_num;
const bool *sharp_edges = (const bool *)CustomData_get_layer_named(
&mesh->edge_data, CD_PROP_BOOL, "sharp_edge");
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
&mesh->face_data, CD_PROP_BOOL, "sharp_face");
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
*r_poly_group = BKE_mesh_calc_smoothgroups(mesh->totedge,
mesh->faces(),
mesh->corner_edges(),

View File

@ -232,6 +232,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
blender::MutableSpan<int> corner_edges,
const blender::OffsetIndices<int> faces)
{
using namespace blender;
Object *ob_target = enmd->target;
const bool do_facenors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
@ -321,8 +322,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
if (do_facenors_fix) {
faces_check_flip(*mesh, nos, mesh->face_normals());
}
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
blender::bke::mesh::normals_loop_custom_set(vert_positions,
edges,
faces,
@ -358,6 +359,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
blender::MutableSpan<int> corner_edges,
const blender::OffsetIndices<int> faces)
{
using namespace blender;
Object *ob_target = enmd->target;
const bool do_facenors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
@ -426,8 +428,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
if (do_facenors_fix) {
faces_check_flip(*mesh, nos, mesh->face_normals());
}
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
blender::bke::mesh::normals_loop_custom_set(positions,
edges,
faces,
@ -511,8 +513,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
clnors = static_cast<blender::short2 *>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size()));
loop_normals.reinitialize(corner_verts.size());
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&result->face_data, CD_PROP_BOOL, "sharp_face"));
const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
blender::bke::mesh::normals_calc_loop(positions,
edges,
faces,
@ -521,7 +522,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
result->corner_to_face_map(),
result->vert_normals(),
result->face_normals(),
sharp_edges.span.data(),
sharp_edges.span,
sharp_faces,
clnors,
nullptr,

View File

@ -22,6 +22,7 @@
#include "DNA_scene_types.h"
#include "BKE_action.h" /* BKE_pose_channel_find_name */
#include "BKE_attribute.hh"
#include "BKE_deform.h"
#include "BKE_editmesh.hh"
#include "BKE_image.h"
@ -100,8 +101,9 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__);
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
CustomData_validate_layer_name(&mesh->loop_data, CD_PROP_FLOAT2, dmd->uvlayer_name, uvname);
const float(*mloop_uv)[2] = static_cast<const float(*)[2]>(
CustomData_get_layer_named(&mesh->loop_data, CD_PROP_FLOAT2, uvname));
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan uv_map = *attributes.lookup_or_default<float2>(
uvname, ATTR_DOMAIN_CORNER, float2(0));
/* verts are given the UV from the first face that uses them */
for (const int i : faces.index_range()) {
@ -110,8 +112,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
const int vert = corner_verts[corner];
if (!BLI_BITMAP_TEST(done, vert)) {
/* remap UVs from [0, 1] to [-1, 1] */
r_texco[vert][0] = (mloop_uv[corner][0] * 2.0f) - 1.0f;
r_texco[vert][1] = (mloop_uv[corner][1] * 2.0f) - 1.0f;
r_texco[vert][0] = (uv_map[corner][0] * 2.0f) - 1.0f;
r_texco[vert][1] = (uv_map[corner][1] * 2.0f) - 1.0f;
BLI_BITMAP_ENABLE(done, vert);
}
}

View File

@ -86,7 +86,7 @@ struct WeightedNormalData {
blender::OffsetIndices<int> faces;
blender::Span<blender::float3> face_normals;
const bool *sharp_faces;
blender::VArraySpan<bool> sharp_faces;
const int *face_strength;
const MDeformVert *dvert;
@ -228,7 +228,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
loop_to_face,
wn_data->vert_normals,
wn_data->face_normals,
wn_data->sharp_edges.data(),
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
&lnors_spacearr,
@ -356,7 +356,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
loop_to_face,
wn_data->vert_normals,
face_normals,
wn_data->sharp_edges.data(),
wn_data->sharp_edges,
wn_data->sharp_faces,
has_clnors ? clnors.data() : nullptr,
nullptr,
@ -541,8 +541,7 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh
wn_data.faces = faces;
wn_data.face_normals = mesh->face_normals();
wn_data.sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, "sharp_face"));
wn_data.sharp_faces = *attributes.lookup<bool>("sharp_face", ATTR_DOMAIN_FACE);
wn_data.face_strength = static_cast<const int *>(CustomData_get_layer_named(
&result->face_data, CD_PROP_INT32, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID));

View File

@ -44,7 +44,7 @@ class InstanceRotationFieldInput final : public bke::InstancesFieldInput {
static void node_geo_exec(GeoNodeExecParams params)
{
Field<float3> rotation{std::make_shared<InstanceRotationFieldInput>()};
Field<math::Quaternion> rotation{std::make_shared<InstanceRotationFieldInput>()};
params.set_output("Rotation", std::move(rotation));
}

View File

@ -520,6 +520,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
if (require_tangent) {
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
const blender::Span<blender::float3> corner_normals = temp_mesh->corner_normals();
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"));
BKE_mesh_calc_loop_tangent_ex(
reinterpret_cast<const float(*)[3]>(positions.data()),
faces,
@ -527,8 +529,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
looptris.data(),
looptri_faces.data(),
looptris.size(),
static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")),
sharp_faces ? blender::Span(sharp_faces, faces.size()) : blender::Span<bool>(),
&dm->loopData,
true,
nullptr,

View File

@ -13,6 +13,7 @@
#include "BLI_vector.hh"
#include "BKE_DerivedMesh.hh"
#include "BKE_attribute.hh"
#include "BKE_customdata.hh"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.hh"
@ -567,15 +568,13 @@ void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf,
char const *uv_layer,
const float uv_offset[2])
{
const blender::float2 *mloopuv;
if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) {
mloopuv = static_cast<const blender::float2 *>(
CustomData_get_layer(&mesh->loop_data, CD_PROP_FLOAT2));
}
else {
mloopuv = static_cast<const blender::float2 *>(
CustomData_get_layer_named(&mesh->loop_data, CD_PROP_FLOAT2, uv_layer));
}
const blender::StringRef uv_map_name = (uv_layer && uv_layer[0]) ?
uv_layer :
CustomData_get_active_layer_name(&mesh->loop_data,
CD_PROP_FLOAT2);
const blender::bke::AttributeAccessor attributes = mesh->attributes();
const blender::VArraySpan<blender::float2> uv_map = *attributes.lookup<blender::float2>(
uv_map_name, ATTR_DOMAIN_CORNER);
blender::render::texturemargin::generate_margin(ibuf,
mask,
@ -585,7 +584,7 @@ void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf,
mesh->faces(),
mesh->corner_edges(),
mesh->corner_verts(),
{mloopuv, mesh->totloop},
uv_map,
uv_offset);
}