The grid Poisson solver node solves `Poisson's equation, which relates
the value of each grid voxel to its neighbors. The result is an output
grid that produces the input grid when the Laplace operator is applied
(sum of gradient contributions from surrounding voxels).
In addition to the source values of the input grid the solution also
depends on boundary conditions at the edge of the solution space.
The default condition enforces a solution value of zero at the boundary
everywhere. Other modes allow enforcing custom fixed values
(Dirichlet condition), or custom gradient values of the resulting
function (Neumann condition), or a combination of both ("Mixed" boundary
condition).
The node is based around the OpenVDB Poisson solver. The solution is
computed on the active values of the input grid. Voxel faces between
active and inactive voxels form the boundary. Technically each face
could have its own boundary conditions, but for practical reasons the
conditions are evaluated at all inactive voxels bordering on the active
solution space (i.e. a 1-voxel dilation of the input grid). This means
all boundary voxels share the same condition, which is an acceptable
limitation for common Poisson problems.
Pull Request: https://projects.blender.org/blender/blender/pulls/163484
Allows to control type of point cloud processed or generated by
geometry nodes. The type could either be Points or 3D Gaussian Splat.
The type is set to the entire point cloud geometry component and
currently it affects how this component will be handled by render
engines.
The behavior is similar to changing the Point Cloud Type in the
properties panel: the node just sets the type. No changes to the
attributes is performed by this node.
Ref #159470
Pull Request: https://projects.blender.org/blender/blender/pulls/163530
A straightforward node that accepts file path to an SPZ file and
outputs point cloud of type 3D Gaussian Splats.
The node performs conversion from the SPZ coordinate convention
to Blender coordinate convention. Note that this convention is not
always followed by all assets on the Internet. The unfortunate part
is that it is not trivial to convert the coordinate systems as the
spherical harmonics attribute requires special handling.
For the efficiency extra parameters might need to be added to the
node. Or, alternatively, spherical harmonics need to become a
native attribute type, so that we can have transform nodes applied
on them.
Ref #159470
This adds the `Combine List` node - which creates a list from the dynamic
number of input items on the node. Several nodes are currently required
to create lists of any size or complexity. This greatly simplifies the
creation of lists for smaller lists that currently all require a
` * to List` node and several others.
Pull Request: https://projects.blender.org/blender/blender/pulls/160345
This adds a new simple node which retrieves the X, Y or Z component of a vector
by index. This is simpler and more efficient than using workarounds like using a
Separate XYZ with an Index Switch node.
The original motivation for this node came from #149091 where we wanted to
support this using expressions (`vector[i]`).
Co-authored-by: Tibo Stans <stanstibo@gmail.com>
This adds a new `Geometry Materials` node that can get the list of materials from any geometry component that has them (i.e., Mesh, Point Cloud, Curve, Grease Pencil).
<img width="259" alt="image.png" src="attachments/f2742cdf-aef1-443c-a41e-0809c7430f0b">
This is a follow up to a PR that I closed about a half year ago (https://projects.blender.org/blender/blender/pulls/144628) now that lists are out of experimental!
Pull Request: https://projects.blender.org/blender/blender/pulls/161451
---------
Co-authored-by: Colin Basnett <5035660+cmbasnett@users.noreply.github.com>
Creates volume grids from point data using rasterization.
Each point value is added to surrounding grid voxels using
a weighting function. This mirrors the _Sample Grid_ node,
which accumulates grid values into point attributes using the
same weighting functions.
Supported weighting functions:
- Nearest Point (1 voxel, aka. "point sampler")
- Linear (2 voxels, aka. "box sampler")
- Quadratic (3 voxels)
- Cubic (4 voxels)
Multiple output grids can be created using different input
fields, using the same kernel function. This allows sorting points
by grid voxel to determine the range of affected voxels efficiently.
Scalar and Vector type fields/grids are supported currently.
Integer and Boolean grid outputs are not directly supported
since the weights cannot be applied in general (except using
the nearest-point weighting mode).
This feature is a critical component of hybrid particle/grid simulations
where information is transferred from particles to grids and back,
such as FLIP fluid simulations. Existing methods of point-to-grid
conversion such as spherical SDFs are not suitable for this purpose.
Pull Request: https://projects.blender.org/blender/blender/pulls/160330
Shader Nodes
- Split Bundle and Closure nodes in their own subsections.
Geometry Nodes
- Reorder certain nodes.
- e.g. `Bone Info`, `Is Edge Smooth`, `Gamma`, `Implicit Conversion`
- Create subsection for tool-specific `Geometry > Read` nodes.
- e.g. `Active Element`, `Selection`
- Create subsection for switch nodes.
- Split the Bundle menu into multiple subsections.
Compositor
- Reorder `Mask to SDF` & `Implicit Conversion`
- Create subsection for switch nodes.
- Make order of `Utilities` submenus consistent with Geometry Nodes.
Pull Request: https://projects.blender.org/blender/blender/pulls/154596
## Translate Typed Bundle entry from node add menu
"Typed Bundle" is a special menu entry to add bundles. It was not
extracted because the `typed_bundle` method is not handled
automatically.
This commit simply adds the `n_` extraction function around the
string. Translation happens later, inside `node_operator`.
## Do not translate node label on declaration, but in UI layout
The `node_operator` method inside `NodeMenu` is used to declare node
menu entries. It can take a label as argument, or fall back on the
node's name. If the name is not found, it falls back on "Unknown".
Translation can be enabled or not in the method, depending on whether
it's handled on the call site. If no label is passed in, it should be
translated so translation is now enabled in that case in the UI layout
method.
But since translation is enabled in UI layout, it shouldn't happen
before, so this commit also replaces `iface_` with `n_` (simple
message extraction, no translation).
Pull Request: https://projects.blender.org/blender/blender/pulls/160788
Boolean combination of grid topology. The result is a grid with active
voxels or tiles where at least one of the input grids has an active
voxel, depending on mode. This combines grids in index space, all grids
should have the same transform.
Supports different boolean combination modes:
- Intersection: creates active voxels where _all_ input grids have
active voxels.
- Union: creates active voxels where _any_ input grid has an active
voxel.
- Difference: creates active voxel where the first input grid is active
but none of the secondary input grids are active.
The value of the output grid voxels is based on the first input grid
and discards values of any secondary grids. In _Union_ mode any voxels
that are not active in the first grid are initialized with its
background value.
Pull Request: https://projects.blender.org/blender/blender/pulls/159849
Deactivates any active grid voxel or tile where the _Selection_ input
field evaluates to _true_. It does not change the state of inactive
voxels.
This allows changing the topology of grids directly by "deleting"
voxels, similar to the _Delete Geometry_ node for other geometry.
The field evaluation is similar to the _Field to Grid_ node, but is used
to change the active state of voxels instead of their value.
Pull Request: https://projects.blender.org/blender/blender/pulls/159846
This adds a new `Sort List` node for changing the ordering of items in a list.
It moves the interface and sorting code from `Sort Elements` node into the
shared `GEO_reorder.hh` to re-use the same interface code. The interface is then
the same as the `Sort Elements` but selecting a list data type instead of a
domain. **Selection**, **Group ID** and **Sort Weight** can all be either single
values, fields or lists of values.
Co-authored-by: Hans Goudey <hans@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/159014
This is for a Bevel Geometry node. The code is a kind of port of the BMesh bevel code in bmesh_bevel.cc, but it needs substantial changes to use Mesh data structures instead of BMesh ones. And therefore, it needs to deal with the fact the the Mesh is not efficiently mutable. The approach is to make an "ExtendibleMesh" that holds data about the original Mesh but also deltas to that mesh to be applied at new Mesh construction time. Many other changes in the code were needed to use ints for Vert, Edge, Face, and Corner instead of pointers to BMesh elements.
In designing the Geometry Node, we made some decisions about some changes to the interface as compared to the BMesh interface to bevel. These were discussed in issue #98674. Some of the bigger decisions:
- Offsets are given per edge (4 of them, one for each side of each end) or per vertex (only the first slot is used) depending on whether we are edge beveling or vertex beveling. There is no "offset kind" spec -- you can achieve kinds other than "offset" by calculating outside the node.
- Miters are both simplfied and expanded. There is a boolean per corner called "miter". If it is true, and the given corner is just past a beveled edge, then the gap between that beveled edge and the next will be mitered. It will be in "patch" miter if the angle is reflect and an "arc" miter otherwise.
- So far there is no "clamp" and "loop slide" option. I remain undecided about what to do here. The eventual hope is that "clamp" will go away because I will use a "straight skeleton" algorithm to "eat away" geometry when it starts to overlap. But this won't happen in time for the intitial release. For now, I may implement clamp as "always on", but this isn't yet implemented. Loop slide can be done by calculation of offsets outside the node, but this could be tedious. I may or may not decide to implement loop slide inside the node; if I do, maybe it will be "always on" -- not sure.
- There is an "effect Faces" option in the UI but it isn't hooked up to anything yet. I'll probably disable that for the first release. Eventually I want to have it, as kind of inset operator.
- There is a "profile" input, meant to take a curve, that will be used for custom profiles, but that is not hooked up to anything yet.
- There are output fields, not yet hooked up, which will give selections of various parts of the new beveled mesh, to be used for things like special materials or normal handling. (As a consequence, there will be no hardening code native to this node.)
The state of the code as of this initial WIP is that many things work (with the exceptions noted above re clamping and loop slide and custom profiles). There are about 70 regression tests, ported from the bevel_operator.py tests (with more UV maps). They all "pass" right now but that's just because I made the expected_object match the current code output. I still have to go through them carefully one-by-one to see that they match the current BMesh behavior.
I added reviewers but this isn't really in a state to review yet, unless you are interested.
One thing I intend to do: update all the "old-style" math functions (that use raw float arrays) to "new-style" math functions.
This code was heavily assisted using Claude Sonnet 4.6 in Antigravity. But I have carefully read the output and will continue to do so, and will stand by the code as if it were totally my own (and, since I wrote the original BMesh code, it is in that sense mostly mine anyway).
Co-authored-by: Hans Goudey <hans@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/158151
This exposes a bunch of new things by default:
* Hair Dynamics node group (with an experimental option to use physics).
* Cloth Dynamics (Experimental) node group.
* Experimental built-in XPBD Solver node.
* Tag Filter node.
* Typed Bundle entry in add menu.
* Get Nested Bundle Paths node.
More information on these will be available in the release notes and docs.
Additionally, this updates the behavior of the Empty Hair operator which creates
a new hair curves object which is attached to the selected surface. It now uses
the Hair Dynamics group. The procedural hair assets have been updated to work
well with it in e10a50f890.
Note: While the experimental option is removed, some of these new features are
still intentionally marked as experimental in the UI. This is not because these
are unstable, but because we need more widespread testing of the design before
being able to guarantee our normal compatibility guarantees. It's expected that
they won't be experimental after one release anymore, ideally without any
compatibility breakages but it's hard to be sure at this point.
Pull Request: https://projects.blender.org/blender/blender/pulls/159493
This adds a `Set String Case` node which changes the case of the input string,
with current options being `Uppercase` and `Lowercase` which change _all
characters_ in the string to the corresponding case.
There is potential to support other case changes such as `Title Case`, but this
simpler node can be added now and those extra formats added later.
Pull Request: https://projects.blender.org/blender/blender/pulls/158580
This PR adds a **Closure to List** node, which can create lists of
geometries, strings, grids, etc. The closure is evaluated once per
index, and creates list elements for each of the node's list outputs.
Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/145984
This makes the Transfer Attributes node available by default. It was originally
developed for the hair dynamics project to copy over the simulated attributes
(like position) onto the static geometry. While transferring individual
attributes with e.g. the Sample Index node is already possible, this node is
more flexible because:
* It allows transferring a dynamic number of attributes, based on a list of name
patterns.
* The attributes can have different data types.
* One can easily use custom IDs to map elements from one geometry to another.
* The node is optimized for various special cases. Importantly, under certain
conditions, the node can be O(1) per attribute because of implicit sharing or
because of single-value attributes.
* It can propagate anonymous attributes.
The basic behavior is that for each given attribute name, it first determines
the domain on the source geometry, then looks at the corresponding IDs on the
source and target geometries. If an element on the target has an id that matches
an id on the source, the value is copied over. If the target has IDs that are
not available on the source, the data remains unchanged or gets the default
value if the attribute didn't exist before.
By default, all ID inputs are the index field. In this configuration it can
easily transfer any attributes between geometries with the same topology
The output contains the names or all transferred attributes except for internal
attributes.
The topology of the target geometry remains unchanged. Only top-level attributes
are transferred, nested instances are ignored.
The `Exclude Names` option can be used to invert the patterns. When true, all
attributes not matching any of the given names are transferred.
In the future, there may be more way to generically handle attributes with
different types but this requires a couple features for Geometry Nodes that we
don't have yet (like "rainbow sockets" which can dynamically change their type).
Pull Request: https://projects.blender.org/blender/blender/pulls/159181
This enables support for storing bundles in geometries by default. This provides
the ability to store arbitrary data on a geometry set, allowing it to be passed
whereever the geometry is passed, including across object boundaries.
This opens up significant new opportunities for building declarative systems
where the overall behavior is controlled by multiple objects. For example, it
allows creating force field objects which can be fed into simulation systems.
The geometry bundles can generally store all kinds of data that is supported by
geometry nodes, including fields, closures, other bundles and other geometry.
One notable exception is that anonymous attributes are removed as geometry
leaves geometry nodes, aka at the end of the evaluation of each modifier. This
constraint is necessary currently, because the lifetimes of these attributes
can't be tracked reliably outside of Geometry Nodes.
This adds two new nodes:
* Set Geometry Bundle: Updates the bundle stored in the geometry. If there was a
bundle already, the old one is discarded.
* Get Geometry Bundle: Retrieve the bundle in a geometry, optionally removing it
from the geometry.
Pull Request: https://projects.blender.org/blender/blender/pulls/159175
A simple node to remove some items from a list. The predicate
for removal is provided in the form of either a boolean field or
a boolean list.
---

Pull Request: https://projects.blender.org/blender/blender/pulls/158859
Previously, getting an individual geometry component required the use of the the
Separate Components node. It always split all components into separate
geometries. However, a common workflow is to extract one component, modify it
and to then merge it back. The current approach forces the node group to
explicitly handle all geometry types instead of just the one it is interested
in.
This patch adds a new Get Geometry Component node to more directly express the
intent. Furthermore, it allows simple checking if a geometry has a specific
component.
The design of the node is similar to nodes like `Get Bundle Item` and `Get
Geometry Bundle`.
Pull Request: https://projects.blender.org/blender/blender/pulls/158177
Add a Reverse String node, which reverses the given input string.
This could be done previously with a repeat zone, but a built-in
node is much more performant, for this somewhat common operation.
Pull Request: https://projects.blender.org/blender/blender/pulls/158387
This adds new **experimental** built-in nodes and a couple of node group assets
which allow simulating hair curves and are fundamental building blocks for more
physics systems in the future.
At the highest level, there is a new "Hair Dynamics" asset which can be used as
modifier or as a node. It takes in hair curves with their corresponding surface
geometry and animates/simulates them based on the surface movement and other
effectors.
This is a fairly large node group which sets up a simulation world bundle that
ends up being passed to the new built-in "XPBD Solver" node. This node actually
updates the position, rotation, velocity and angular velocity attributes based
on the passed in constraints and forces. Note that this node generally needs
some setup like pre-evaluated fields and should generally be used as part of a
node group.
### World Bundle
The constraints as well as the simulated geometry are passed to the solver node
in form of a "world bundle". This bundle declaratively describes what the
physics system looks like.
It is a potentially potentially deeply nested bundle which contains so called
"typed bundles". The typed bundles correspond to specific constraint types based
on their type. Besides typed bundles, it also contains geometries which are
simulated.
Due to their generic nature (just a bundle), world bundles can be composed from
other bundles. For example, it is common to combine multiple
effectors/constraints into one bundle which is then added to the world bundle at
once. Objects can also "export" bundles on the geometry like force fields or
other constraints which can then be passed into the simulation on another
object.
### Constraint Types
The following constraint types are currently supported in the XPBD Solver node:
* Mesh colliders: Handles general collisions with closed(!) meshes.
* Infinite plane colliders: Can handle e.g. an infinite ground plane
efficiently.
* Damping: General damping of linear and angular velocities to increase
stability.
* Pin Position: Explicitly pin the position of individual points. Used for hair
root points.
* Pin Rotation: Explicitly pin the rotation of individual points/segments. Used
for hair root points.
* Rod Stretch/Shear: Attempts to maintain a specific rest length of a curve
segment (stretch) and ensures that the rotation of the segment aligns with
point positions (shear).
* Rod Bend/Twist: Attempts to maintain a specific rotation between neighboring
segments.
* Edge Length: Constrains the length of mesh edges to a given rest length.
* Cross Edge Length: A cheap bending constraint that works by adding a distance
constraint of two vertices opposite an edge.
Most of these constraints also have a compliance value. It indicates how much
the constraint is allowed to be broken. A value of zero means that the contraint
should be perfectly maintained. Sometimes this cannot be achieved due to too few
substeps or constraint steps, or because the way the system is setup makes it
impossible. Since this is a very non-linear value, it is generally exposed as a
"softness" value between 0 and 1 (although technically there is no upper limit).
It's also named e.g. "Bendiness" or "Stretchiness" depending on the context.
### Other New Nodes
Besides the solver node, there are two additional new built-in nodes. These are
required to build the higher level assets.
* Transfer Attributes: Allows copying all or a subset of attributes from one
geometry to another using custom ids on each domain for the mapping.
Importantly, this is even capable of transferring anonymous attributes.
* Tag Filter: A simple node that takes a list of tags and a filter string and
checks if the filter matches the tag list. Currently, only a comma separated
list is allowed as filter but a slightly more complex syntax may be supported
in the future. The goal is to be able to reuse the same syntax across
different tagging systems in Blender.
### Field Pre-evaluation
The XPBD Solver node does not evaluate any fields itself currently. Instead it
relies on other nodes to pre-evaluate these fields and to write them in specific
named attributes for easy consumption.
Besides simplifying the solver, this appears to be necessary to cleanly support
constraints which are interpolated across the substeps like pinning constraints.
For those, the solver not only needs the current pin position, but also the pin
position from the previous time step. Doing this attribute handling entirely
outside of the solver node allows it to be used more ways.
Two different kinds of pre-evaluations are necessary:
* Hard-coded attribute names: The solver reads from (and sometimes writes to)
these hard-coded attribute names directly. This includes `position`,
`velocity`, `rotation`, `angular_velocity`, `external_force`,
`external_torque`, `mass`, `moment_of_inertia`, `static_friction`,
`dynamic_friction`, `radius`.
* Effector specific attributes: Some effectors (like the Pin Position
constraint) needs additional attributes on the geometries it affects. In this
specific case, it's necessary to know for the current and previous frame which
points are pinned and where (and that per constraint when there are multiple).
* The used naming convention for these attributes is:
`sim:prop:{effector_path}:{property_name}` (e.g. `sim:prop:Hair/Pin
Position:selection`). The effector path is the bundle path starting at the
root bundle.
* The data from the previous frame is stored with a very similar naming
convention: `sim::prop_prev:{effector_path}:{property_name}`.
* Note that outside of building fully custom simulation systems, the user is
never expected to deal with these attributes manually. This is entirely
handled in existing node groups.
### Todos before release
Before this is released, a few things need to be done:
* New node group assets still need to be finalized, especially with respect to
the surface geometry and forces.
* The already existing hair assets need to be updated too.
* The operator to set up hair needs to be updated.
Co-authored-by: Lukas Tönne <lukas@blender.org>
Co-authored-by: Hans Goudey <hans@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/154435
This PR adds the `Get Attribute Names` node to retrieve attribute names
as a list of strings. The attributes can be filtered by domain and data
type. Filters for both can be disabled.
Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/134760
The main goal of this PR is to add the ability to replace the Merge by
Distance node with customizable node groups built on top of smaller and
more generic building blocks. The main part of that plan is the Merge
Points node which works with the Group ID of vertices so merging
geometry can be defined directly by the selection, indices and groups,
without the need for the current workaround of changing positions and
dealing with floating point precision issues at far coordinates in order
to avoid false positive merges.
In addition to just editing of the mesh and the point cloud, this PR
also adds a pair of nodes to reproduce "by Distance" part. The Cluster
by Distance node works similarly to Index of Nearest but instead of
knowing local most nearest elements, now each point knows the ID of the
cluster of some size it belongs to. Internally this is done in non-
trivial way which is hard to reproduce as user level currently. And both
optimizations and different algorithms for that problem can be add later.
The other new node, Cluster by Connected, is currently just designed to
replace the "Connected Only" feature of the Merge by Distance node.
From performance side this change does not have a large impact. The main
bottleneck is the mesh merge part (clusterization cost is smaller).
Co-authored-by: Hans Goudey <hans@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/151978
Specialized nodes for constructing bundles with a "Type" item. The type
can be any string, but a number of known types can be registered in
advance to support string search.
Typed bundles can be searched using the `Get Nested Bundle Paths` node,
which returns a list of bundle paths with matching type. Nested bundles
can also be searched.
This will be used by the future hair dynamics feature to support
declarative physics components. New nodes are hidden behind the
experimental hair dynamics feature flag for the time being.
Pull Request: https://projects.blender.org/blender/blender/pulls/158043
Compared to the ultimate goal for lists including list fields and
support in many more places, lists are still quite young, but as-is they
add valuable functionality and are used for the hair simulation code
that we hope to start landing soon. This makes these nodes available:
- Field to List
- Get List Item
- List Length
- Split String
- Collection Children
Pull Request: https://projects.blender.org/blender/blender/pulls/157301
This PR adds the Instance Reference Index geometry node, which outputs
the .reference_index attribute as an integer field. This is useful for
identifying instances with shared geometry sets.
Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/155492
This adds a new node which allows getting frequency information from sound
directly inside of Geometry Nodes, making baking to f-curves unnecessary.
This is a new implementation, but it is significantly inspired by #122228 and
also builds on top of some of the changes that landed during the GSOC project
already (like `PROP_FREQUENCY`).
This also exposes the new sound socket types. Note that just by loading the
sound into Geometry Nodes, it is not played back. It needs to be added to e.g.
the sequencer too.
Pull Request: https://projects.blender.org/blender/blender/pulls/156247
When adding an Integer Math node, the inputs are initialized to 1 or 0
depending on the operation.
Defaults:
1st and 2nd inputs set to 1:
- Multiply
- Divide
- Divide Round
- Divide Floor
- Divide Ceil
- Floored Modulo
- Modulo
1st input to 1, 2nd to 0:
- Multiply Add
Pull Request: https://projects.blender.org/blender/blender/pulls/156823
This PR adds a new node that renames an attribute or changes the prefix
of many attributes. The internal implementation of attribute renaming is
also changed so that it no longer has quadratic cost when renaming many
attributes. Previously it was implemented by removing and adding
each attribute. Unfortunately the combination of vertex groups and
attributes makes this a bit complicated.
Adding a test file I also found a bug in the realize instances vertex
group name joining code which is fixed here too.
Pull Request: https://projects.blender.org/blender/blender/pulls/156328
Follow-up to c01b317f14
Initialize new math node with reasonable defaults depending on the
operation.
## Defaults:
### 1st and 2nd input defaults to 1:
- Multiply
- Multiply Add
- Power
- Truncated modulo
- Floored modulo
- Modulo
- Artan2
### 1st and 2nd input defaults to 0:
- Add
### 1st input defaults to 1, 2nd to 0:
- Subtract (`1 - x` are more common for subtraction)
### 2nd input set to 1, 3rd input defaults to 0:
- Multiply Add
Pull Request: https://projects.blender.org/blender/blender/pulls/155879
This adds a new Trim String node. It removes specific characters at the
beginning and end of a string. Most often this is used to remove unnecessary
whitespace but it can be used with other characters too.
Since it's the most common use-case, and it's tricky to type in manually, there
is a special "Whitespace" option on the node which includes spaces, newlines,
tabs and carriage-return (` \t\n\r`).
I originally used this while working on the physics system to "fix" tag names
provided by the user in a comma-separated-list.
Pull Request: https://projects.blender.org/blender/blender/pulls/154465
This splits a string at a given separator and outputs a list of substrings. This
node is still experimental for as long as lists are.
I originally used this in the physics branch to split a comma separated string
of tags into a list of tags.
Pull Request: https://projects.blender.org/blender/blender/pulls/154468
Pablo Vazquez spotted the issue with the name immediately using "curve"
when it applies just to NURBS curves. Even though `Set Handle Positions`
and `Set Handle Type` also have an implicit curve type, the word "order"
makes it even more confusing in our case.
Pull Request: https://projects.blender.org/blender/blender/pulls/155164
Input "Constant" nodes for missing socket data types:
- `Font` ID data blocks
- `Menu` enum values
The Font input node is initialized with the default font, just like font
input sockets generally are.
Co-authored-by: Sergey Sharybin <sergey@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/154318
Simple generic type conversion nodes that implicitly convert the input
to a specific data type.
These nodes are conceptually similar to _Reroute_ nodes, except with a
fixed, selectable data type. They can be useful for forcing a node
socket to be converted to a given data type, instead of just relying on
the source and target types. This will be needed for improving the
_ungroup_ operator, which can then preserve the behavior of the
original node group interface sockets (#151432).
Pull Request: https://projects.blender.org/blender/blender/pulls/154497
This patch adds a Collection Children node that outputs object and collection
lists from a specified collection either directly or recursively.
Since this node outputs lists, it's still an experimental feature for as long as
lists are.
Pull Request: https://projects.blender.org/blender/blender/pulls/150923
This PR adds a new node to clip an input grid based on an min and max indices.
Voxels outside of the bounding box are deactivated and their values set to the
background value for the grid. If a tile is partially clipped it is fully
voxelised before relevant voxels being clipped.
There are performance issues for calling `.clip()` with large clipping bounding
boxes, but this issue is solved by first calling `.intersect()` on the active
bounding box so that clipping only happens on a relevantly-sized bounding box.
Pull Request: https://projects.blender.org/blender/blender/pulls/153809
This adds a new Grid to Points node. Each active tile or voxel is turned into a
point. The voxel value is stored as an anonymous attribute on the points and is
output as field. Additionally, information about each voxel or tile in index
space is provided.
This is very useful for building custom volume grid visualizations or just to
further process the voxel values as points. Even in case we get better built-in
ways to debug grids there is always a need to build custom visualizations for
specific purposes. This node is a great building block to build these.
Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/153664
This PR exposes the OpenVDB `mean` and `median` filters for regular grids.
These filters are similar but distinct to the SDF Filter operations. These
filters also support the integer and float grids. Boolean is not supported as
these operations don't change those grid values at all. OpenVDB also has the
`gaussian` filter, but is defined as just 4 iterations of the `mean` so is
omitted from these nodes.
Pull Request: https://projects.blender.org/blender/blender/pulls/147433
This PR exposes the OpenVDB dilate & erode operations as a single node.
This node importantly _only_ affects the active state of voxels, and does not
change their values at all. Dilating does expand the number of active voxels.
It is of particular use in combination with the _Advect Grid_ node. A common
source of frustration from users is that the velocity grid has to be slightly
larger than the value grid for advection to work properly. Dilating the grid
before advection is the approach taken by the crurrent "Volume Displace"
modifier.
### Value of newly activated voxels
When dilating, previously inactive voxels become active. There is some subtlety
in what value these voxels have after the node. In openvdb grids, inactive
voxels can have values stored which are different from the background value
(although when sampling them, they will appear to have the background value).
When a previously inactive voxel becomes active again, it will get the value
which was stored for it previously. Often that is the background value, but not
always. For example, when first eroding a grid with noise values and then
dilating it again, these noise values will still be there (unless an entire tile
was eroded in which case it is removed). If one wants to ensure that the newly
active voxels have the background value, one needs to make sure that the
inactive voxel values are properly set. This can be done with a slightly updated
Set Grid Background (#153525) node that can force-override all inactive values
in the grid.
In the future, the node could support writing an explicit value to each newly
activated voxel, or it could output a topology grid containing the voxels which
have changed active status. This comes with a fair amount of overhead and is not
necessary for many use-cases, so it's not implemented for now.
Pull Request: https://projects.blender.org/blender/blender/pulls/147430
Adds the 'Cube Grid Topology' node. The output is a boolean grid that is dense.
Intended for usage with the _Field to Grid_ node to create arbitrary grids
without the need for the _Volume Cube_ or _Get Named Grid_ nodes.
Resolution determines how many voxels for each axis become active, and the
`Min *` values determine an offset in the voxel space where the voxels start
becoming active. It doesn't displace the active grid in object space because of
the bounds apply a transform, but removing that transform can show where in
index space the voxels are active.
The 'Bounds' are ultimately optional as a user might want to set a custom
transform with the _Set Grid Transform_ node but are still included for
convenience.
Pull Request: https://projects.blender.org/blender/blender/pulls/146933