Commit Graph

1299 Commits

Author SHA1 Message Date
Hans Goudey
d0705bd697 Mesh: Split MLoopTri poly indices into a separate array
For derived mesh triangulation information, currently the three face
corner indices are stored in the same struct as index of the mesh
polygon the triangle is part of. While those pieces of information are
often used together, they often aren't, and combining them prevents
the indices from being used with generic utilities. It also means that
1/3 more memory has to be written when recalculating the triangulation
after deforming the mesh, and that the entire triangle data has to be
read when only the polygon indices are needed.

This commit splits the polygon index into a separate cache on `Mesh`.
The triangulation data isn't saved to files, so this doesn't affect
.blend files at all.

In a simple test deforming a mesh with geometry nodes, the time used
to recalculate the triangulation reduced from 2.0 ms to 1.6 ms,
increasing overall FPS from 14.6 to 15.

Pull Request: https://projects.blender.org/blender/blender/pulls/106774
2023-05-04 15:39:10 +02:00
Hans Goudey
367145209c Cleanup: Move attribute_math to proper blenkernel namespace
The fact that blenlib doesn't know about the set of attribute types is
actually an important detail right now that can influence how things
are designed. Longer term it would be good to consolidate many of
these attribute propagation algorithms anyway.
2023-05-03 12:10:54 -04:00
Hans Goudey
d9a7f1285f Cleanup: Rename field input classes to match UI names 2023-05-03 12:10:54 -04:00
Hans Goudey
7f040099e3 Cleanup: Deduplicate sampling at index in geometry nodes
The "Evaluate at Index" and "Sample Index" nodes are exactly the same
once they retrieve the values to copy and the indices (apart from the
clamping option anyway). This also allows devirtualizing the index input
in the evaluate at index node like the sample index node.
2023-05-03 12:10:54 -04:00
Sergey Sharybin
42cdd39618 Fix return of stack memory
The fix is suggested by Jacques.

Pull Request: https://projects.blender.org/blender/blender/pulls/107586
2023-05-03 17:59:12 +02:00
Hans Goudey
7ff752b789 Cleanup: Unify mesh sampling multifunctions
Change the implementation of the raycast and sample nearest surface
node to split separate loops into separate multi-functions. This
clarifies the task of each function, gives more information to the
field evaluator, and gives more opportunity for memory reuse.

Sampling mesh attributes with triangle barycentric weights is now
implemented in a single place. Two other new multi-functions
handle conversion of sampled positions into barycentric weights.
Normalizing the ray directions for the raycast node is split out
too, so it can be skipped in some cases in the future.

The mesh attribute interpolator helper class is also removed,
since it didn't give much benefit over a more functional approach.

I didn't notice a performance improvement from this change.

Pull Request: https://projects.blender.org/blender/blender/pulls/107563
2023-05-03 15:07:16 +02:00
Hong Shin
642e18e889 Cleanup: Move node_util.h to C++
Ref: #103343

Pull Request: https://projects.blender.org/blender/blender/pulls/107569
2023-05-03 14:21:14 +02:00
Jacques Lucke
0de54b84c6 Geometry Nodes: add simulation support
This adds support for building simulations with geometry nodes. A new
`Simulation Input` and `Simulation Output` node allow maintaining a
simulation state across multiple frames. Together these two nodes form
a `simulation zone` which contains all the nodes that update the simulation
state from one frame to the next.

A new simulation zone can be added via the menu
(`Simulation > Simulation Zone`) or with the node add search.

The simulation state contains a geometry by default. However, it is possible
to add multiple geometry sockets as well as other socket types. Currently,
field inputs are evaluated and stored for the preceding geometry socket in
the order that the sockets are shown. Simulation state items can be added
by linking one of the empty sockets to something else. In the sidebar, there
is a new panel that allows adding, removing and reordering these sockets.

The simulation nodes behave as follows:
* On the first frame, the inputs of the `Simulation Input` node are evaluated
  to initialize the simulation state. In later frames these sockets are not
  evaluated anymore. The `Delta Time` at the first frame is zero, but the
  simulation zone is still evaluated.
* On every next frame, the `Simulation Input` node outputs the simulation
  state of the previous frame. Nodes in the simulation zone can edit that
  data in arbitrary ways, also taking into account the `Delta Time`. The new
  simulation state has to be passed to the `Simulation Output` node where it
  is cached and forwarded.
* On a frame that is already cached or baked, the nodes in the simulation
  zone are not evaluated, because the `Simulation Output` node can return
  the previously cached data directly.

It is not allowed to connect sockets from inside the simulation zone to the
outside without going through the `Simulation Output` node. This is a necessary
restriction to make caching and sub-frame interpolation work. Links can go into
the simulation zone without problems though.

Anonymous attributes are not propagated by the simulation nodes unless they
are explicitly stored in the simulation state. This is unfortunate, but
currently there is no practical and reliable alternative. The core problem
is detecting which anonymous attributes will be required for the simulation
and afterwards. While we can detect this for the current evaluation, we can't
look into the future in time to see what data will be necessary. We intend to
make it easier to explicitly pass data through a simulation in the future,
even if the simulation is in a nested node group.

There is a new `Simulation Nodes` panel in the physics tab in the properties
editor. It allows baking all simulation zones on the selected objects. The
baking options are intentially kept at a minimum for this MVP. More features
for simulation baking as well as baking in general can be expected to be added
separately.

All baked data is stored on disk in a folder next to the .blend file. #106937
describes how baking is implemented in more detail. Volumes can not be baked
yet and materials are lost during baking for now. Packing the baked data into
the .blend file is not yet supported.

The timeline indicates which frames are currently cached, baked or cached but
invalidated by user-changes.

Simulation input and output nodes are internally linked together by their
`bNode.identifier` which stays the same even if the node name changes. They
are generally added and removed together. However, there are still cases where
"dangling" simulation nodes can be created currently. Those generally don't
cause harm, but would be nice to avoid this in more cases in the future.

Co-authored-by: Hans Goudey <h.goudey@me.com>
Co-authored-by: Lukas Tönne <lukas@blender.org>

Pull Request: https://projects.blender.org/blender/blender/pulls/104924
2023-05-03 13:18:59 +02:00
Hans Goudey
b3a3b94976 Cleanup: Avoid allocating extra array in sample nearest node
The distances array was filled but never used.
2023-05-02 15:07:52 -04:00
Campbell Barton
6859bb6e67 Cleanup: format (with BraceWrapping::AfterControlStatement "MultiLine") 2023-05-02 09:37:49 +10:00
Damien Picard
44103f5529 I18n: improve geometry nodes field tooltips
Node socket tooltips suffered from several issues.

- Some could not be translated because they were not properly
  extracted, so extraction macros were added.

- Some were extracted but included newlines at the end which did not
  get translated, such as `ss << TIP_("Geometry:\n")`, changed to
  `ss << TIP_("Geometry:") << "\n"`.

- Some translations were not functional, such as:
  `TIP_(attributes_num == 1 ? " Named Attribute" : " Named Attributes");`
  because `TIP_()` needs to be around a single string.

- Some extraction macros had no effect and were removed, such as:
  `.description(N_(leading_out_description));`
  This is a no-op macro which can be used only around a string literal.

Pull Request: https://projects.blender.org/blender/blender/pulls/107257
2023-04-28 21:37:33 +02:00
Hans Goudey
bec033e057 Cleanup: Simplify and deduplicate mesh sampling code
It arguably reads easier if simple operations like reading from indices
of an array don't each get their own line. Also the same corner
attribute sampling was repeated in a few places. And add a new
function to sample normals from the corner domain, and use
lower level arguments to the lower level functions (i.e. not just
a mesh pointer, but the necessary data arrays).
2023-04-28 14:45:22 -04:00
Hans Goudey
bea6391188 Fix: Wrong logic in recent extrude node fix
A local change that I forgot to add to the commit before pushing.
2023-04-28 14:14:32 -04:00
Hans Goudey
060216ac31 Cleanup: Implement "make available" for extrude node individual input
Since the faces mode is already the default, this won't change
anything, but it makes sense to have for consistency anyway.
2023-04-28 14:00:10 -04:00
Hans Goudey
0f47722d82 Fix: Extrude node propagates all anonymous attributes
Usually anonymous attributes are removed earlier, but otherwise
the extrude node can end up doing extra work.We need to retrieve the
propagation set and remove not-propagated attributes. And also fix
a case where in vertex mode, the offsets array could be freed when
the mesh is resized.
2023-04-28 14:00:10 -04:00
Hans Goudey
a6baf7beae BLI: Allow different integer types when filling span indices 2023-04-27 08:50:41 -04:00
Hans Goudey
4b96af6cdd Cleanup: Remove timer in node, improve comment 2023-04-26 23:50:57 -04:00
Chris Blackbourn
249f677a1f Cleanup: format 2023-04-27 10:36:43 +12:00
Hans Goudey
d8f4387ac9 Geometry Nodes: Index of Nearest: Use grain size based on tree sizes
Use a grain size for the final tree creation/balancing/lookup that
depends on the average size of each tree. When the trees are larger,
fewer trees are processed on each thread and vice versa. I didn't notice
a difference when there are hundreds of thousands of groups, but
when there are few (i.e. around the number of cores), I noticed a 6x
performance improvement, from over 1 second to around 0.2 s.

Note that generally the performance is better with many small groups,
because the creation and balancing of trees is single threaded.
2023-04-26 12:34:48 -04:00
Hans Goudey
4346314351 Geometry Nodes: Index of Nearest: Use span for non-single ids
If the Group ID input isn't a single value, it's likely to be a span,
so making sure that's true should generally be free, at least in
most cases. This brought a test with 1 million points from 37
to 34 ms, roughtly an 8% improvement.
2023-04-26 12:26:38 -04:00
Campbell Barton
ca98185f84 Cleanup: quiet unused function warning WITH_OPENSUBDIV=OFF 2023-04-26 16:14:07 +10:00
Hans Goudey
5727851d65 Cleanup: Declare field context variables const 2023-04-25 22:23:38 -04:00
Erik Abrahamsson
700d168a5c Volumes: Generate proper fog volume in Mesh to Volume node
Currently `Mesh to Volume` creates a volume using
`openvdb::tools::meshToVolume` which is then filled with the specified
density and the class set to Fog Volume. This is wrong because
`meshToVolume` creates a signed distance field by default that needs
to be converted to a Fog Volume with `openvdb::tools::sdfToFogVolume`
to get a proper Fog volume.

Here is the description of what that function does (from OpenVDB):

"The active and negative-valued interior half of the narrow band
becomes a linear ramp from 0 to 1; the inactive interior becomes
active with a constant value of 1; and the exterior, including the
background and the active exterior half of the narrow band, becomes
inactive with a constant value of 0. The interior, though active,
remains sparse."

This means with this commit old files will not look the same.
There is no way to version this as the options for external band width
and not filling the volume is removed (they don't make any sense for a
proper fog volume).

Pull Request: https://projects.blender.org/blender/blender/pulls/107279
2023-04-25 21:56:14 +02:00
Jacques Lucke
a57584e40d BLI: extract MapItem type to simplify iterating over map items 2023-04-25 12:15:02 +02:00
Damien Picard
4f08eeae9c Nodes: Make spacings unitless in String to Curves node
The String to Curves node allows selecting various metrics for the
characters. Size is the absolute height between two lines, and is
correctly marked as a distance. Character, Word and Line Spacing, on
the other hand, do not represent any distance, but are proportional to
the base size and should not have distance units.

This commit simply removes the properties' `PROP_DISTANCE` subtype.

Pull Request: https://projects.blender.org/blender/blender/pulls/106660
2023-04-24 18:31:25 +02:00
Jacques Lucke
ca32fb604e Geometry Nodes: support outputting field without computing full node
Many nodes output anonymous attributes (e.g. the top selection in the
Cylinder node). The actual data is only contained in the geometry output
though. The field output just contains a reference to this data (essentially
just the generated name of an attribute). This data can be output even
without computing the geometry itself.

As of right now, this only simplifies the code a bit, but does not have a
bigger impact, because to use the anonymous attribute, you always need
the geometry anyway. However, with the upcoming simulation nodes,
it's possible to create the anonymous attribute in one frame and to access
it in another frame. In the other frame we only need the anonymous
attribute reference and don't have to create the actual geometry again.
Skipping creating the actual attribute on the geometry can have a
significant performance benefit.
2023-04-24 11:42:05 +02:00
Hans Goudey
993d24c174 Cleanup: Miscellaneous improvements to subdivision geometry nodes
- Implement mesh creation in GeometrySet agnostic way, with less context
- Remove useless comments
- Use a field to clamp crease values instead of clamping when copying
- Small variable name tweaks
- Use `BKE_subdiv_new_from_mesh` instead of "update"
- Remove crease layers before writing, avoiding potential copy
2023-04-23 15:27:20 -04:00
Hans Goudey
2f581a779c Cleanup: Use utility constructor to create field operations 2023-04-23 15:27:20 -04:00
Jacques Lucke
1e81e27557 Cleanup: use hash value that fits into int to fix compile error 2023-04-22 15:28:26 +02:00
Hans Goudey
8e967cfeaf Mesh: Cache loose vertices
Similar to the cache of loose edges added in 1ea169d90e,
cache the number of loose vertices and which are loose in a bit map.
This can save significant time when drawing large meshes in the
viewport, because recalculations can be avoided when the data doesn't
change, and because many geometry nodes set the loose geometry
caches eagerly when the meshes contain no loose elements.

There are two types of loose vertices:
1. Vertices not used by any edges or faces
   `Mesh.loose_verts()`
2. Vertices not used by any faces (may be used by loose edges)
   `Mesh.verts_no_face()`

Because both are used by Blender in various places, because the cost
is only a bit per vertex (or constant at best) and for design consistency,
we cache both types of loose elements. The bit maps will only be
allocated when they're actually used, but they are already accessed
in a few important places:
- Attribute domain interpolation
- Subdivision surface modifier
- Viewport drawing

Just skipping viewport drawing calculation after certain geometry
nodes setups can have a large impact. Here is the time taken by
viewport loose geometry extraction before and after the change:
- 4 million vertex grid node: 28 ms to 0 ms
- Large molecular nodes setup (curve to mesh node): 104 ms to 0 ms
- Realize instances with 1 million cubes: 131 ms to 0 ms

Pull Request: https://projects.blender.org/blender/blender/pulls/105567
2023-04-22 13:46:11 +02:00
illua1
15f9e42c4f Geometry Nodes: new Index of Nearest node
The node outputs the index of the closest element to itself. See #102387
for the original design.

This is different from the Sample Nearest node in two important ways:
* It does not have a geometry input, instead the geometry is taken from the
  field evaluation context.
* The node can exclude the "current" element from the search.
* The group id input can be used to build subsets of elements that only
  consider each other as neighbors and ignore elements with other ids.

Pull Request: https://projects.blender.org/blender/blender/pulls/104619
2023-04-22 13:11:51 +02:00
Jacques Lucke
3ee21d1098 Cleanup: rename anonymous attribute id pointer type 2023-04-21 14:14:27 +02:00
Iliya Katueshenock
88f6d584ca Fix: wrong field inferencing in Sample Curve node
Whether the outputs are fields only depends on whether at least one of the
last three inputs is a field. It does not matter whether the `Value` input is
a field.

Pull Request: https://projects.blender.org/blender/blender/pulls/106007
2023-04-21 13:27:09 +02:00
Brecht Van Lommel
0e23aef6b6 Fix build error when not using unity build 2023-04-20 15:46:15 +02:00
Hans Goudey
10d175e223 Cleanup: Use consistent argument order for mesh creation functions
The typical order is vertex, edge, face(polygon), corner(loop), but in
these three functions polys and loops were reversed. Also use more
typical "num" variable names rather than "len"
2023-04-19 15:52:56 -04:00
Hans Goudey
097b9c5a36 Fix: Build error after last commit
Also fix fallthrough warnings
2023-04-19 13:05:08 -04:00
Hans Goudey
e45ed69349 Attributes: Integrate implicit sharing with the attribute API
Add the ability to retrieve implicit sharing info directly from the
C++ attribute API, which simplifies memory usage and performance
optimizations making use of it. This commit uses the additions to
the API to avoid copies in a few places:
- The "rest_position" attribute in the mesh modifier stack
- Instance on Points node
- Instances to points node
- Mesh to points node
- Points to vertices node

Many files are affected because in order to include the new information
in the API's returned data, I had to switch a bunch of types from
`VArray` to `AttributeReader`. This generally makes sense anyway, since
it allows retrieving the domain, which wasn't possible before in some
cases. I overloaded the `*` deference operator for some syntactic sugar
to avoid the (very ugly) `.varray` that would be necessary otherwise.

Pull Request: https://projects.blender.org/blender/blender/pulls/107059
2023-04-19 11:21:06 +02:00
Hans Goudey
ab8acbbfe5 Cleanup: Use curve positions accessor function
There's no particular reason to use the attribute API instead here.
2023-04-17 23:38:10 -04:00
Hans Goudey
c234a802ba Cleanup: Remove unused using keyword 2023-04-17 23:38:10 -04:00
Hans Goudey
2a4323c2f5 Mesh: Move edges to a generic attribute
Implements #95966, as the final step of #95965.

This commit changes the storage of mesh edge vertex indices from the
`MEdge` type to the generic `int2` attribute type. This follows the
general design for geometry and the attribute system, where the data
storage type and the usage semantics are separated.

The main benefit of the change is reduced memory usage-- the
requirements of storing mesh edges is reduced by 1/3. For example,
this saves 8MB on a 1 million vertex grid. This also gives performance
benefits to any memory-bound mesh processing algorithm that uses edges.

Another benefit is that all of the edge's vertex indices are
contiguous. In a few cases, it's helpful to process all of them as
`Span<int>` rather than `Span<int2>`. Similarly, the type is more
likely to match a generic format used by a library, or code that
shouldn't know about specific Blender `Mesh` types.

Various Notes:
- The `.edge_verts` name is used to reflect a mapping between domains,
  similar to `.corner_verts`, etc. The period means that it the data
  shouldn't change arbitrarily by the user or procedural operations.
- `edge[0]` is now used instead of `edge.v1`
- Signed integers are used instead of unsigned to reduce the mixing
  of signed-ness, which can be error prone.
- All of the previously used core mesh data types (`MVert`, `MEdge`,
  `MLoop`, `MPoly` are now deprecated. Only generic types are used).
- The `vec2i` DNA type is used in the few C files where necessary.

Pull Request: https://projects.blender.org/blender/blender/pulls/106638
2023-04-17 13:47:41 +02:00
illua1
15f464019a Geometry Nodes: avoid last buffer copy in Blur Attribute node
Previously, there was a "main" and "tmp" buffer and the final
result was expected to be in the "main" buffer. Now the two buffers
are called a and b and the final result can be in either of those.

This can improve performance especially if the number of iterations is low.

Pull Request: https://projects.blender.org/blender/blender/pulls/106860
2023-04-17 08:08:46 +02:00
Erik Abrahamsson
2fade47a9d Fix: Transform geometry node doesn't translate volumes correctly
Fixes a bug introduced in b0b9e746fa.
The volume transformation matrix is multiplied in the wrong order
which means the grid scale is applied on the translation.
2023-04-17 03:10:40 +02:00
Hans Goudey
dcb3b1c1f9 Geometry: Use implicit sharing for curve and mesh offsets
Similar to 7eee378ecc, this change decreases memory usage and
improves performance when copying curves and meshes without changing
their topology. The same change used for custom data layers is applied
to face and curve offset indices, which aren't stored as a custom data
layer.

The implicit sharing info for the offsets is stored in the mesh and
curve runtime structs, since it doesn't need to be written to files
directly. When changing the offsets pointer directly, the sharing info
must be updated accordingly. To make that easier, a few utility
functions take care of common operations like making an array mutable,
resizing an array, and creating sharing info for allocated data.

This commit also clarifies the intention to not allocate the offsets
at all when there are no curves/faces. That slightly complicates some
of the logic, but there's no reason for the single `0` integer to be
allocated.

Pull Request: https://projects.blender.org/blender/blender/pulls/106907
2023-04-14 17:58:13 +02:00
Hans Goudey
80f3f59555 Fix: Remove unsupported data types in extrude and split edges nodes
The extrude node resizes an existing mesh, but doesn't initialize new
data for most non-generic data types like shape keys or freestyle tags,
or custom normals. The split edges node doesn't process some
similar vertex data too.

In the future this data can become generic attributes, or it can be
supported in the nodes anyway. But now the new data is un-initialized
after being allocated.

Fixes #106926
2023-04-14 10:06:48 -04:00
Hans Goudey
197e9b9f80 Cleanup: Use more descriptive function name in extrude node 2023-04-13 12:49:16 -04:00
Hans Goudey
a7bee90c1d Cleanup: Add access method for point cloud positions
The position attribute has special meaning for point clouds, and
meshes and curves have access methods for the attribute as well.
This saves boilerplate and gives more consistency between types.
2023-04-13 12:49:16 -04:00
Campbell Barton
61cb302dd5 Cleanup: sort cmake file lists 2023-04-13 13:14:11 +10:00
Hans Goudey
16de3ba759 Fix #106845: Extrude node crash when no faces added
The non-individual face mode needs to check if there are any new faces
before accumulating their corner offsets.
2023-04-12 15:40:55 -04:00
Damien Picard
5cf365554b I18n: disambiguate a few messages
- "Lens" can be a transparent object used in cameras, or specifically
  its property of focal length
- "Empty" can be an adjective meaning void, or an object type. The
  latter is already disambiguated using `ID_ID`
- "New" and "Old" are adjectives that can have agreements in some
  languages
- "Modified" is an adjective that can have agreement in some languages
- "Clipping" can be a property of a camera, or a behavior of the
  mirror modifier
- "Value" in HSV nodes, see #105113
- "Area" in the Face Area geometry node, can mean a measurement or a
  window type
- "New" is an adjective that can have agreement
- "Tab" can be a UI element or a whitespace character
- "Volume" can mean a measurement or an object type. The latter is
  already disambiguated using `ID_ID`

These changes introduce the new `BLT_I18NCONTEXT_TIME` translation
context.

They also remove `BLT_I18NCONTEXT_VIRTUAL_REALITY`, which I added at
one point but then couldn't find which messages I wanted to fix with
it.

Ref #43295

Pull Request: #106718
2023-04-12 15:09:17 +02:00
Hans Goudey
4170545dc5 Fix #106828: Extrude individual mode crash on mesh with no faces
Caused by 7966cd16d6
2023-04-11 15:34:03 -04:00