Blender V4.3
node_geo_sdf_grid_boolean.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#ifdef WITH_OPENVDB
6# include <openvdb/openvdb.h>
7# include <openvdb/tools/Composite.h>
8#endif
9
10#include "BKE_volume_grid.hh"
11
13
14#include "NOD_rna_define.hh"
15
16#include "UI_interface.hh"
17#include "UI_resources.hh"
18
19#include "node_geometry_util.hh"
20
22
23enum class Operation {
24 Intersect = 0,
25 Union = 1,
26 Difference = 2,
27};
28
30{
31 const bNode *node = b.node_or_null();
32
33 auto &first_grid = b.add_input<decl::Float>("Grid 1").hide_value();
34
35 if (node) {
36 static const auto make_available = [](bNode &node) {
37 node.custom1 = int16_t(Operation::Difference);
38 };
39 switch (Operation(node->custom1)) {
42 b.add_input<decl::Float>("Grid", "Grid 2")
43 .hide_value()
44 .multi_input()
45 .make_available(make_available);
46 break;
48 b.add_input<decl::Float>("Grid 2").hide_value().multi_input().make_available(
49 make_available);
50 break;
51 }
52 }
53
54 b.add_output<decl::Float>("Grid").hide_value();
55
56 if (node) {
57 switch (Operation(node->custom1)) {
60 first_grid.available(false);
61 break;
63 first_grid.available(true);
64 break;
65 }
66 }
67}
68
69static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
70{
71 uiItemR(layout, ptr, "operation", UI_ITEM_NONE, "", ICON_NONE);
72}
73
74static void node_init(bNodeTree * /*tree*/, bNode *node)
75{
76 node->custom1 = int16_t(Operation::Difference);
77}
78
79#ifdef WITH_OPENVDB
80static void get_float_grids(MutableSpan<SocketValueVariant> values,
82{
83 for (SocketValueVariant &input : values) {
84 if (auto grid = input.extract<bke::VolumeGrid<float>>()) {
85 grids.append(std::move(grid));
86 }
87 }
88}
89#endif
90
92{
93#ifdef WITH_OPENVDB
94 const Operation operation = Operation(params.node().custom1);
95
96 Vector<SocketValueVariant> inputs = params.extract_input<Vector<SocketValueVariant>>("Grid 2");
98 switch (operation) {
100 case Operation::Union:
101 get_float_grids(inputs, operands);
102 break;
104 if (auto grid = params.extract_input<bke::VolumeGrid<float>>("Grid 1")) {
105 operands.append(std::move(grid));
106 }
107 get_float_grids(inputs, operands);
108 break;
109 }
110
111 if (operands.is_empty()) {
112 params.set_default_remaining_outputs();
113 return;
114 }
115
116 bke::VolumeTreeAccessToken result_token;
117 openvdb::FloatGrid &result_grid = operands.first().grid_for_write(result_token);
118 const openvdb::math::Transform &transform = result_grid.transform();
119
120 for (bke::VolumeGrid<float> &volume_grid : operands.as_mutable_span().drop_front(1)) {
121 bke::VolumeTreeAccessToken tree_token;
122 std::shared_ptr<openvdb::FloatGrid> resampled_storage;
123 openvdb::FloatGrid &grid = geometry::resample_sdf_grid_if_necessary(
124 volume_grid, tree_token, transform, resampled_storage);
125
126 try {
127 switch (operation) {
129 openvdb::tools::csgIntersection(result_grid, grid);
130 break;
131 case Operation::Union:
132 openvdb::tools::csgUnion(result_grid, grid);
133 break;
135 openvdb::tools::csgDifference(result_grid, grid);
136 break;
137 }
138 }
139 catch (const openvdb::ValueError & /*ex*/) {
140 /* May happen if a grid is empty. */
141 params.set_default_remaining_outputs();
142 return;
143 }
144 }
145
146 params.set_output("Grid", std::move(operands.first()));
147#else
149#endif
150}
151
152static void node_rna(StructRNA *srna)
153{
154 static const EnumPropertyItem operation_items[] = {
156 "INTERSECT",
157 0,
158 "Intersect",
159 "Keep the part of the grids that is common between all operands"},
160 {int(Operation::Union), "UNION", 0, "Union", "Combine grids in an additive way"},
162 "DIFFERENCE",
163 0,
164 "Difference",
165 "Combine grids in a subtractive way"},
166 {0, nullptr, 0, nullptr, nullptr},
167 };
168
170 "operation",
171 "Operation",
172 "",
173 operation_items,
176}
177
178static void node_register()
179{
180 static blender::bke::bNodeType ntype;
181 geo_node_type_base(&ntype, GEO_NODE_SDF_GRID_BOOLEAN, "SDF Grid Boolean", NODE_CLASS_GEOMETRY);
182 ntype.declare = node_declare;
183 ntype.initfunc = node_init;
188 node_rna(ntype.rna_ext.srna);
189}
191
192} // namespace blender::nodes::node_geo_sdf_grid_boolean_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void append(const T &value)
bool is_empty() const
MutableSpan< T > as_mutable_span()
const T & first() const
void make_available(bNode &node) const
local_group_size(16, 16) .push_constant(Type b
OperationNode * node
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_init(bNodeTree *, bNode *node)
static void node_geo_exec(GeoNodeExecParams params)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void search_link_ops_for_volume_grid_node(GatherLinkSearchOpParams &params)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams &params)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
signed short int16_t
Definition stdint.h:76
StructRNA * srna
Definition RNA_types.hh:780
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:363
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126