Blender  V2.93
node_geo_boolean.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "DNA_mesh_types.h"
18 
20 
21 #include "UI_interface.h"
22 #include "UI_resources.h"
23 
24 #include "node_geometry_util.hh"
25 
27  {SOCK_GEOMETRY, N_("Geometry 1")},
29  N_("Geometry 2"),
30  0.0f,
31  0.0f,
32  0.0f,
33  0.0f,
34  0.0f,
35  0.0f,
36  PROP_NONE,
38  {SOCK_BOOLEAN, N_("Self Intersection")},
39  {SOCK_BOOLEAN, N_("Hole Tolerant")},
40  {-1, ""},
41 };
42 
44  {SOCK_GEOMETRY, N_("Geometry")},
45  {-1, ""},
46 };
47 
49 {
50  uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
51 }
52 
54 {
56 
57  bNodeSocket *geometry_1_socket = (bNodeSocket *)node->inputs.first;
58  bNodeSocket *geometry_2_socket = geometry_1_socket->next;
59 
60  switch (operation) {
63  nodeSetSocketAvailability(geometry_1_socket, false);
64  nodeSetSocketAvailability(geometry_2_socket, true);
65  node_sock_label(geometry_2_socket, N_("Geometry"));
66  break;
68  nodeSetSocketAvailability(geometry_1_socket, true);
69  nodeSetSocketAvailability(geometry_2_socket, true);
70  node_sock_label(geometry_2_socket, N_("Geometry 2"));
71  break;
72  }
73 }
74 
76 {
78 }
79 
80 namespace blender::nodes {
81 
83 {
85  const bool use_self = params.get_input<bool>("Self Intersection");
86  const bool hole_tolerant = params.get_input<bool>("Hole Tolerant");
87 
88 #ifndef WITH_GMP
89  params.error_message_add(NodeWarningType::Error,
90  TIP_("Disabled, Blender was compiled without GMP"));
91 #endif
92 
93  Vector<const Mesh *> meshes;
94  Vector<const float4x4 *> transforms;
95 
96  GeometrySet set_a;
97  if (operation == GEO_NODE_BOOLEAN_DIFFERENCE) {
98  set_a = params.extract_input<GeometrySet>("Geometry 1");
99  /* Note that it technically wouldn't be necessary to realize the instances for the first
100  * geometry input, but the boolean code expects the first shape for the difference operation
101  * to be a single mesh. */
102  set_a = geometry_set_realize_instances(set_a);
103  const Mesh *mesh_in_a = set_a.get_mesh_for_read();
104  if (mesh_in_a != nullptr) {
105  meshes.append(mesh_in_a);
106  transforms.append(nullptr);
107  }
108  }
109 
110  /* The instance transform matrices are owned by the instance group, so we have to
111  * keep all of them around for use during the boolean operation. */
113  Vector<GeometrySet> geometry_sets = params.extract_multi_input<GeometrySet>("Geometry 2");
114  for (const GeometrySet &geometry_set : geometry_sets) {
115  bke::geometry_set_gather_instances(geometry_set, set_groups);
116  }
117 
118  for (const bke::GeometryInstanceGroup &set_group : set_groups) {
119  const Mesh *mesh_in = set_group.geometry_set.get_mesh_for_read();
120  if (mesh_in != nullptr) {
121  meshes.append_n_times(mesh_in, set_group.transforms.size());
122  for (const int i : set_group.transforms.index_range()) {
123  transforms.append(set_group.transforms.begin() + i);
124  }
125  }
126  }
127 
129  meshes, transforms, float4x4::identity(), {}, use_self, hole_tolerant, operation);
130 
131  params.set_output("Geometry", GeometrySet::create_with_mesh(result));
132 }
133 
134 } // namespace blender::nodes
135 
137 {
138  static bNodeType ntype;
139 
146  nodeRegisterType(&ntype);
147 }
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3726
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
#define GEO_NODE_BOOLEAN
Definition: BKE_node.h:1379
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
#define UNUSED(x)
#define TIP_(msgid)
#define N_(msgid)
@ SOCK_MULTI_INPUT
@ SOCK_BOOLEAN
@ SOCK_GEOMETRY
GeometryNodeBooleanOperation
@ GEO_NODE_BOOLEAN_DIFFERENCE
@ GEO_NODE_BOOLEAN_UNION
@ GEO_NODE_BOOLEAN_INTERSECT
@ PROP_NONE
Definition: RNA_types.h:113
#define C
Definition: RandGen.cpp:39
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void append(const T &value)
Definition: BLI_vector.hh:438
void append_n_times(const T &value, const int64_t n)
Definition: BLI_vector.hh:489
OperationNode * node
void * tree
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void geometry_set_gather_instances(const GeometrySet &geometry_set, Vector< GeometryInstanceGroup > &r_instance_groups)
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
Mesh * direct_mesh_boolean(blender::Span< const Mesh * > meshes, blender::Span< const float4x4 * > obmats, const float4x4 &target_transform, blender::Span< blender::Array< short >> material_remaps, const bool use_self, const bool hole_tolerant, const int boolean_mode)
static void geo_node_boolean_exec(GeoNodeExecParams params)
static bNodeSocketTemplate geo_node_boolean_out[]
static void geo_node_boolean_update(bNodeTree *UNUSED(ntree), bNode *node)
static void geo_node_boolean_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void geo_node_boolean_init(bNodeTree *UNUSED(tree), bNode *node)
void register_node_type_geo_boolean()
static bNodeSocketTemplate geo_node_boolean_in[]
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_sock_label(bNodeSocket *sock, const char *name)
Definition: node_util.c:88
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Mesh * get_mesh_for_read() const
float size[3]
Compact definition of a node socket.
Definition: BKE_node.h:95
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327
void(* updatefunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:274
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:253
static float4x4 identity()
Definition: BLI_float4x4.hh:48
PointerRNA * ptr
Definition: wm_files.c:3157