Cleanup: simplify access to cached mesh normals

This commit is contained in:
Jacques Lucke 2022-12-02 13:11:53 +01:00
parent 198460f6a4
commit 6d22aa2f84
4 changed files with 31 additions and 10 deletions

View File

@ -1122,6 +1122,18 @@ inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
return {BKE_mesh_deform_verts_for_write(this), this->totvert};
}
inline blender::Span<blender::float3> Mesh::poly_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_poly_normals_ensure(this)),
this->totpoly};
}
inline blender::Span<blender::float3> Mesh::vertex_normals() const
{
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vertex_normals_ensure(this)),
this->totvert};
}
#endif
/** \} */

View File

@ -124,19 +124,17 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
{
switch (domain) {
case ATTR_DOMAIN_FACE: {
return VArray<float3>::ForSpan(
{(float3 *)BKE_mesh_poly_normals_ensure(&mesh), mesh.totpoly});
return VArray<float3>::ForSpan(mesh.poly_normals());
}
case ATTR_DOMAIN_POINT: {
return VArray<float3>::ForSpan(
{(float3 *)BKE_mesh_vertex_normals_ensure(&mesh), mesh.totvert});
return VArray<float3>::ForSpan(mesh.vertex_normals());
}
case ATTR_DOMAIN_EDGE: {
/* In this case, start with vertex normals and convert to the edge domain, since the
* conversion from edges to vertices is very simple. Use "manual" domain interpolation
* instead of the GeometryComponent API to avoid calculating unnecessary values and to
* allow normalizing the result more simply. */
Span<float3> vert_normals{(float3 *)BKE_mesh_vertex_normals_ensure(&mesh), mesh.totvert};
Span<float3> vert_normals = mesh.vertex_normals();
const Span<MEdge> edges = mesh.edges();
Array<float3> edge_normals(mask.min_array_size());
for (const int i : mask) {
@ -153,9 +151,7 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
* component's generic domain interpolation is fine, the data will still be normalized,
* since the face normal is just copied to every corner. */
return mesh.attributes().adapt_domain(
VArray<float3>::ForSpan({(float3 *)BKE_mesh_poly_normals_ensure(&mesh), mesh.totpoly}),
ATTR_DOMAIN_FACE,
ATTR_DOMAIN_CORNER);
VArray<float3>::ForSpan(mesh.poly_normals()), ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER);
}
default:
return {};

View File

@ -15,6 +15,9 @@
/** Workaround to forward-declare C++ type in C header. */
#ifdef __cplusplus
# include "BLI_math_vec_types.hh"
namespace blender {
template<typename T> class Span;
template<typename T> class MutableSpan;
@ -267,6 +270,17 @@ typedef struct Mesh {
* cache dirty. If the mesh was changed first, the relevant dirty tags should be called first.
*/
void loose_edges_tag_none() const;
/**
* Normal direction of every polygon, which is defined by the winding direction of its corners.
*/
blender::Span<blender::float3> poly_normals() const;
/**
* Normal direction for each vertex, which is defined as the weighted average of the normals
* from a vertices surrounding faces, or the normalized position of vertices connected to no
* faces.
*/
blender::Span<blender::float3> vertex_normals() const;
#endif
} Mesh;

View File

@ -40,8 +40,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput {
const Span<MVert> verts = mesh.verts();
const Span<MPoly> polys = mesh.polys();
const Span<MLoop> loops = mesh.loops();
const Span<float3> poly_normals{
reinterpret_cast<const float3 *>(BKE_mesh_poly_normals_ensure(&mesh)), mesh.totpoly};
const Span<float3> poly_normals = mesh.poly_normals();
bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE};
fn::FieldEvaluator evaluator{context, polys.size()};