GPv3: Curve to Mesh node #113659

Manually merged
Dalai Felinto merged 86 commits from dfelinto/blender:grease-nodes-curve-to-mesh into main 2023-10-16 11:49:25 +02:00
1 changed files with 46 additions and 21 deletions
Showing only changes of commit 47cfeb45d8 - Show all commits

View File

@ -10,7 +10,9 @@
#include "DNA_pointcloud_types.h"
#include "BKE_curves.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
#include "BKE_pointcloud.h"
@ -23,17 +25,15 @@
namespace blender::nodes::node_geo_delete_geometry_cc {
/** \return std::nullopt if the geometry should remain unchanged. */
static std::optional<Curves *> separate_curves_selection(
const Curves &src_curves_id,
static std::optional<bke::CurvesGeometry> separate_curves_selection(
const bke::CurvesGeometry &src_curves,
const fn::FieldContext &field_context,
const Field<bool> &selection_field,
const eAttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
{
const bke::CurvesGeometry &src_curves = src_curves_id.geometry.wrap();
const int domain_size = src_curves.attributes().domain_size(domain);
const bke::CurvesFieldContext context{src_curves, domain};
fn::FieldEvaluator evaluator{context, domain_size};
fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@ -41,23 +41,17 @@ static std::optional<Curves *> separate_curves_selection(
return std::nullopt;
}
if (selection.is_empty()) {
return nullptr;
return bke::CurvesGeometry();
}
Curves *dst_curves_id = nullptr;
if (domain == ATTR_DOMAIN_POINT) {
bke::CurvesGeometry dst_curves = bke::curves_copy_point_selection(
src_curves, selection, propagation_info);
dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
return bke::curves_copy_point_selection(src_curves, selection, propagation_info);
}
else if (domain == ATTR_DOMAIN_CURVE) {
bke::CurvesGeometry dst_curves = bke::curves_copy_curve_selection(
src_curves, selection, propagation_info);
dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
return bke::curves_copy_curve_selection(src_curves, selection, propagation_info);
}
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
return dst_curves_id;
BLI_assert_unreachable();
return std::nullopt;
}
/** \return std::nullopt if the geometry should remain unchanged. */
@ -168,16 +162,47 @@ void separate_geometry(GeometrySet &geometry_set,
some_valid_domain = true;
}
}
if (const Curves *curves_id = geometry_set.get_curves()) {
if (const Curves *src_curves_id = geometry_set.get_curves()) {
if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE)) {
std::optional<Curves *> dst_curves = file_ns::separate_curves_selection(
*curves_id, selection, domain, propagation_info);
const bke::CurvesGeometry &src_curves = src_curves_id->geometry.wrap();
const bke::CurvesFieldContext field_context{src_curves, domain};
std::optional<bke::CurvesGeometry> dst_curves = file_ns::separate_curves_selection(
src_curves, field_context, selection, domain, propagation_info);
if (dst_curves) {
geometry_set.replace_curves(*dst_curves);
if (dst_curves->points_num() == 0) {
geometry_set.remove<CurveComponent>();
}
else {
Curves *dst_curves_id = bke::curves_new_nomain(*dst_curves);
bke::curves_copy_parameters(*src_curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);
}
}
some_valid_domain = true;
}
}
if (geometry_set.get_grease_pencil()) {
using namespace blender::bke::greasepencil;
GreasePencil &grease_pencil = *geometry_set.get_grease_pencil_for_write();
for (const int layer_index : grease_pencil.layers().index_range()) {
Drawing *drawing = get_eval_grease_pencil_layer_drawing_for_write(grease_pencil,
layer_index);
if (drawing == nullptr) {
continue;
}
const bke::CurvesGeometry &src_curves = drawing->strokes();
const bke::GreasePencilLayerFieldContext field_context(
grease_pencil, ATTR_DOMAIN_CURVE, layer_index);
std::optional<bke::CurvesGeometry> dst_curves = file_ns::separate_curves_selection(
src_curves, field_context, selection, domain, propagation_info);
if (!dst_curves) {
continue;
}
drawing->strokes_for_write() = std::move(*dst_curves);
drawing->tag_topology_changed();
some_valid_domain = true;
}
}
if (geometry_set.has_instances()) {
if (domain == ATTR_DOMAIN_INSTANCE) {
file_ns::delete_selected_instances(geometry_set, selection, propagation_info);