New Grid Info node for reading grid transforms and background value
These are generic properties of grids (not stored in voxels) which are useful to know in geometry nodes. The transform in particular defines the voxel size. Background value is used outside of active voxels. Pull Request: https://projects.blender.org/blender/blender/pulls/138592
This commit is contained in:
@@ -796,6 +796,7 @@ class NODE_MT_geometry_node_GEO_VOLUME_READ(Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeGetNamedGrid")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeGridInfo")
|
||||
node_add_menu.draw_assets_for_catalog(layout, "Volume/Read")
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ std::optional<blender::Bounds<blender::float3>> BKE_volume_grid_bounds(
|
||||
openvdb::GridBase::ConstPtr BKE_volume_grid_shallow_transform(openvdb::GridBase::ConstPtr grid,
|
||||
const blender::float4x4 &transform);
|
||||
|
||||
blender::float4x4 BKE_volume_transform_to_blender(const openvdb::math::Transform &transform);
|
||||
openvdb::math::Transform BKE_volume_transform_to_openvdb(const blender::float4x4 &transform);
|
||||
|
||||
template<typename OpType>
|
||||
auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
|
||||
{
|
||||
|
||||
@@ -1092,6 +1092,32 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_shallow_transform(openvdb::GridBase:
|
||||
return grid->copyGridReplacingTransform(grid_transform);
|
||||
}
|
||||
|
||||
blender::float4x4 BKE_volume_transform_to_blender(const openvdb::math::Transform &transform)
|
||||
{
|
||||
/* Perspective not supported for now, getAffineMap() will leave out the
|
||||
* perspective part of the transform. */
|
||||
const openvdb::math::Mat4f matrix = transform.baseMap()->getAffineMap()->getMat4();
|
||||
/* Blender column-major and OpenVDB right-multiplication conventions match. */
|
||||
float4x4 result;
|
||||
for (int col = 0; col < 4; col++) {
|
||||
for (int row = 0; row < 4; row++) {
|
||||
result[col][row] = matrix(col, row);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
openvdb::math::Transform BKE_volume_transform_to_openvdb(const blender::float4x4 &transform)
|
||||
{
|
||||
openvdb::math::Mat4f matrix_openvdb;
|
||||
for (int col = 0; col < 4; col++) {
|
||||
for (int row = 0; row < 4; row++) {
|
||||
matrix_openvdb(col, row) = transform[col][row];
|
||||
}
|
||||
}
|
||||
return openvdb::math::Transform(std::make_shared<openvdb::math::AffineMap>(matrix_openvdb));
|
||||
}
|
||||
|
||||
/* Changing the resolution of a grid. */
|
||||
|
||||
/**
|
||||
|
||||
@@ -436,19 +436,7 @@ int get_channels_num(const VolumeGridType type)
|
||||
float4x4 get_transform_matrix(const VolumeGridData &grid)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
const openvdb::math::Transform &transform = grid.transform();
|
||||
|
||||
/* Perspective not supported for now, getAffineMap() will leave out the
|
||||
* perspective part of the transform. */
|
||||
openvdb::math::Mat4f matrix = transform.baseMap()->getAffineMap()->getMat4();
|
||||
/* Blender column-major and OpenVDB right-multiplication conventions match. */
|
||||
float4x4 result;
|
||||
for (int col = 0; col < 4; col++) {
|
||||
for (int row = 0; row < 4; row++) {
|
||||
result[col][row] = matrix(col, row);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return BKE_volume_transform_to_blender(grid.transform());
|
||||
#else
|
||||
UNUSED_VARS(grid);
|
||||
return float4x4::identity();
|
||||
@@ -458,15 +446,7 @@ float4x4 get_transform_matrix(const VolumeGridData &grid)
|
||||
void set_transform_matrix(VolumeGridData &grid, const float4x4 &matrix)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
openvdb::math::Mat4f matrix_openvdb;
|
||||
for (int col = 0; col < 4; col++) {
|
||||
for (int row = 0; row < 4; row++) {
|
||||
matrix_openvdb(col, row) = matrix[col][row];
|
||||
}
|
||||
}
|
||||
|
||||
grid.transform_for_write() = openvdb::math::Transform(
|
||||
std::make_shared<openvdb::math::AffineMap>(matrix_openvdb));
|
||||
grid.transform_for_write() = BKE_volume_transform_to_openvdb(matrix);
|
||||
#else
|
||||
UNUSED_VARS(grid, matrix);
|
||||
#endif
|
||||
|
||||
@@ -13883,6 +13883,7 @@ static void rna_def_nodes(BlenderRNA *brna)
|
||||
define("GeometryNode", "GeometryNodeGizmoLinear");
|
||||
define("GeometryNode", "GeometryNodeGizmoTransform", rna_def_geo_gizmo_transform);
|
||||
define("GeometryNode", "GeometryNodeGreasePencilToCurves");
|
||||
define("GeometryNode", "GeometryNodeGridInfo");
|
||||
define("GeometryNode", "GeometryNodeGridToMesh");
|
||||
define("GeometryNode", "GeometryNodeImageInfo");
|
||||
define("GeometryNode", "GeometryNodeImageTexture", def_geo_image_texture);
|
||||
|
||||
@@ -89,6 +89,7 @@ set(SRC
|
||||
nodes/node_geo_gizmo_linear.cc
|
||||
nodes/node_geo_gizmo_transform.cc
|
||||
nodes/node_geo_grease_pencil_to_curves.cc
|
||||
nodes/node_geo_grid_info.cc
|
||||
nodes/node_geo_grid_to_mesh.cc
|
||||
nodes/node_geo_image.cc
|
||||
nodes/node_geo_image_info.cc
|
||||
|
||||
117
source/blender/nodes/geometry/nodes/node_geo_grid_info.cc
Normal file
117
source/blender/nodes/geometry/nodes/node_geo_grid_info.cc
Normal file
@@ -0,0 +1,117 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
#include "BLI_math_matrix.hh"
|
||||
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_volume_grid.hh"
|
||||
#include "BKE_volume_openvdb.hh"
|
||||
|
||||
#include "NOD_rna_define.hh"
|
||||
#include "NOD_socket.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_grid_info_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const bNode *node = b.node_or_null();
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(node->custom1);
|
||||
|
||||
b.add_input(data_type, "Grid").hide_value();
|
||||
|
||||
b.add_output<decl::Matrix>("Transform")
|
||||
.description("Transform from grid index space to object space");
|
||||
b.add_output(data_type, "Background Value").description("Default value outside of grid voxels");
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(params.node().custom1);
|
||||
|
||||
const auto grid = params.extract_input<bke::GVolumeGrid>("Grid");
|
||||
if (!grid) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
bke::VolumeTreeAccessToken tree_token;
|
||||
const std::shared_ptr<const openvdb::GridBase> vdb_grid = grid->grid_ptr(tree_token);
|
||||
params.set_output("Transform", BKE_volume_transform_to_blender(vdb_grid->transform()));
|
||||
|
||||
bke::attribute_math::convert_to_static_type(
|
||||
*bke::socket_type_to_geo_nodes_base_cpp_type(data_type), [&](auto type_tag) {
|
||||
using ValueT = decltype(type_tag);
|
||||
using type_traits = typename bke::VolumeGridTraits<ValueT>;
|
||||
using TreeType = typename type_traits::TreeType;
|
||||
using GridType = openvdb::Grid<TreeType>;
|
||||
|
||||
if constexpr (!std::is_same_v<typename type_traits::BlenderType, void>) {
|
||||
const std::shared_ptr<const GridType> vdb_typed_grid = openvdb::GridBase::grid<GridType>(
|
||||
vdb_grid);
|
||||
params.set_output("Background Value",
|
||||
type_traits::to_blender(vdb_typed_grid->background()));
|
||||
}
|
||||
});
|
||||
#else
|
||||
params.set_default_remaining_outputs();
|
||||
params.error_message_add(NodeWarningType::Error,
|
||||
TIP_("Disabled, Blender was compiled without OpenVDB"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void node_init(bNodeTree * /*tree*/, bNode *node)
|
||||
{
|
||||
node->custom1 = SOCK_FLOAT;
|
||||
}
|
||||
|
||||
static void node_rna(StructRNA *srna)
|
||||
{
|
||||
RNA_def_node_enum(srna,
|
||||
"data_type",
|
||||
"Data Type",
|
||||
"Type of grid data",
|
||||
rna_enum_node_socket_data_type_items,
|
||||
NOD_inline_enum_accessors(custom1),
|
||||
SOCK_FLOAT,
|
||||
grid_socket_type_items_filter_fn);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static blender::bke::bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, "GeometryNodeGridInfo");
|
||||
ntype.ui_name = "Grid Info";
|
||||
ntype.ui_description = "Retrieve information about a volume grid";
|
||||
ntype.nclass = NODE_CLASS_INPUT;
|
||||
ntype.initfunc = node_init;
|
||||
ntype.geometry_node_execute = node_geo_exec;
|
||||
ntype.draw_buttons = node_layout;
|
||||
ntype.declare = node_declare;
|
||||
blender::bke::node_register_type(ntype);
|
||||
|
||||
node_rna(ntype.rna_ext.srna);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_geo_grid_info_cc
|
||||
Reference in New Issue
Block a user