Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc476
1 files changed, 152 insertions, 324 deletions
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 99edc4d298c..b74b4e45199 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -8,10 +8,11 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "BKE_attribute_math.hh"
+#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_pointcloud.h"
-#include "BKE_spline.hh"
#include "node_geometry_util.hh"
@@ -38,30 +39,17 @@ 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`.
*/
static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
- const GeometryComponent &in_component,
- GeometryComponent &result_component,
- const Span<AttributeDomain> domains)
+ const bke::AttributeAccessor src_attributes,
+ bke::MutableAttributeAccessor dst_attributes,
+ const Span<eAttrDomain> domains)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -70,9 +58,9 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
if (!domains.contains(attribute.domain)) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
@@ -81,11 +69,11 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
- VArray_Span<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ VArraySpan<T> span{attribute.varray.typed<T>()};
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
out_span.copy_from(span);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
@@ -94,14 +82,14 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
* the mask to `result_component`.
*/
static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKind> &attributes,
- const GeometryComponent &in_component,
- GeometryComponent &result_component,
- const AttributeDomain domain,
+ const bke::AttributeAccessor src_attributes,
+ bke::MutableAttributeAccessor dst_attributes,
+ const eAttrDomain domain,
const IndexMask mask)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -110,9 +98,9 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
if (domain != attribute.domain) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
@@ -121,23 +109,23 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
- VArray_Span<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ VArraySpan<T> span{attribute.varray.typed<T>()};
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
copy_data_based_on_mask(span, out_span, mask);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind> &attributes,
- const GeometryComponent &in_component,
- GeometryComponent &result_component,
- const AttributeDomain domain,
+ const bke::AttributeAccessor src_attributes,
+ bke::MutableAttributeAccessor dst_attributes,
+ const eAttrDomain domain,
const Span<int> index_map)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@@ -146,9 +134,9 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
if (domain != attribute.domain) {
continue;
}
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+ const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
+ GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
@@ -157,17 +145,17 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
- VArray_Span<T> span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
+ VArraySpan<T> span{attribute.varray.typed<T>()};
+ MutableSpan<T> out_span = result_attribute.span.typed<T>();
copy_data_based_on_map(span, out_span, index_map);
});
- result_attribute.save();
+ result_attribute.finish();
}
}
static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
- const GeometryComponent &in_component,
- GeometryComponent &out_component,
+ const bke::AttributeAccessor src_attributes,
+ bke::MutableAttributeAccessor dst_attributes,
const int selected_loops_num,
const Span<int> selected_poly_indices,
const Mesh &mesh_in)
@@ -183,7 +171,7 @@ static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind>
}
}
copy_attributes_based_on_mask(
- attributes, in_component, out_component, ATTR_DOMAIN_CORNER, IndexMask(indices));
+ attributes, src_attributes, dst_attributes, ATTR_DOMAIN_CORNER, IndexMask(indices));
}
static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
@@ -324,227 +312,87 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
}
}
-static void spline_copy_builtin_attributes(const Spline &spline,
- Spline &r_spline,
- const IndexMask mask)
-{
- copy_data_based_on_mask(spline.positions(), r_spline.positions(), mask);
- copy_data_based_on_mask(spline.radii(), r_spline.radii(), mask);
- copy_data_based_on_mask(spline.tilts(), r_spline.tilts(), mask);
- switch (spline.type()) {
- case CURVE_TYPE_POLY:
- break;
- case CURVE_TYPE_BEZIER: {
- const BezierSpline &src = static_cast<const BezierSpline &>(spline);
- BezierSpline &dst = static_cast<BezierSpline &>(r_spline);
- copy_data_based_on_mask(src.handle_positions_left(), dst.handle_positions_left(), mask);
- copy_data_based_on_mask(src.handle_positions_right(), dst.handle_positions_right(), mask);
- copy_data_based_on_mask(src.handle_types_left(), dst.handle_types_left(), mask);
- copy_data_based_on_mask(src.handle_types_right(), dst.handle_types_right(), mask);
- break;
- }
- case CURVE_TYPE_NURBS: {
- const NURBSpline &src = static_cast<const NURBSpline &>(spline);
- NURBSpline &dst = static_cast<NURBSpline &>(r_spline);
- copy_data_based_on_mask(src.weights(), dst.weights(), mask);
- break;
- }
- case CURVE_TYPE_CATMULL_ROM: {
- BLI_assert_unreachable();
- break;
- }
- }
-}
-
-static void copy_dynamic_attributes(const CustomDataAttributes &src,
- CustomDataAttributes &dst,
- const IndexMask mask)
-{
- src.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src_attribute = src.get_for_read(attribute_id);
- BLI_assert(src_attribute);
-
- if (!dst.create(attribute_id, meta_data.data_type)) {
- /* Since the source spline of the same type had the attribute, adding it should work.
- */
- BLI_assert_unreachable();
- }
-
- std::optional<GMutableSpan> new_attribute = dst.get_for_write(attribute_id);
- BLI_assert(new_attribute);
-
- attribute_math::convert_to_static_type(new_attribute->type(), [&](auto dummy) {
- using T = decltype(dummy);
- copy_data_based_on_mask(src_attribute->typed<T>(), new_attribute->typed<T>(), mask);
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-}
-
-/**
- * Deletes points in the spline. Those not in the mask are deleted. The spline is not split into
- * multiple newer splines.
- */
-static SplinePtr spline_delete(const Spline &spline, const IndexMask mask)
-{
- SplinePtr new_spline = spline.copy_only_settings();
- new_spline->resize(mask.size());
-
- spline_copy_builtin_attributes(spline, *new_spline, mask);
- copy_dynamic_attributes(spline.attributes, new_spline->attributes, mask);
-
- return new_spline;
-}
-
-static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve,
- const Span<bool> selection,
- const AttributeDomain selection_domain,
- const bool invert)
+static void delete_curves_selection(GeometrySet &geometry_set,
+ const Field<bool> &selection_field,
+ const eAttrDomain selection_domain)
{
- Span<SplinePtr> input_splines = input_curve.splines();
- std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>();
-
- /* Keep track of which splines were copied to the result to copy spline domain attributes. */
- Vector<int64_t> copied_splines;
-
- if (selection_domain == ATTR_DOMAIN_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) {
- output_curve->add_spline(input_splines[i]->copy());
- copied_splines.append(i);
- }
- }
- }
- else {
- /* Operates on the points in the splines themselves. */
-
- /* Reuse index vector for each spline. */
- Vector<int64_t> indices_to_copy;
-
- int selection_index = 0;
- for (const int i : input_splines.index_range()) {
- const Spline &spline = *input_splines[i];
-
- indices_to_copy.clear();
- for (const int i_point : IndexRange(spline.size())) {
- if (selection[selection_index] != invert) {
- /* Append i_point instead of selection_index because we need indices local to the spline
- * for copying. */
- indices_to_copy.append(i_point);
- }
- selection_index++;
- }
-
- /* Avoid creating an empty spline. */
- if (indices_to_copy.is_empty()) {
- continue;
- }
+ const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
+ GeometryComponentFieldContext field_context{src_component, selection_domain};
- SplinePtr new_spline = spline_delete(spline, IndexMask(indices_to_copy));
- output_curve->add_spline(std::move(new_spline));
- copied_splines.append(i);
- }
+ const int domain_num = src_component.attribute_domain_size(selection_domain);
+ fn::FieldEvaluator evaluator{field_context, domain_num};
+ evaluator.set_selection(selection_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ if (selection.is_empty()) {
+ return;
}
-
- if (copied_splines.is_empty()) {
- return {};
+ if (selection.size() == domain_num) {
+ geometry_set.remove<CurveComponent>();
+ return;
}
- output_curve->attributes.reallocate(output_curve->splines().size());
- copy_dynamic_attributes(
- input_curve.attributes, output_curve->attributes, IndexMask(copied_splines));
+ CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>();
+ Curves &curves_id = *component.get_for_write();
+ bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- return output_curve;
-}
-
-static void separate_curve_selection(GeometrySet &geometry_set,
- const Field<bool> &selection_field,
- const AttributeDomain selection_domain,
- const bool invert)
-{
- const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
- GeometryComponentFieldContext field_context{src_component, selection_domain};
-
- fn::FieldEvaluator selection_evaluator{field_context,
- src_component.attribute_domain_num(selection_domain)};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const VArray_Span<bool> &selection = 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);
- if (r_curve) {
- geometry_set.replace_curves(curve_eval_to_curves(*r_curve));
+ if (selection_domain == ATTR_DOMAIN_POINT) {
+ curves.remove_points(selection);
}
- else {
- geometry_set.replace_curves(nullptr);
+ else if (selection_domain == ATTR_DOMAIN_CURVE) {
+ curves.remove_curves(selection);
}
}
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 selection_evaluator{field_context,
- src_points.attribute_domain_num(ATTR_DOMAIN_POINT)};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const VArray_Span<bool> &selection = 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);
+ fn::FieldEvaluator evaluator{field_context, src_points.attribute_domain_size(ATTR_DOMAIN_POINT)};
+ evaluator.set_selection(selection_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ if (selection.is_empty()) {
+ geometry_set.replace_pointcloud(nullptr);
return;
}
- PointCloudComponent dst_points;
- dst_points.replace(pointcloud, GeometryOwnershipType::Editable);
+ PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
Map<AttributeIDRef, AttributeKind> attributes;
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,
+ bke::pointcloud_attributes(*src_points.get_for_read()),
+ bke::pointcloud_attributes_for_write(*pointcloud),
+ 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.instances_num()};
+ 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)
{
@@ -552,7 +400,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++;
}
@@ -566,7 +414,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)
{
@@ -577,7 +424,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++;
}
@@ -591,7 +438,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,
@@ -609,7 +455,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;
}
@@ -633,7 +479,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,
@@ -645,7 +490,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) {
@@ -671,7 +516,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)
{
@@ -679,7 +523,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++;
}
@@ -697,7 +541,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,
@@ -713,7 +556,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;
}
@@ -736,7 +579,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,
@@ -746,11 +588,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,
@@ -763,7 +604,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,
@@ -774,14 +614,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,
@@ -795,7 +634,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,
@@ -804,10 +642,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,
@@ -820,7 +657,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,
@@ -833,14 +669,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,
@@ -852,7 +686,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,
@@ -867,7 +700,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;
@@ -883,7 +716,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,
@@ -903,7 +735,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;
@@ -930,7 +762,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,
@@ -954,7 +785,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,10 +815,9 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh,
* Keep the parts of the mesh that are in the selection.
*/
static void do_mesh_separation(GeometrySet &geometry_set,
- const MeshComponent &in_component,
- const VArray_Span<bool> &selection,
- const bool invert,
- const AttributeDomain domain,
+ const Mesh &mesh_in,
+ const Span<bool> selection,
+ const eAttrDomain domain,
const GeometryNodeDeleteGeometryMode mode)
{
/* Needed in all cases. */
@@ -996,9 +826,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
int selected_polys_num = 0;
int selected_loops_num = 0;
- const Mesh &mesh_in = *in_component.get_for_read();
Mesh *mesh_out;
- MeshComponent out_component;
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
@@ -1017,7 +845,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,
@@ -1030,7 +857,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,
@@ -1043,7 +869,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,
@@ -1063,7 +888,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
0,
selected_loops_num,
selected_polys_num);
- out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
copy_masked_vertices_to_new_mesh(mesh_in, *mesh_out, vertex_map);
@@ -1072,18 +896,24 @@ static void do_mesh_separation(GeometrySet &geometry_set,
mesh_in, *mesh_out, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
- copy_attributes_based_on_map(
- attributes, in_component, out_component, ATTR_DOMAIN_POINT, vertex_map);
- copy_attributes_based_on_map(
- attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
+ copy_attributes_based_on_map(attributes,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
+ ATTR_DOMAIN_POINT,
+ vertex_map);
+ copy_attributes_based_on_map(attributes,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
+ ATTR_DOMAIN_EDGE,
+ edge_map);
copy_attributes_based_on_mask(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@@ -1098,7 +928,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,
@@ -1109,7 +938,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,
@@ -1120,7 +948,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,
@@ -1138,7 +965,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
0,
selected_loops_num,
selected_polys_num);
- out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
@@ -1147,17 +973,23 @@ static void do_mesh_separation(GeometrySet &geometry_set,
mesh_in, *mesh_out, edge_map, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
- copy_attributes(attributes, in_component, out_component, {ATTR_DOMAIN_POINT});
- copy_attributes_based_on_map(
- attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
+ copy_attributes(attributes,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
+ {ATTR_DOMAIN_POINT});
+ copy_attributes_based_on_map(attributes,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
+ ATTR_DOMAIN_EDGE,
+ edge_map);
copy_attributes_based_on_mask(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@@ -1169,7 +1001,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,
@@ -1178,7 +1009,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,
@@ -1187,7 +1017,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,
@@ -1199,7 +1028,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
}
mesh_out = BKE_mesh_new_nomain_from_template(
&mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num);
- out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
@@ -1207,16 +1035,18 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
- copy_attributes(
- attributes, in_component, out_component, {ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE});
+ copy_attributes(attributes,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
+ {ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE});
copy_attributes_based_on_mask(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
- in_component,
- out_component,
+ bke::mesh_attributes(mesh_in),
+ bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@@ -1230,32 +1060,26 @@ static void do_mesh_separation(GeometrySet &geometry_set,
static void separate_mesh_selection(GeometrySet &geometry_set,
const Field<bool> &selection_field,
- const AttributeDomain selection_domain,
- const GeometryNodeDeleteGeometryMode mode,
- const bool invert)
+ const eAttrDomain selection_domain,
+ const GeometryNodeDeleteGeometryMode mode)
{
const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>();
GeometryComponentFieldContext field_context{src_component, selection_domain};
- fn::FieldEvaluator selection_evaluator{field_context,
- src_component.attribute_domain_num(selection_domain)};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const VArray_Span<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
-
+ fn::FieldEvaluator evaluator{field_context,
+ src_component.attribute_domain_size(selection_domain)};
+ evaluator.add(selection_field);
+ evaluator.evaluate();
+ 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_empty() || (selection.is_single() && selection.get_internal_single())) {
return;
}
- do_mesh_separation(geometry_set, src_component, selection, invert, selection_domain, mode);
+ const VArraySpan<bool> selection_span{selection};
+
+ do_mesh_separation(
+ geometry_set, *src_component.get_for_read(), selection_span, selection_domain, mode);
}
} // namespace blender::nodes::node_geo_delete_geometry_cc
@@ -1263,10 +1087,9 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
namespace blender::nodes {
void separate_geometry(GeometrySet &geometry_set,
- const AttributeDomain domain,
+ 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;
@@ -1274,25 +1097,26 @@ 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::delete_curves_selection(
+ geometry_set, fn::invert_boolean_field(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;
}
}
@@ -1320,7 +1144,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
const bNode *node = static_cast<bNode *>(ptr->data);
const NodeGeometryDeleteGeometry &storage = node_storage(*node);
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
/* Only show the mode when it is relevant. */
@@ -1342,21 +1166,25 @@ 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 AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+ const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain);
const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode;
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);
});
}