diff options
5 files changed, 70 insertions, 125 deletions
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 46051a58e8b..a8136d06c5f 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -476,6 +476,8 @@ template<typename T> T evaluate_constant_field(const Field<T> &field) return value; } +Field<bool> invert_boolean_field(const Field<bool> &field); + GField make_constant_field(const CPPType &type, const void *value); template<typename T> Field<T> make_constant_field(T value) diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index a53da717606..47f6a0f19ca 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -518,6 +518,14 @@ GField make_field_constant_if_possible(GField field) return new_field; } +Field<bool> invert_boolean_field(const Field<bool> &field) +{ + static CustomMF_SI_SO<bool, bool> not_fn{ + "Not", [](bool a) { return !a; }, CustomMF_presets::AllSpanOrSingle()}; + auto not_op = std::make_shared<FieldOperation>(FieldOperation(not_fn, {field})); + return Field<bool>(not_op); +} + GField make_constant_field(const CPPType &type, const void *value) { auto constant_node = std::make_shared<FieldConstant>(type, value); diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index d261928d1b8..efb7efaf1cc 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -73,7 +73,6 @@ void separate_geometry(GeometrySet &geometry_set, eAttrDomain domain, GeometryNodeDeleteGeometryMode mode, const Field<bool> &selection_field, - bool invert, bool &r_is_error); std::optional<eCustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index c29fe9e08eb..fba696b5b95 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -38,19 +38,6 @@ static void copy_data_based_on_map(Span<T> src, MutableSpan<T> dst, Span<int> in } } -/** Utility function for making an IndexMask from a boolean selection. The indices vector should - * live at least as long as the returned IndexMask. - */ -static IndexMask index_mask_indices(Span<bool> mask, const bool invert, Vector<int64_t> &indices) -{ - for (const int i : mask.index_range()) { - if (mask[i] != invert) { - indices.append(i); - } - } - return IndexMask(indices); -} - /** * Copies the attributes with a domain in `domains` to `result_component`. */ @@ -400,8 +387,7 @@ static SplinePtr spline_delete(const Spline &spline, const IndexMask mask) static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, const Span<bool> selection, - const eAttrDomain selection_domain, - const bool invert) + const eAttrDomain selection_domain) { Span<SplinePtr> input_splines = input_curve.splines(); std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>(); @@ -413,7 +399,7 @@ static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, /* Operates on each of the splines as a whole, i.e. not on the points in the splines * themselves. */ for (const int i : selection.index_range()) { - if (selection[i] != invert) { + if (selection[i]) { output_curve->add_spline(input_splines[i]->copy()); copied_splines.append(i); } @@ -431,7 +417,7 @@ static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, indices_to_copy.clear(); for (const int i_point : IndexRange(spline.size())) { - if (selection[selection_index] != invert) { + if (selection[selection_index]) { /* Append i_point instead of selection_index because we need indices local to the spline * for copying. */ indices_to_copy.append(i_point); @@ -463,8 +449,7 @@ static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, static void separate_curve_selection(GeometrySet &geometry_set, const Field<bool> &selection_field, - const eAttrDomain selection_domain, - const bool invert) + const eAttrDomain selection_domain) { const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); GeometryComponentFieldContext field_context{src_component, selection_domain}; @@ -475,7 +460,7 @@ static void separate_curve_selection(GeometrySet &geometry_set, evaluator.evaluate(); const VArray_Span<bool> &selection = evaluator.get_evaluated<bool>(0); std::unique_ptr<CurveEval> r_curve = curve_separate( - *curves_to_curve_eval(*src_component.get_for_read()), selection, selection_domain, invert); + *curves_to_curve_eval(*src_component.get_for_read()), selection, selection_domain); if (r_curve) { geometry_set.replace_curves(curve_eval_to_curves(*r_curve)); } @@ -485,28 +470,23 @@ static void separate_curve_selection(GeometrySet &geometry_set, } static void separate_point_cloud_selection(GeometrySet &geometry_set, - const Field<bool> &selection_field, - const bool invert) + const Field<bool> &selection_field) { const PointCloudComponent &src_points = *geometry_set.get_component_for_read<PointCloudComponent>(); GeometryComponentFieldContext field_context{src_points, ATTR_DOMAIN_POINT}; fn::FieldEvaluator evaluator{field_context, src_points.attribute_domain_num(ATTR_DOMAIN_POINT)}; - evaluator.add(selection_field); + evaluator.set_selection(selection_field); evaluator.evaluate(); - const VArray_Span<bool> &selection = evaluator.get_evaluated<bool>(0); - - Vector<int64_t> indices; - const IndexMask mask = index_mask_indices(selection, invert, indices); - const int total = mask.size(); - PointCloud *pointcloud = BKE_pointcloud_new_nomain(total); - - if (total == 0) { - geometry_set.replace_pointcloud(pointcloud); + const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + if (selection.is_empty()) { + geometry_set.replace_pointcloud(nullptr); return; } + PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size()); + PointCloudComponent dst_points; dst_points.replace(pointcloud, GeometryOwnershipType::Editable); @@ -514,36 +494,30 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set, geometry_set.gather_attributes_for_propagation( {GEO_COMPONENT_TYPE_POINT_CLOUD}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); - copy_attributes_based_on_mask(attributes, src_points, dst_points, ATTR_DOMAIN_POINT, mask); + copy_attributes_based_on_mask(attributes, src_points, dst_points, ATTR_DOMAIN_POINT, selection); geometry_set.replace_pointcloud(pointcloud); } -static void separate_instance_selection(GeometrySet &geometry_set, - const Field<bool> &selection_field, - const bool invert) +static void delete_selected_instances(GeometrySet &geometry_set, + const Field<bool> &selection_field) { InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>(); GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE}; - const int domain_num = instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE); - fn::FieldEvaluator evaluator{field_context, domain_num}; - evaluator.add(selection_field); + fn::FieldEvaluator evaluator{field_context, + instances.attribute_domain_num(ATTR_DOMAIN_INSTANCE)}; + evaluator.set_selection(selection_field); evaluator.evaluate(); - const VArray_Span<bool> &selection = evaluator.get_evaluated<bool>(0); - - Vector<int64_t> indices; - const IndexMask mask = index_mask_indices(selection, invert, indices); - - if (mask.is_empty()) { + const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + if (selection.is_empty()) { geometry_set.remove<InstancesComponent>(); return; } - instances.remove_instances(mask); + instances.remove_instances(selection); } static void compute_selected_vertices_from_vertex_selection(const Span<bool> vertex_selection, - const bool invert, MutableSpan<int> r_vertex_map, int *r_selected_vertices_num) { @@ -551,7 +525,7 @@ static void compute_selected_vertices_from_vertex_selection(const Span<bool> ver int selected_verts_num = 0; for (const int i : r_vertex_map.index_range()) { - if (vertex_selection[i] != invert) { + if (vertex_selection[i]) { r_vertex_map[i] = selected_verts_num; selected_verts_num++; } @@ -565,7 +539,6 @@ static void compute_selected_vertices_from_vertex_selection(const Span<bool> ver static void compute_selected_edges_from_vertex_selection(const Mesh &mesh, const Span<bool> vertex_selection, - const bool invert, MutableSpan<int> r_edge_map, int *r_selected_edges_num) { @@ -576,7 +549,7 @@ static void compute_selected_edges_from_vertex_selection(const Mesh &mesh, const MEdge &edge = mesh.medge[i]; /* Only add the edge if both vertices will be in the new mesh. */ - if (vertex_selection[edge.v1] != invert && vertex_selection[edge.v2] != invert) { + if (vertex_selection[edge.v1] && vertex_selection[edge.v2]) { r_edge_map[i] = selected_edges_num; selected_edges_num++; } @@ -590,7 +563,6 @@ static void compute_selected_edges_from_vertex_selection(const Mesh &mesh, static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, const Span<bool> vertex_selection, - const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, int *r_selected_polys_num, @@ -608,7 +580,7 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, bool all_verts_in_selection = true; Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); for (const MLoop &loop : loops_src) { - if (vertex_selection[loop.v] == invert) { + if (!vertex_selection[loop.v]) { all_verts_in_selection = false; break; } @@ -632,7 +604,6 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, static void compute_selected_vertices_and_edges_from_edge_selection( const Mesh &mesh, const Span<bool> edge_selection, - const bool invert, MutableSpan<int> r_vertex_map, MutableSpan<int> r_edge_map, int *r_selected_vertices_num, @@ -644,7 +615,7 @@ static void compute_selected_vertices_and_edges_from_edge_selection( int selected_verts_num = 0; for (const int i : IndexRange(mesh.totedge)) { const MEdge &edge = mesh.medge[i]; - if (edge_selection[i] != invert) { + if (edge_selection[i]) { r_edge_map[i] = selected_edges_num; selected_edges_num++; if (r_vertex_map[edge.v1] == -1) { @@ -670,7 +641,6 @@ static void compute_selected_vertices_and_edges_from_edge_selection( */ static void compute_selected_edges_from_edge_selection(const Mesh &mesh, const Span<bool> edge_selection, - const bool invert, MutableSpan<int> r_edge_map, int *r_selected_edges_num) { @@ -678,7 +648,7 @@ static void compute_selected_edges_from_edge_selection(const Mesh &mesh, int selected_edges_num = 0; for (const int i : IndexRange(mesh.totedge)) { - if (edge_selection[i] != invert) { + if (edge_selection[i]) { r_edge_map[i] = selected_edges_num; selected_edges_num++; } @@ -696,7 +666,6 @@ static void compute_selected_edges_from_edge_selection(const Mesh &mesh, */ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, const Span<bool> edge_selection, - const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, int *r_selected_polys_num, @@ -712,7 +681,7 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, bool all_edges_in_selection = true; Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); for (const MLoop &loop : loops_src) { - if (edge_selection[loop.e] == invert) { + if (!edge_selection[loop.e]) { all_edges_in_selection = false; break; } @@ -735,7 +704,6 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, static void compute_selected_mesh_data_from_vertex_selection_edge_face( const Mesh &mesh, const Span<bool> vertex_selection, - const bool invert, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, @@ -745,11 +713,10 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face( { compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num); + mesh, vertex_selection, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_vertex_selection(mesh, vertex_selection, - invert, r_selected_poly_indices, r_loop_starts, r_selected_polys_num, @@ -762,7 +729,6 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face( */ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh, const Span<bool> vertex_selection, - const bool invert, MutableSpan<int> r_vertex_map, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, @@ -773,14 +739,13 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh, int *r_selected_loops_num) { compute_selected_vertices_from_vertex_selection( - vertex_selection, invert, r_vertex_map, r_selected_vertices_num); + vertex_selection, r_vertex_map, r_selected_vertices_num); compute_selected_edges_from_vertex_selection( - mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num); + mesh, vertex_selection, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_vertex_selection(mesh, vertex_selection, - invert, r_selected_poly_indices, r_loop_starts, r_selected_polys_num, @@ -794,7 +759,6 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh, static void compute_selected_mesh_data_from_edge_selection_edge_face( const Mesh &mesh, const Span<bool> edge_selection, - const bool invert, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, @@ -803,10 +767,9 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face( int *r_selected_loops_num) { compute_selected_edges_from_edge_selection( - mesh, edge_selection, invert, r_edge_map, r_selected_edges_num); + mesh, edge_selection, r_edge_map, r_selected_edges_num); compute_selected_polygons_from_edge_selection(mesh, edge_selection, - invert, r_selected_poly_indices, r_loop_starts, r_selected_polys_num, @@ -819,7 +782,6 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face( */ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, const Span<bool> edge_selection, - const bool invert, MutableSpan<int> r_vertex_map, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, @@ -832,14 +794,12 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, r_vertex_map.fill(-1); compute_selected_vertices_and_edges_from_edge_selection(mesh, edge_selection, - invert, r_vertex_map, r_edge_map, r_selected_vertices_num, r_selected_edges_num); compute_selected_polygons_from_edge_selection(mesh, edge_selection, - invert, r_selected_poly_indices, r_loop_starts, r_selected_polys_num, @@ -851,7 +811,6 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, */ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh, const Span<bool> poly_selection, - const bool invert, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, int *r_selected_polys_num, @@ -866,7 +825,7 @@ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh, for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ - if (poly_selection[i] != invert) { + if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); r_loop_starts.append_unchecked(selected_loops_num); selected_loops_num += poly_src.totloop; @@ -882,7 +841,6 @@ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh, static void compute_selected_mesh_data_from_poly_selection_edge_face( const Mesh &mesh, const Span<bool> poly_selection, - const bool invert, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, Vector<int> &r_loop_starts, @@ -902,7 +860,7 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ - if (poly_selection[i] != invert) { + if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); r_loop_starts.append_unchecked(selected_loops_num); selected_loops_num += poly_src.totloop; @@ -929,7 +887,6 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( */ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, const Span<bool> poly_selection, - const bool invert, MutableSpan<int> r_vertex_map, MutableSpan<int> r_edge_map, Vector<int> &r_selected_poly_indices, @@ -953,7 +910,7 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, for (const int i : IndexRange(mesh.totpoly)) { const MPoly &poly_src = mesh.mpoly[i]; /* We keep this one. */ - if (poly_selection[i] != invert) { + if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); r_loop_starts.append_unchecked(selected_loops_num); selected_loops_num += poly_src.totloop; @@ -984,8 +941,7 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, */ static void do_mesh_separation(GeometrySet &geometry_set, const MeshComponent &in_component, - const VArray_Span<bool> &selection, - const bool invert, + const Span<bool> selection, const eAttrDomain domain, const GeometryNodeDeleteGeometryMode mode) { @@ -1016,7 +972,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_POINT: compute_selected_mesh_data_from_vertex_selection(mesh_in, selection, - invert, vertex_map, edge_map, selected_poly_indices, @@ -1029,7 +984,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_EDGE: compute_selected_mesh_data_from_edge_selection(mesh_in, selection, - invert, vertex_map, edge_map, selected_poly_indices, @@ -1042,7 +996,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_FACE: compute_selected_mesh_data_from_poly_selection(mesh_in, selection, - invert, vertex_map, edge_map, selected_poly_indices, @@ -1097,7 +1050,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_POINT: compute_selected_mesh_data_from_vertex_selection_edge_face(mesh_in, selection, - invert, edge_map, selected_poly_indices, new_loop_starts, @@ -1108,7 +1060,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_EDGE: compute_selected_mesh_data_from_edge_selection_edge_face(mesh_in, selection, - invert, edge_map, selected_poly_indices, new_loop_starts, @@ -1119,7 +1070,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_FACE: compute_selected_mesh_data_from_poly_selection_edge_face(mesh_in, selection, - invert, edge_map, selected_poly_indices, new_loop_starts, @@ -1168,7 +1118,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_POINT: compute_selected_polygons_from_vertex_selection(mesh_in, selection, - invert, selected_poly_indices, new_loop_starts, &selected_polys_num, @@ -1177,7 +1126,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_EDGE: compute_selected_polygons_from_edge_selection(mesh_in, selection, - invert, selected_poly_indices, new_loop_starts, &selected_polys_num, @@ -1186,7 +1134,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, case ATTR_DOMAIN_FACE: compute_selected_polygons_from_poly_selection(mesh_in, selection, - invert, selected_poly_indices, new_loop_starts, &selected_polys_num, @@ -1230,8 +1177,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, static void separate_mesh_selection(GeometrySet &geometry_set, const Field<bool> &selection_field, const eAttrDomain selection_domain, - const GeometryNodeDeleteGeometryMode mode, - const bool invert) + const GeometryNodeDeleteGeometryMode mode) { const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>(); GeometryComponentFieldContext field_context{src_component, selection_domain}; @@ -1240,21 +1186,15 @@ static void separate_mesh_selection(GeometrySet &geometry_set, src_component.attribute_domain_num(selection_domain)}; evaluator.add(selection_field); evaluator.evaluate(); - const VArray_Span<bool> &selection = evaluator.get_evaluated<bool>(0); - + const VArray<bool> selection = evaluator.get_evaluated<bool>(0); /* Check if there is anything to delete. */ - bool delete_nothing = true; - for (const int i : selection.index_range()) { - if (selection[i] == invert) { - delete_nothing = false; - break; - } - } - if (delete_nothing) { + if (selection.is_single() && selection.get_internal_single()) { return; } - do_mesh_separation(geometry_set, src_component, selection, invert, selection_domain, mode); + const VArray_Span<bool> selection_span{selection}; + + do_mesh_separation(geometry_set, src_component, selection_span, selection_domain, mode); } } // namespace blender::nodes::node_geo_delete_geometry_cc @@ -1265,7 +1205,6 @@ void separate_geometry(GeometrySet &geometry_set, const eAttrDomain domain, const GeometryNodeDeleteGeometryMode mode, const Field<bool> &selection_field, - const bool invert, bool &r_is_error) { namespace file_ns = blender::nodes::node_geo_delete_geometry_cc; @@ -1273,25 +1212,25 @@ void separate_geometry(GeometrySet &geometry_set, bool some_valid_domain = false; if (geometry_set.has_pointcloud()) { if (domain == ATTR_DOMAIN_POINT) { - file_ns::separate_point_cloud_selection(geometry_set, selection_field, invert); + file_ns::separate_point_cloud_selection(geometry_set, selection_field); some_valid_domain = true; } } if (geometry_set.has_mesh()) { if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER)) { - file_ns::separate_mesh_selection(geometry_set, selection_field, domain, mode, invert); + file_ns::separate_mesh_selection(geometry_set, selection_field, domain, mode); some_valid_domain = true; } } if (geometry_set.has_curves()) { if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE)) { - file_ns::separate_curve_selection(geometry_set, selection_field, domain, invert); + file_ns::separate_curve_selection(geometry_set, selection_field, domain); some_valid_domain = true; } } if (geometry_set.has_instances()) { if (domain == ATTR_DOMAIN_INSTANCE) { - file_ns::separate_instance_selection(geometry_set, selection_field, invert); + file_ns::delete_selected_instances(geometry_set, selection_field); some_valid_domain = true; } } @@ -1341,7 +1280,11 @@ static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); - const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); + /* The node's input is a selection of elements that should be deleted, but the code is + * implemented as a separation operation that copies the selected elements to a new geometry. + * Invert the selection to avoid the need to keep track of both cases in the code. */ + const Field<bool> selection = fn::invert_boolean_field( + params.extract_input<Field<bool>>("Selection")); const NodeGeometryDeleteGeometry &storage = node_storage(params.node()); const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); @@ -1349,13 +1292,13 @@ static void node_geo_exec(GeoNodeExecParams params) if (domain == ATTR_DOMAIN_INSTANCE) { bool is_error; - separate_geometry(geometry_set, domain, mode, selection_field, true, is_error); + separate_geometry(geometry_set, domain, mode, selection, is_error); } else { geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { bool is_error; /* Invert here because we want to keep the things not in the selection. */ - separate_geometry(geometry_set, domain, mode, selection_field, true, is_error); + separate_geometry(geometry_set, domain, mode, selection, is_error); }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc index 22712c873a3..d785694f253 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc @@ -45,36 +45,29 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometrySeparateGeometry &storage = node_storage(params.node()); const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); - auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set, bool invert) { + auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set, + const Field<bool> &selection) { bool is_error; if (domain == ATTR_DOMAIN_INSTANCE) { /* Only delete top level instances. */ - separate_geometry(geometry_set, - domain, - GEO_NODE_DELETE_GEOMETRY_MODE_ALL, - selection_field, - invert, - is_error); + separate_geometry( + geometry_set, domain, GEO_NODE_DELETE_GEOMETRY_MODE_ALL, selection, is_error); } else { geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - separate_geometry(geometry_set, - domain, - GEO_NODE_DELETE_GEOMETRY_MODE_ALL, - selection_field, - invert, - is_error); + separate_geometry( + geometry_set, domain, GEO_NODE_DELETE_GEOMETRY_MODE_ALL, selection, is_error); }); } }; GeometrySet second_set(geometry_set); if (params.output_is_required("Selection")) { - separate_geometry_maybe_recursively(geometry_set, false); + separate_geometry_maybe_recursively(geometry_set, selection_field); params.set_output("Selection", std::move(geometry_set)); } if (params.output_is_required("Inverted")) { - separate_geometry_maybe_recursively(second_set, true); + separate_geometry_maybe_recursively(second_set, fn::invert_boolean_field(selection_field)); params.set_output("Inverted", std::move(second_set)); } } |