Page MenuHome

Geometry Nodes: Expose vertex normals as an attribute
ClosedPublic

Authored by Hans Goudey (HooglyBoogly) on Feb 26 2021, 5:35 AM.

Details

Summary

This attribute exposes mesh vertex normals as an attribute for use with
the attribute nodes. Since the normal vector stored in vertices is only
a cache of data computable from the surrounding faces, the attribute is
read-only.

Initially I was hoping this could be a write-able attribute, but it
doesn't work consistently because the data is treated strictly as a
cache in the code. Custom normals will be stored on the corner domain,
an attribute which will be called corner_normal.

Diff Detail

Repository
rB Blender

Event Timeline

Hans Goudey (HooglyBoogly) requested review of this revision.Feb 26 2021, 5:35 AM
Hans Goudey (HooglyBoogly) created this revision.
  • Add checks in join node and realize instances code
Jacques Lucke (JacquesLucke) requested changes to this revision.Feb 26 2021, 1:59 PM

The code looks mostly good, except for a rather large constness and threading issue which really needs to be resolved first..

source/blender/blenkernel/intern/attribute_access.cc
1379

Need to be very careful here. Const-casting the geometry component seems dangerous here, also because MeshComponent::get_for_write might make a copy of the mesh.

It would be better to only cast away const from the Mesh *. Furthermore, to make this work, BKE_mesh_calc_normals needs to become threadsafe. Currently it is not protected by a mutex, so different threads could enter it on the same mesh at the same time.

source/blender/blenkernel/intern/geometry_set_instances.cc
382

We should probably store this list somewhere else, but that can be changed separately.

This revision now requires changes to proceed.Feb 26 2021, 1:59 PM
  • Add a mutex so multiple threads don't write normals from this function at the same time

As noted in the code, this uses a global mutex rather than a per-mesh mutex. I thought of
using a mutex stored on MeshComponent, but then two mesh components might share the same
mesh, so that probably wouldn't work. Note that I've tried a few things, but I haven't been
able to trigger a problem without this lock though. Maybe there are better ways to solve
this, I'm not sure.

This locking feels really weak to me, but we might be lucky in the case of vertex normals that it won't cause any issues. In the long run we really need a more general solution to cached derived mesh data.
Given that vertex normals are exposed as readonly attribute, we can still change the internal implementation later on if necessary.

source/blender/blenkernel/intern/attribute_access.cc
1388

This could actually use a double checked lock as well, so that the normals are not needless recomputed.

1525

Wanted to rename to vertex_normal.

Hans Goudey (HooglyBoogly) marked 3 inline comments as done.
  • Merge branch 'master' into geometry-nodes-normal-attribute
  • Rename attribute to vertex_normal (see T86206)
  • Remove unecessary change
  • Double check if normals are dirty after lock, improve comments

Do you think it would be better to use MeshRuntime.eval_mutex?

Hm, using that existing mutex seems to make sense. Ideally we want something very similar to BKE_mesh_runtime_looptri_ensure.

  • Merge branch 'master' into geometry-nodes-normal-attribute
  • Use mesh eval mutex

This inline comment still needs to be fixed, but then this should be fine, I hope.

source/blender/blenkernel/intern/geometry_set_instances.cc
382

still says normal, same below

This revision is now accepted and ready to land.Mar 5 2021, 8:21 PM