WIP: Volume Grid Nodes #116021

Draft
Lukas Tönne wants to merge 226 commits from LukasTonne/blender:volume-grid-nodes into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Member

Various nodes for volume grids using the new grid sockets (#115270).

This is an experimental branch. The nodes will be reviewed and merged into main as separate PRs.

General Issues

  • Many nodes work only on topology and don't care about the voxel values at all. They currently still need a data type selector to declare a concrete socket type. The "rainbow" socket should eventually make this unnecessary.
  • Only float and vector (float3) socket types are supported for grids currently. This is to keep boilerplate code to a minimum while testing core code changes. Eventually all the possible socket/grid types should be supported.
  • Grid sockets are currently not implicitly converted. It's possible to connect a vector to a float grid socket and the node won't work because the grid casting produces nullptr.

Set Grid Value

Replace a grid values by capturing a field, keeping topology unchanged.
image

Primitive grids (Cube, Sphere, etc.) can be constructed by capturing a value like this node does, or they could be value-less mask grids which just define topology. The Set Grid Value node can then be used to combine such primitives and give them a new value.

It can also be used to redefine the type of grids, for example taking the topology of a density volume and replacing voxel values with vectors.

Sample Grid

Output interpolated grid values as a field.
image
This is a re-implementation of the existing grid sampling node that does not require a Volume geometry.

Grid to Points

Convert grid voxel data into point cloud attributes.
This is mostly useful for debugging purposes until viewer nodes and spreadsheet integration are available.
Screenshot_20231215_181151

  • Many of the output attributes should eventually have equivalent input nodes in grid context. For example, the voxel coordinate is supposed to be accessible via a Grid Coordinate input node. These attributes can be propagated to the points output, similar to other geometry conversion nodes, removing the need for explicit output sockets.

Combine Grid Topology

Union/difference/intersection of active voxel states.
image

  • The "Grids" socket is supposed to be a multi-input, for parity with the Mesh Boolean node. This does not currently work because multi-inputs require a CPPType for Vector<ValueOrField<T>> which is not yet defined. Not sure if all the possible CPPTypes should be registered or if there is a more elegant solution.

Deactivate Voxels

Set voxel state to inactive based on value.
image

  • Node sockets reflect the OpenVDB function openvdb::tools::deactivate. Might be nicer to use a boolean selection field instead of always using value comparison.

Filter

Blurring-like filters for density grids: Mean, Median, Gaussian (blur), Offset
image

  • Modes are different enough that implementation as separate nodes could be preferable.
  • Offset mode is just adding to voxel values. This can be a simple math operation instead (but performance may be better this way). For SDF grids the Offset might be more complicated (confirm?).

Level Set Filter

Blurring-like filters for SDF grids: Mean, Mean Curvature, Median, Gaussian (blur), Offset, Laplacian
image

  • Why does the level-set function not have an iterations input like for density grids?

Dilate/Erode

image

Extrapolate Grid

Extend the boundary to the interior and/or exterior of a density or SDF grid. Copies the value of the closest boundary voxel.
image

Poisson Solver

Find a smooth gradient between values on the boundary.
image

Various nodes for volume grids using the new grid sockets (#115270). This is an experimental branch. The nodes will be reviewed and merged into main as separate PRs. ## General Issues - [ ] Many nodes work only on topology and don't care about the voxel values at all. They currently still need a data type selector to declare a concrete socket type. The "rainbow" socket should eventually make this unnecessary. - [ ] Only float and vector (float3) socket types are supported for grids currently. This is to keep boilerplate code to a minimum while testing core code changes. Eventually all the possible socket/grid types should be supported. - [ ] Grid sockets are currently not implicitly converted. It's possible to connect a vector to a float grid socket and the node won't work because the grid casting produces nullptr. ### Set Grid Value Replace a grid values by capturing a field, keeping topology unchanged. ![image](/attachments/b127f109-f17a-4e73-b6b5-a78e8be494ad) Primitive grids (Cube, Sphere, etc.) can be constructed by capturing a value like this node does, or they could be value-less mask grids which just define topology. The _Set Grid Value_ node can then be used to combine such primitives and give them a new value. It can also be used to redefine the type of grids, for example taking the topology of a density volume and replacing voxel values with vectors. ### Sample Grid Output interpolated grid values as a field. ![image](/attachments/d7797a37-a541-4b1d-9d63-7b94ccf8c170) This is a re-implementation of the existing grid sampling node that does not require a Volume geometry. ### Grid to Points Convert grid voxel data into point cloud attributes. This is mostly useful for debugging purposes until viewer nodes and spreadsheet integration are available. ![Screenshot_20231215_181151](/attachments/085034d6-61f7-4d40-b953-d737b9d9c8e6) - [ ] Many of the output attributes should eventually have equivalent input nodes in grid context. For example, the voxel coordinate is supposed to be accessible via a `Grid Coordinate` input node. These attributes can be propagated to the points output, similar to other geometry conversion nodes, removing the need for explicit output sockets. ### Combine Grid Topology Union/difference/intersection of active voxel states. ![image](/attachments/044da0e7-6612-4cac-9663-d127d3798b6d) - [ ] The "Grids" socket is supposed to be a multi-input, for parity with the Mesh Boolean node. This does not currently work because multi-inputs require a CPPType for `Vector<ValueOrField<T>>` which is not yet defined. Not sure if all the possible CPPTypes should be registered or if there is a more elegant solution. ### Deactivate Voxels Set voxel state to inactive based on value. ![image](/attachments/d026d950-bfb9-4e4a-9565-539715beb4be) - [ ] Node sockets reflect the OpenVDB function [openvdb::tools::deactivate](https://www.openvdb.org/documentation/doxygen/namespaceopenvdb_1_1v11__0_1_1tools.html#a95818e0902bf2d721182aea060c98a39). Might be nicer to use a boolean selection field instead of always using value comparison. ### Filter Blurring-like filters for density grids: Mean, Median, Gaussian (blur), Offset ![image](/attachments/61882826-9a81-4965-9b7d-f652e4b2d913) - [ ] Modes are different enough that implementation as separate nodes could be preferable. - [ ] _Offset_ mode is just adding to voxel values. This can be a simple math operation instead (but performance may be better this way). For SDF grids the Offset might be more complicated (confirm?). ### Level Set Filter Blurring-like filters for SDF grids: Mean, Mean Curvature, Median, Gaussian (blur), Offset, Laplacian ![image](/attachments/4f15ad2f-0c03-489c-acc5-03ab40eff9f6) - [ ] Why does the level-set function not have an iterations input like for density grids? ### Dilate/Erode ![image](/attachments/075a3a99-77dd-43e8-9a41-09be6f2c7eb4) ### Extrapolate Grid Extend the boundary to the interior and/or exterior of a density or SDF grid. Copies the value of the closest boundary voxel. ![image](/attachments/f0c3312c-cf13-454b-9853-2e7503c62782) ### Poisson Solver Find a smooth gradient between values on the boundary. ![image](/attachments/b03be664-d09d-471c-bda4-20a142ec0d78)
Lukas Tönne added 178 commits 2023-12-11 07:39:42 +01:00
7c87888c4a Use regular float/vector/etc. sockets to represent grids.
The socket value will be extended from ValueOrField to
"ValueOrFieldOrGrid" (with a nicer name). The data type is the same,
and the socket shape will be updated later when inferencing supports
grid data.
999b08ca3a Move ValueOrField into BKE.
This struct is used for geometry nodes sockets only and only used by
the geometry nodes module (with an indirect dependency via simulation
zone baking). It currently lives in the functions namespace, which is
problematic when adding grids in future, which should not be part of
the functions module.
e9d78c65b0 Added a Grid pointer to the ValueOrField struct.
This will be used for grid sockets to pass grid data at runtime.
The GridType is a forward-declared OpenVDB grid class, with a template
parameter that matches Blender math types and gets swapped with a
matching OpenVDB type for the actual grid.
9f45d22858 Use implicit sharing to create deep copies of grids when needed.
This allows branching from a node socket to multiple inputs.
bca4dffe22 Cleanup: Moved VolumeGrid into BKE_volume_grid.hh.
The BKE_grid_types header becomes BKE_volume_grid. The VolumeGrid struct
will be the main wrapper around openvdb::Grid. GVolumeGrid will be a
generic base class and VolumeGrid<T> the type variants.
021121382b Renamed VolumeGrid to GVolumeGrid as a generic grid wrapper.
VolumeGrid<T> will be a template for typed grid wrappers.
2f35ca5a91 Temp: Move VolumeGrid into bke namespace.
VolumeGrid -> blender::bke::GVolumeGrid

A type alias is added to existing volume code outside of bke working
with the existing type name. Unfortunately this does not work for RNA
where a plain C struct in the global namespace is needed.
cb88e6c113 Added dummy struct in RNA to act as a placeholder for GVolumeGrid.
DummyVolumeGrid is used as a stand-in for the actual VolumeGrid struct.
RNA callback wrappers around `rna_VolumeGrid_load` and
`rna_VolumeGrid_unload` need a C struct as the main "self" argument.
The struct does not have to be an actual DNA struct.
- VolumeGrid is a type alias ("using") that cannot be used directly for
  this purpose.
- blender::bke::GVolumeGrid is the actual struct but C++ namespaces also
  don't work.
This dummy struct is used as a placeholder for the callbacks and
reinterpreted as the actual VolumeGrid type.
0858c6992b Make VolumeGridCommon an ImplicitSharingMixing class.
This currently breaks storage of grids in Volume, because the std::list
will allocate and decallocate grids, which does not respect the user
count of implicit sharing. Have to change the container to use pointers.
b5741095cb Store ImplicitSharingPtr to grids in VolumeGridVector.
Implicit sharing means that grids should not be allocated and freed
by the grid vector, otherwise they will not get deallocated properly.
3b3cc31141 Fix unexpected data destruction by making constructor explicit.
The ImplicitSharingPtr had an implicit constructor for raw pointers.
This had unintended effects when comparing an ImplicitSharingPtr to a
raw pointer: The raw pointer was implicitly converted to the shared
pointer (without change in refcount) and when going out of scope would
decrement user count, eventually freeing the data.

Conversion from raw pointer to shared pointer should not happen
implicitly. The constructor is made explicit now. This requires a little
more boilerplate when constructing a sharing pointer. A special
constructor for the nullptr is added so comparison with nullptr can
still happen without writing out a constructor.
b2c9503996 Rename VolumeGrid type alias to GVolumeGrid.
This is to avoid name conflicts once the FieldValueGrid gets renamed.
d5a98e0079 Another wrapper type around openvdb grid pointers.
The type structure for VolumeGrid needs to change: Casting from a
generic GVolumeGrid to a typed VolumeGrid<T> and vice versa would mean
constructing a new instance, which means deep copies of data because the
VolumeGrid is not just a reference but the ImplicitSharingData itself.

To fix this the structure should be:
1. `SharedGrid<GridType>`: A wrapper around some openvdb::Grid (can be
    GridBase).
2. `VolumeGrid<T>`/`GVolumeGrid`: Stores a `ImplicitSharingPtr` to a
    `SharedGrid`.
3. `VolumeGridVector` goes back to storing the `VolumeGrid` themselves,
    no need for another indirection here.
d123afbd31 Revert "Store ImplicitSharingPtr to grids in VolumeGridVector."
This reverts commit b5741095cb.

VolumeGridVector now stores plain GVolumeGrid instances again instead of
ImplicitSharingPtr. The shared pointers will get moved inside the
VolumeGrid struct, so that they can be casted as lightweight wrappers
without having to do deep copies of the data.
1127ac2e61 Restructured volume grid data types to separate shared data and pointers.
The VolumeGrid class will become the primary ImplicitSharingData, while
the VolumeGridPtr<T> and GVolumeGridPtr are ImplicitSharingPtrs.
Casing only happens on the pointer side, otherwise the casting would
create a deep copy of the data each time.
31e07a3953 Catch OpenVDB exceptions when the ISO value is out of range.
This cannot easily be anticipated to avoid the error condition, so we
have to handle exceptions as best as possible.
0336ed9273 Fixed copy-on-write grids in dilate/erode nodes.
If the grid type is correct, `grid_for_write` should always return a
valid grid. Also have to make sure to output the new grid pointer
instead of just copying the existing input.
cbc52b3225 Fix Store Named Grid node with mutable VolumeGrid.
Volume API now has a "move" function for inserting an existing
VolumeGrid into the Volume. Store Named Grid node now creates a correct
mutable grid to store.
0bc33f3f88 Fix Store Named Grid node with mutable VolumeGrid.
Volume API now has a "move" function for inserting an existing
VolumeGrid into the Volume. Store Named Grid node now creates a correct
mutable grid to store.
3d5b151366 Increment user count in cast constructor instead of `typed()` method.
The constructor also becomes private since it shouldn't be called
outside of the downcast function.
9c83b3b515 Remove potential grid copy in VolumeGridPtr accessors.
The `grid`/`grid_for_write` getters are shortcuts to the internal
VolumeGrid data. They are useful because VolumeGrid is always un-typed,
so getting a typed openvdb::Grid from volume grid requires a second cast
to the type already known by VolumeGridPtr<T>. But the grid accessors
should work the same ways as accessing the openvdb::Grid from VolumeGrid
and leave copy-on-write to higher level methods.

VolumeGridPtr might be better off untyped, with typed grid accessors
inside VolumeGrid. But that is for a later change.
de674d2553 Return grid pointer directly when extracting grid inputs.
The `as_grid` function will construct an empty grid if none is present.
That is not usually what we want when extracting an input, since a
nullptr grid is a valid pointer and can be used as the default input.

For example, using a mask grid can be optional, and the input should be
a nullptr when no mask is used. With the as_grid method the result would
always be a (empty) grid rather than nullptr.
Lukas Tönne added a new dependency 2023-12-11 08:27:24 +01:00
Lukas Tönne added 2 commits 2023-12-11 09:53:31 +01:00
Lukas Tönne added 3 commits 2023-12-11 10:36:41 +01:00
7af2717b1c Remove potential grid copy in VolumeGridPtr accessors.
The `grid`/`grid_for_write` getters are shortcuts to the internal
VolumeGrid data. They are useful because VolumeGrid is always un-typed,
so getting a typed openvdb::Grid from volume grid requires a second cast
to the type already known by VolumeGridPtr<T>. But the grid accessors
should work the same ways as accessing the openvdb::Grid from VolumeGrid
and leave copy-on-write to higher level methods.

VolumeGridPtr might be better off untyped, with typed grid accessors
inside VolumeGrid. But that is for a later change.
0c788585ca Return grid pointer directly when extracting grid inputs.
The `as_grid` function will construct an empty grid if none is present.
That is not usually what we want when extracting an input, since a
nullptr grid is a valid pointer and can be used as the default input.

For example, using a mask grid can be optional, and the input should be
a nullptr when no mask is used. With the as_grid method the result would
always be a (empty) grid rather than nullptr.
Lukas Tönne added 11 commits 2023-12-15 11:20:26 +01:00
869cf6bb30 Reimplemented the file cache for volume grids.
The file cache stores VolumeGrid implicit sharing data now. It uses
a combination of file path, grid name, and the simplification leve as
the key. That way simplified grids can be handled as cached data without
complicated internal refcounting. Generated grids will not have cached
simplification, but that is expected and in line with other caching
systems in Blender.

The `is_loaded` flag has been replaced with a more explicit enum
`VolumeTreeSource` to make more transparent decisions about what should
happen to grids on load/unload, simplification, copy, etc.
6d7effb088 Unnamed grids are valid, ignore grid names in file cache keys.
This is to fix the blendfile_versioning test which loads a vdb file
with an unnamed grid.
2f2a784fbd Fix cycles test: Replace the grid when unloading instead of new tree.
Cycles "steals" the OpenVDB grid from the VolumeGrid when constructing
the scene and then unloads the grid again. This unloading was replacing
the tree pointer inside the grid, breaking cycles volume rendering.

Do what the old cache did and replace the entire OpenVDB grid in case
some code holds a reference to the pointer. This is not great but it
keeps things working.
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
6c8211baf2
Fix for USD volume bounds calculation, have to load the grid first.
This pattern is not at all ideal but currently common: Any code that
wants to access grid data has to call BKE_volume_grid_load first to
ensure that the potential grid placeholder gets the full tree data.

Like in other places (Cycles, viewport drawing) the code first checks
if the volume grid is a placeholder, and in that case unloads the grid
again after getting the bounds.

Eventually grids should automatically be loaded when accessing the
internal OpenVDB grid data. This would remove the need for
BKE_volume_grid_load, but it does not cover the case of automatic
unloading after use. Some transient struct that unloads a placeholder
grid after going out of scope might handle this.
Lukas Tönne added 1 commit 2023-12-15 11:27:01 +01:00
Lukas Tönne added 1 commit 2023-12-15 12:39:27 +01:00
Lukas Tönne added 1 commit 2023-12-15 13:44:00 +01:00
Lukas Tönne added 1 commit 2023-12-15 14:37:24 +01:00
Lukas Tönne added 1 commit 2023-12-15 18:12:24 +01:00
e16086278c Grid-to-points node for converting a grid to a point cloud.
This dumps most available grid information into a point cloud, creating
a point for each voxel and/or tile, with anonymous attributes for the
voxel value and various other properties.

This node is mostly useful for debugging and visualizing grid data,
at least until built-in viewer nodes and spreadsheet support are
available.
Lukas Tönne added 1 commit 2023-12-17 00:01:57 +01:00
Lukas Tönne added 1 commit 2024-01-04 13:31:08 +01:00
Lukas Tönne added 2 commits 2024-01-04 16:40:30 +01:00
Lukas Tönne added 1 commit 2024-01-04 17:11:21 +01:00
Lukas Tönne added 1 commit 2024-01-05 10:30:03 +01:00
Lukas Tönne added 1 commit 2024-01-05 11:43:25 +01:00
Lukas Tönne added 1 commit 2024-01-05 11:51:36 +01:00
Author
Member

@JacquesLucke I've updated this branch to build against the new SocketValueVariant. However, many nodes currently will crash because they don't handle user count correctly yet. I think the steps needed to make this work could be improved.

I've made two versions of a typical workflow, using the Dilate node as an example case. Neither of them are nice, maybe there is a better way?

First get the input grid

  // Internal `SocketValueVariant` conversion is nice!
  auto grid = params.extract_input<bke::VolumeGrid<T>>("Grid");

Then modify it and write to output. But the way copy-on-write, user count, and type casting is handled makes for verbose and complicated code.

  // Version 1: Get raw data, wrap in a new VolumeGrid at the end.
  bke::VolumeGridData &data = grid.get_for_write();

  openvdb::GridBase &vdb_grid_base = data.grid_for_write(data.tree_access_token());
  // Low-level casting required here since we don't have a VolumeGrid<T> wrapper for the result yet.
  auto &vdb_grid = reinterpret_cast<bke::OpenvdbGridType<T> &>(vdb_grid_base);
  
  openvdb::tools::dilateActiveValues(
      vdb_grid.tree(), iterations, BKE_volume_vdb_neighbors_mode(neighbors_mode));

  // Have to manually increment user count after get_for_write.
  // Watch out: doing this will make the output pointer immutable again and require copy-on-write.
  data.add_user();
  params.set_output("Grid", bke::VolumeGrid<T>(&data));
  // Version 2: Wrap the writable data in a new VolumeGrid straight away to make use of casting accessors.
  bke::VolumeGridData &data = grid.get_for_write();
  // Warning! This is not safe, the wrapper will destroy data when it goes out of scope.
  // It's crucial to increment the user count before that happens.
  bke::VolumeGrid<T> output_grid(&data);

  // Minor annoyance: grid_for_write is a bit misleading?
  // It's a member function of the VolumeGrid but unlike get_for_write
  // it does not handle the implicit sharing copy-on-write.
  // Two different ways of interpreting "for_write" i suppose ...
  openvdb::tools::dilateActiveValues(output_grid.grid_for_write(data.tree_access_token()).tree(),
                                     iterations,
                                     BKE_volume_vdb_neighbors_mode(neighbors_mode));

  // Have to manually increment user count after get_for_write.
  // We cannot do this before accessing the grid data, since it makes the output_grid
  // read-only again and requires yet another copy-on-write.
  data.add_user();
  params.set_output("Grid", std::move(output_grid));
@JacquesLucke I've updated this branch to build against the new `SocketValueVariant`. However, many nodes currently will crash because they don't handle user count correctly yet. I think the steps needed to make this work could be improved. I've made two versions of a typical workflow, using the Dilate node as an example case. Neither of them are nice, maybe there is a better way? First get the input grid ```cpp // Internal `SocketValueVariant` conversion is nice! auto grid = params.extract_input<bke::VolumeGrid<T>>("Grid"); ``` Then modify it and write to output. But the way copy-on-write, user count, and type casting is handled makes for verbose and complicated code. ```cpp // Version 1: Get raw data, wrap in a new VolumeGrid at the end. bke::VolumeGridData &data = grid.get_for_write(); openvdb::GridBase &vdb_grid_base = data.grid_for_write(data.tree_access_token()); // Low-level casting required here since we don't have a VolumeGrid<T> wrapper for the result yet. auto &vdb_grid = reinterpret_cast<bke::OpenvdbGridType<T> &>(vdb_grid_base); openvdb::tools::dilateActiveValues( vdb_grid.tree(), iterations, BKE_volume_vdb_neighbors_mode(neighbors_mode)); // Have to manually increment user count after get_for_write. // Watch out: doing this will make the output pointer immutable again and require copy-on-write. data.add_user(); params.set_output("Grid", bke::VolumeGrid<T>(&data)); ``` ```cpp // Version 2: Wrap the writable data in a new VolumeGrid straight away to make use of casting accessors. bke::VolumeGridData &data = grid.get_for_write(); // Warning! This is not safe, the wrapper will destroy data when it goes out of scope. // It's crucial to increment the user count before that happens. bke::VolumeGrid<T> output_grid(&data); // Minor annoyance: grid_for_write is a bit misleading? // It's a member function of the VolumeGrid but unlike get_for_write // it does not handle the implicit sharing copy-on-write. // Two different ways of interpreting "for_write" i suppose ... openvdb::tools::dilateActiveValues(output_grid.grid_for_write(data.tree_access_token()).tree(), iterations, BKE_volume_vdb_neighbors_mode(neighbors_mode)); // Have to manually increment user count after get_for_write. // We cannot do this before accessing the grid data, since it makes the output_grid // read-only again and requires yet another copy-on-write. data.add_user(); params.set_output("Grid", std::move(output_grid)); ```
Member

You can actually just use params.set_output("Grid", std::move(grid));
There is no need to create a new VolumeGrid, you're just mutating the existing one.

Note that the tree access token must be in scope for as long as the tree is used. Generally, you should not pass it directly to the accessor function, but store it in a separate variable instead.

The reinterpret_cast to the openvdb grid type, also shouldn't be necessary, because you can use VolumeGrid<T>::grid_for_write(...). I am noticing one issue with that right now that I need to look into though. It's that you can't really have access to the tree token yet, because an internal copy might be made internally. Need to think about that.. Maybe the method has to return the grid and the token together for correctness, or it has to modify the token internally.

You can actually just use `params.set_output("Grid", std::move(grid));` There is no need to create a new `VolumeGrid`, you're just mutating the existing one. Note that the tree access token must be in scope for as long as the tree is used. Generally, you should not pass it directly to the accessor function, but store it in a separate variable instead. The `reinterpret_cast` to the openvdb grid type, also shouldn't be necessary, because you can use `VolumeGrid<T>::grid_for_write(...)`. I am noticing one issue with that right now that I need to look into though. It's that you can't really have access to the tree token yet, because an internal copy might be made internally. Need to think about that.. Maybe the method has to return the grid and the token together for correctness, or it has to modify the token internally.
Jacques Lucke added 2 commits 2024-01-10 16:18:56 +01:00
Lukas Tönne added 1 commit 2024-01-20 10:07:49 +01:00
Lukas Tönne added 1 commit 2024-01-20 10:34:30 +01:00
Lukas Tönne added 1 commit 2024-01-20 10:55:28 +01:00
9668a2feec Renamed "Capture Grid" to "Set Grid Value".
Making the topology input grid unnecessary won't really work, the value
field alone simply cannot define grid topology. The new name and layout
better reflects what the node is doing and should make it more
intuitive.
Author
Member

@JacquesLucke I'm hitting an assert in the VolumeGridData(std::shared_ptr<openvdb::GridBase> grid) constructor: it expects the input pointer to be unique, but passing the pointer by value it increments user count, even when the caller moves the pointer. I guess the constructor should take an rvalue reference?

EDIT: Well that didn't fix it, i'm not entirely sure where the extra user count comes from.

EDIT2: Mystery solved: i was using a const pointer as a local output grid variable:
const GridPtr output_grid = GridType::create(vdb_background);
When moving this to the output GVolumeGrid the type does not match and a copy is made.
return bke::GVolumeGrid(std::move(output_grid));
Making the output_grid non-const solves the issue. This doesn't seem quite obvious enough. Maybe should have a constructor for const pointers that could have a static assert.

@JacquesLucke I'm hitting an assert in the `VolumeGridData(std::shared_ptr<openvdb::GridBase> grid)` constructor: it expects the input pointer to be unique, but passing the pointer by value it increments user count, even when the caller moves the pointer. I guess the constructor should take an rvalue reference? EDIT: Well that didn't fix it, i'm not entirely sure where the extra user count comes from. EDIT2: Mystery solved: i was using a const pointer as a local output grid variable: `const GridPtr output_grid = GridType::create(vdb_background);` When moving this to the output `GVolumeGrid` the type does not match and a copy is made. `return bke::GVolumeGrid(std::move(output_grid));` Making the `output_grid` non-const solves the issue. This doesn't seem quite obvious enough. Maybe should have a constructor for const pointers that could have a static assert.
Lukas Tönne added 1 commit 2024-01-20 17:33:51 +01:00
de6e4207d8 Added new MaskGrid socket declaration for generic topology grids.
This removes the need for secondary type selection in many nodes.
Lukas Tönne added 6 commits 2024-02-07 14:46:28 +01:00
Lukas Tönne added 1 commit 2024-02-07 14:47:05 +01:00
Lukas Tönne added 1 commit 2024-02-10 11:12:07 +01:00
Lukas Tönne added 1 commit 2024-02-11 11:15:24 +01:00
Lukas Tönne added 2 commits 2024-02-19 09:46:59 +01:00
Lukas Tönne added 1 commit 2024-02-25 10:05:02 +01:00
Lukas Tönne added 1 commit 2024-03-08 15:15:36 +01:00
This pull request has changes conflicting with the target branch.
  • scripts/startup/bl_ui/node_add_menu_geometry.py
  • source/blender/blenkernel/BKE_node.hh
  • source/blender/blenlib/BLI_implicit_sharing_ptr.hh

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u volume-grid-nodes:LukasTonne-volume-grid-nodes
git checkout LukasTonne-volume-grid-nodes
Sign in to join this conversation.
No reviewers
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Reference: blender/blender#116021
No description provided.