Geometry Nodes: Support grid inputs to viewer node
Display the grid in the 3D viewport (internally just create a volume geometry so this case doesn't spread into any rendering code), and add very basic data in the spreadsheet for the grid. I had to store the geometry in the viewer node log as a cache so the lifetime of the temporary volume grid was long enough. Pull Request: https://projects.blender.org/blender/blender/pulls/146780
This commit is contained in:
@@ -1861,7 +1861,7 @@ void object_duplilist_preview(Depsgraph *depsgraph,
|
||||
if (const geo_log::ViewerNodeLog *viewer_log =
|
||||
geo_log::GeoNodesLog::find_viewer_node_log_for_path(*viewer_path))
|
||||
{
|
||||
if (std::optional<blender::bke::GeometrySet> viewer_geometry = viewer_log->main_geometry()) {
|
||||
if (const blender::bke::GeometrySet *viewer_geometry = viewer_log->main_geometry()) {
|
||||
ctx.preview_base_geometry = &*viewer_geometry;
|
||||
make_duplis_geometry_set_impl(&ctx,
|
||||
*viewer_geometry,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "BKE_volume_grid_fwd.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_virtual_array.hh"
|
||||
@@ -564,6 +565,18 @@ void VolumeDataSource::foreach_default_column_ids(
|
||||
}
|
||||
}
|
||||
|
||||
static StringRef grid_class_name(const bke::VolumeGridData &grid_data)
|
||||
{
|
||||
openvdb::GridClass grid_class = grid_data.grid_class();
|
||||
if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
|
||||
return IFACE_("Fog Volume");
|
||||
}
|
||||
if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
|
||||
return IFACE_("Level Set");
|
||||
}
|
||||
return IFACE_("Unknown");
|
||||
}
|
||||
|
||||
std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
|
||||
const SpreadsheetColumnID &column_id) const
|
||||
{
|
||||
@@ -594,15 +607,7 @@ std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
|
||||
if (STREQ(column_id.name, "Class")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
IFACE_("Class"), VArray<std::string>::from_std_func(size, [volume](int64_t index) {
|
||||
const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
|
||||
openvdb::GridClass grid_class = volume_grid->grid_class();
|
||||
if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
|
||||
return IFACE_("Fog Volume");
|
||||
}
|
||||
if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) {
|
||||
return IFACE_("Level Set");
|
||||
}
|
||||
return IFACE_("Unknown");
|
||||
return grid_class_name(*BKE_volume_grid_get(volume, index));
|
||||
}));
|
||||
}
|
||||
#else
|
||||
@@ -621,6 +626,51 @@ int VolumeDataSource::tot_rows() const
|
||||
return BKE_volume_num_grids(volume);
|
||||
}
|
||||
|
||||
VolumeGridDataSource::VolumeGridDataSource(const bke::GVolumeGrid &grid)
|
||||
: grid_(std::make_unique<bke::GVolumeGrid>(grid))
|
||||
{
|
||||
}
|
||||
|
||||
void VolumeGridDataSource::foreach_default_column_ids(
|
||||
FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const
|
||||
{
|
||||
if (!grid_) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const char *name : {"Data Type", "Class"}) {
|
||||
SpreadsheetColumnID column_id{(char *)name};
|
||||
fn(column_id, false);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ColumnValues> VolumeGridDataSource::get_column_values(
|
||||
const SpreadsheetColumnID &column_id) const
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
if (STREQ(column_id.name, "Data Type")) {
|
||||
const VolumeGridType type = (*grid_)->grid_type();
|
||||
const char *name = nullptr;
|
||||
RNA_enum_name_from_value(rna_enum_volume_grid_data_type_items, type, &name);
|
||||
return std::make_unique<ColumnValues>(IFACE_("Data Type"),
|
||||
VArray<std::string>::from_single(name, 1));
|
||||
}
|
||||
if (STREQ(column_id.name, "Class")) {
|
||||
const StringRef name = grid_class_name(grid_->get());
|
||||
return std::make_unique<ColumnValues>(IFACE_("Class"),
|
||||
VArray<std::string>::from_single(name, 1));
|
||||
}
|
||||
#else
|
||||
UNUSED_VARS(column_id);
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
int VolumeGridDataSource::tot_rows() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
ListDataSource::ListDataSource(nodes::ListPtr list) : list_(std::move(list)) {}
|
||||
|
||||
void ListDataSource::foreach_default_column_ids(
|
||||
@@ -1051,7 +1101,7 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
|
||||
return {};
|
||||
}
|
||||
if (display_data.is_volume_grid()) {
|
||||
return {};
|
||||
return std::make_unique<VolumeGridDataSource>(display_data.get<bke::GVolumeGrid>());
|
||||
}
|
||||
if (display_data.is_list()) {
|
||||
return std::make_unique<ListDataSource>(display_data.extract<nodes::ListPtr>());
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_instances.hh"
|
||||
#include "BKE_volume_grid_fwd.hh"
|
||||
|
||||
#include "NOD_geometry_nodes_bundle_fwd.hh"
|
||||
#include "NOD_geometry_nodes_closure_fwd.hh"
|
||||
@@ -93,6 +94,22 @@ class VolumeDataSource : public DataSource {
|
||||
int tot_rows() const override;
|
||||
};
|
||||
|
||||
class VolumeGridDataSource : public DataSource {
|
||||
/** Using #unique_ptr so that `BKE_volume_grid_fwd.hh` can be used. */
|
||||
std::unique_ptr<bke::GVolumeGrid> grid_;
|
||||
|
||||
public:
|
||||
VolumeGridDataSource(const bke::GVolumeGrid &grid);
|
||||
|
||||
void foreach_default_column_ids(
|
||||
FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const override;
|
||||
|
||||
std::unique_ptr<ColumnValues> get_column_values(
|
||||
const SpreadsheetColumnID &column_id) const override;
|
||||
|
||||
int tot_rows() const override;
|
||||
};
|
||||
|
||||
class ListDataSource : public DataSource {
|
||||
nodes::ListPtr list_;
|
||||
|
||||
|
||||
@@ -888,7 +888,7 @@ static bke::GeometrySet find_geometry_for_gizmo(const Object &object_eval,
|
||||
if (const geo_eval_log::ViewerNodeLog *viewer_log =
|
||||
nmd_orig.runtime->eval_log->find_viewer_node_log_for_path(viewer_path))
|
||||
{
|
||||
if (std::optional<bke::GeometrySet> viewer_geometry = viewer_log->main_geometry()) {
|
||||
if (const bke::GeometrySet *viewer_geometry = viewer_log->main_geometry()) {
|
||||
return *viewer_geometry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "BLI_cache_mutex.hh"
|
||||
#include "BLI_compute_context.hh"
|
||||
#include "BLI_enumerable_thread_specific.hh"
|
||||
#include "BLI_generic_pointer.hh"
|
||||
@@ -239,6 +240,9 @@ class ListInfoLog : public ValueLog {
|
||||
* Data logged by a viewer node when it is executed.
|
||||
*/
|
||||
class ViewerNodeLog {
|
||||
mutable CacheMutex main_geometry_cache_mutex_;
|
||||
mutable std::optional<bke::GeometrySet> main_geometry_cache_;
|
||||
|
||||
public:
|
||||
struct Item {
|
||||
int identifier;
|
||||
@@ -255,7 +259,7 @@ class ViewerNodeLog {
|
||||
|
||||
CustomIDVectorSet<Item, ItemIdentifierGetter> items;
|
||||
|
||||
std::optional<bke::GeometrySet> main_geometry() const;
|
||||
const bke::GeometrySet *main_geometry() const;
|
||||
};
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "NOD_geometry_nodes_bundle.hh"
|
||||
#include "NOD_geometry_nodes_closure.hh"
|
||||
#include "NOD_geometry_nodes_log.hh"
|
||||
@@ -381,14 +382,25 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<bke::GeometrySet> ViewerNodeLog::main_geometry() const
|
||||
const bke::GeometrySet *ViewerNodeLog::main_geometry() const
|
||||
{
|
||||
for (const Item &item : this->items) {
|
||||
if (item.value.is_single() && item.value.get_single_ptr().is_type<bke::GeometrySet>()) {
|
||||
return *item.value.get_single_ptr().get<bke::GeometrySet>();
|
||||
main_geometry_cache_mutex_.ensure([&]() {
|
||||
for (const Item &item : this->items) {
|
||||
if (item.value.is_volume_grid()) {
|
||||
const bke::GVolumeGrid grid = item.value.get<bke::GVolumeGrid>();
|
||||
Volume *volume = BKE_id_new_nomain<Volume>(nullptr);
|
||||
grid->add_user();
|
||||
BKE_volume_grid_add(volume, grid.get());
|
||||
main_geometry_cache_ = bke::GeometrySet::from_volume(volume);
|
||||
return;
|
||||
}
|
||||
if (item.value.is_single() && item.value.get_single_ptr().is_type<bke::GeometrySet>()) {
|
||||
main_geometry_cache_ = *item.value.get_single_ptr().get<bke::GeometrySet>();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
});
|
||||
return main_geometry_cache_ ? &*main_geometry_cache_ : nullptr;
|
||||
}
|
||||
|
||||
static bool warning_is_propagated(const NodeWarningPropagation propagation,
|
||||
|
||||
Reference in New Issue
Block a user