26 const bNode *node =
b.node_or_null();
30 .supported_type(GeometryComponent::Type::Mesh)
31 .
description(
"Base mesh to subtract geometry from");
33 if (node !=
nullptr) {
38 .supported_type(GeometryComponent::Type::Mesh)
44 .supported_type(GeometryComponent::Type::Mesh)
46 .
description(
"Mesh that is subtracted from the first mesh");
51 auto make_mesh_arr = [](
bNode &node) {
54 auto &self_intersect =
55 b.add_input<
decl::Bool>(
"Self Intersection").make_available(make_mesh_arr);
56 auto &hole_tolerant =
b.add_input<
decl::Bool>(
"Hole Tolerant").make_available(make_mesh_arr);
61 if (node !=
nullptr) {
65 output_edges.available(
73 first_geometry.available(
false);
111 bool use_self =
false;
112 bool hole_tolerant =
false;
114 use_self =
params.extract_input<
bool>(
"Self Intersection");
115 hole_tolerant =
params.extract_input<
bool>(
"Hole Tolerant");
132 if (mesh_in_a->totcol == 0) {
134 materials.
add(
nullptr);
137 materials.
add_multiple({mesh_in_a->mat, mesh_in_a->totcol});
139 material_remaps.
append({});
155 const Span<float4x4> instance_transforms = instances->transforms();
156 for (
const int i :
handles.index_range()) {
158 switch (reference.
type()) {
164 transforms.
append(instance_transforms[
i]);
172 transforms.
append(instance_transforms[
i]);
187 material_remaps.
resize(0);
193 "Intersecting Edges");
216 TIP_(
"Boolean result is too big for solver to handle"));
220 TIP_(
"Boolean solver not available (compiled without it)"));
226 params.set_default_remaining_outputs();
241 selection.
span.fill(
false);
242 for (
const int i : intersecting_edges) {
243 selection.
span[
i] =
true;
250 all_geometries.
append(set_a);
253 const std::array types_to_join = {GeometryComponent::Type::Edit};
255 all_geometries, {}, std::make_optional(types_to_join));
259 params.set_output(
"Mesh", std::move(result_geometry));
269 "Keep the part of the mesh that is common between all operands"},
274 "Combine meshes in an additive way"},
279 "Combine meshes in a subtractive way"},
280 {0,
nullptr, 0,
nullptr,
nullptr},
287 "Slower solver with the best results for coplanar faces"},
292 "Simple solver with good performance, without support for overlapping geometry"},
297 "Fastest solver that works only on manifold meshes but gives better results"},
298 {0,
nullptr, 0,
nullptr,
nullptr},
305 rna_node_geometry_boolean_method_items,
313 rna_geometry_boolean_solver_items,
322 ntype.
ui_name =
"Mesh Boolean";
323 ntype.
ui_description =
"Cut, subtract, or join multiple mesh inputs";
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_MESH_BOOLEAN
Object is a sort of wrapper for general info.
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
constexpr void copy_from(Span< T > values) const
int64_t index_of_or_add(const Key &key)
void add_multiple(Span< Key > keys)
void append(const T &value)
void resize(const int64_t new_size)
void extend(Span< T > array)
GeometrySet & geometry_set()
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
void make_available(bNode &node) const
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
static void error(const char *str)
void node_register_type(bNodeType &ntype)
GeometrySet object_get_evaluated_geometry_set(const Object &object, bool apply_subdiv=true)
Mesh * mesh_boolean(Span< const Mesh * > meshes, Span< float4x4 > transforms, Span< Array< short > > material_remaps, BooleanOpParameters op_params, Solver solver, Vector< int > *r_intersecting_edges, BooleanError *r_error)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt, bool allow_merging_instance_references=true)
void debug_randomize_mesh_order(Mesh *mesh)
static void node_init(bNodeTree *, bNode *node)
static Array< short > calc_mesh_material_map(const Mesh &mesh, VectorSet< Material * > &all_materials)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
static void node_register()
static void node_rna(StructRNA *srna)
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 geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
static MatBase identity()
const Mesh * get_mesh() const
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
MutableVArraySpan< T > span
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
bool no_self_intersections
bool no_nested_components
std::optional< std::string > intersecting_edges_id
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)