Cleanup: Small cleanups to mesh normals calculation

- Use consistent data fetch order
- Slightly tweak whitespace
- Use C++ vector type and math function
This commit is contained in:
Hans Goudey 2023-11-11 22:41:21 +01:00
parent 6273205c93
commit 0d1831cd2e

@ -240,18 +240,18 @@ blender::bke::MeshNormalDomain Mesh::normals_domain() const
blender::Span<blender::float3> Mesh::vert_normals() const
{
using namespace blender;
using namespace blender::bke;
if (this->runtime->vert_normals_cache.is_cached()) {
return this->runtime->vert_normals_cache.data();
}
const Span<float3> positions = this->vert_positions();
const OffsetIndices faces = this->faces();
const Span<int> corner_verts = this->corner_verts();
const Span<float3> positions = this->vert_positions();
const Span<float3> face_normals = this->face_normals();
const GroupedSpan<int> vert_to_face_map = this->vert_to_face_map();
const GroupedSpan<int> vert_to_face = this->vert_to_face_map();
this->runtime->vert_normals_cache.ensure([&](Vector<float3> &r_data) {
r_data.reinitialize(positions.size());
bke::mesh::normals_calc_verts(
positions, faces, corner_verts, vert_to_face_map, face_normals, r_data);
mesh::normals_calc_verts(positions, faces, corner_verts, vert_to_face, face_normals, r_data);
});
return this->runtime->vert_normals_cache.data();
}
@ -263,7 +263,6 @@ blender::Span<blender::float3> Mesh::face_normals() const
const Span<float3> positions = this->vert_positions();
const OffsetIndices faces = this->faces();
const Span<int> corner_verts = this->corner_verts();
r_data.reinitialize(faces.size());
bke::mesh::normals_calc_faces(positions, faces, corner_verts, r_data);
});
@ -395,16 +394,16 @@ MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
namespace blender::bke::mesh {
static CornerNormalSpace lnor_space_define(const float lnor[3],
float vec_ref[3],
float vec_other[3],
static CornerNormalSpace lnor_space_define(const float3 &lnor,
float3 vec_ref,
float3 vec_other,
const Span<float3> edge_vectors)
{
CornerNormalSpace lnor_space{};
const float pi2 = float(M_PI) * 2.0f;
float tvec[3], dtp;
const float dtp_ref = dot_v3v3(vec_ref, lnor);
const float dtp_other = dot_v3v3(vec_other, lnor);
const float dtp_ref = math::dot(vec_ref, lnor);
const float dtp_other = math::dot(vec_other, lnor);
if (UNLIKELY(fabsf(dtp_ref) >= LNOR_SPACE_TRIGO_THRESHOLD ||
fabsf(dtp_other) >= LNOR_SPACE_TRIGO_THRESHOLD))
@ -421,7 +420,7 @@ static CornerNormalSpace lnor_space_define(const float lnor[3],
if (!edge_vectors.is_empty()) {
float alpha = 0.0f;
for (const float3 &vec : edge_vectors) {
alpha += math::safe_acos_approx(dot_v3v3(vec, lnor));
alpha += math::safe_acos_approx(math::dot(vec, lnor));
}
/* This piece of code shall only be called for more than one loop. */
/* NOTE: In theory, this could be `count > 2`,
@ -432,8 +431,8 @@ static CornerNormalSpace lnor_space_define(const float lnor[3],
lnor_space.ref_alpha = alpha / float(edge_vectors.size());
}
else {
lnor_space.ref_alpha = (math::safe_acos_approx(dot_v3v3(vec_ref, lnor)) +
math::safe_acos_approx(dot_v3v3(vec_other, lnor))) /
lnor_space.ref_alpha = (math::safe_acos_approx(math::dot(vec_ref, lnor)) +
math::safe_acos_approx(math::dot(vec_other, lnor))) /
2.0f;
}
@ -451,10 +450,10 @@ static CornerNormalSpace lnor_space_define(const float lnor[3],
normalize_v3(vec_other);
/* Beta is angle between ref_vec and other_vec, around lnor. */
dtp = dot_v3v3(lnor_space.vec_ref, vec_other);
dtp = math::dot(lnor_space.vec_ref, vec_other);
if (LIKELY(dtp < LNOR_SPACE_TRIGO_THRESHOLD)) {
const float beta = math::safe_acos_approx(dtp);
lnor_space.ref_beta = (dot_v3v3(lnor_space.vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta;
lnor_space.ref_beta = (math::dot(lnor_space.vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta;
}
else {
lnor_space.ref_beta = pi2;
@ -580,11 +579,9 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
short2 r_clnor_data;
const float pi2 = float(M_PI * 2.0);
const float cos_alpha = dot_v3v3(lnor_space.vec_lnor, custom_lnor);
float vec[3], cos_beta;
float alpha;
const float cos_alpha = math::dot(lnor_space.vec_lnor, custom_lnor);
alpha = math::safe_acos_approx(cos_alpha);
const float alpha = math::safe_acos_approx(cos_alpha);
if (alpha > lnor_space.ref_alpha) {
/* Note we could stick to [0, pi] range here,
* but makes decoding more complex, not worth it. */
@ -595,15 +592,16 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space,
}
/* Project custom lnor on (vec_ref, vec_ortho) plane. */
float3 vec;
mul_v3_v3fl(vec, lnor_space.vec_lnor, -cos_alpha);
add_v3_v3(vec, custom_lnor);
normalize_v3(vec);
cos_beta = dot_v3v3(lnor_space.vec_ref, vec);
const float cos_beta = math::dot(lnor_space.vec_ref, vec);
if (cos_beta < LNOR_SPACE_TRIGO_THRESHOLD) {
float beta = math::safe_acos_approx(cos_beta);
if (dot_v3v3(lnor_space.vec_ortho, vec) < 0.0f) {
if (math::dot(lnor_space.vec_ortho, vec) < 0.0f) {
beta = pi2 - beta;
}
@ -697,8 +695,8 @@ static void mesh_edges_sharp_tag(const OffsetIndices<int> faces,
}
else if (e2l[1] == INDEX_UNSET) {
const bool is_angle_sharp = (check_angle &&
dot_v3v3(face_normals[loop_to_face_map[e2l[0]]],
face_normals[face_i]) < split_angle_cos);
math::dot(face_normals[loop_to_face_map[e2l[0]]],
face_normals[face_i]) < split_angle_cos);
/* Second loop using this edge, time to test its sharpness.
* An edge is sharp if it is tagged as such, or its face is not smooth,