diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc index 25a20c602c7..9b949f64468 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc @@ -15,42 +15,91 @@ namespace blender::nodes::node_geo_curve_subdivide_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_input("Curve").supported_type(GeometryComponent::Type::Curve); + b.add_input("Curve").supported_type( + {GeometryComponent::Type::Curve, GeometryComponent::Type::GreasePencil}); b.add_input("Cuts").default_value(1).min(0).max(1000).field_on_all().description( "The number of control points to create on the segment following each point"); b.add_output("Curve").propagate_all(); } +static Curves *subdivide_curves(const Curves &src_curves_id, + Field &cuts_field, + const AnonymousAttributePropagationInfo &propagation_info) +{ + const bke::CurvesGeometry &src_curves = src_curves_id.geometry.wrap(); + + const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_POINT}; + fn::FieldEvaluator evaluator{field_context, src_curves.points_num()}; + evaluator.add(cuts_field); + evaluator.evaluate(); + const VArray cuts = evaluator.get_evaluated(0); + + if (cuts.is_single() && cuts.get_internal_single() < 1) { + return nullptr; + } + + bke::CurvesGeometry dst_curves = geometry::subdivide_curves( + src_curves, src_curves.curves_range(), cuts, propagation_info); + + Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); + bke::curves_copy_parameters(src_curves_id, *dst_curves_id); + return dst_curves_id; +} + +static void subdivide_grease_pencil_curves( + GreasePencil &grease_pencil, + Field &cuts_field, + const AnonymousAttributePropagationInfo &propagation_info) +{ + using namespace bke::greasepencil; + 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_POINT, layer_index}; + + fn::FieldEvaluator evaluator{field_context, src_curves.points_num()}; + evaluator.add(cuts_field); + evaluator.evaluate(); + const VArray cuts = evaluator.get_evaluated(0); + + if (cuts.is_single() && cuts.get_internal_single() < 1) { + continue; + } + + bke::CurvesGeometry dst_curves = geometry::subdivide_curves( + src_curves, src_curves.curves_range(), cuts, propagation_info); + + drawing->strokes_for_write() = std::move(dst_curves); + drawing->tag_topology_changed(); + } +} + static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input("Curve"); Field cuts_field = params.extract_input>("Cuts"); - + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Curve"); GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_curves()) { - return; + if (geometry_set.has_curves()) { + const Curves &src_curves_id = *geometry_set.get_curves(); + Curves *dst_curves_id = subdivide_curves(src_curves_id, cuts_field, propagation_info); + if (dst_curves_id) { + geometry_set.replace_curves(dst_curves_id); + } } - - const Curves &src_curves_id = *geometry_set.get_curves(); - const bke::CurvesGeometry &src_curves = src_curves_id.geometry.wrap(); - - const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_POINT}; - fn::FieldEvaluator evaluator{field_context, src_curves.points_num()}; - evaluator.add(cuts_field); - evaluator.evaluate(); - const VArray cuts = evaluator.get_evaluated(0); - if (cuts.is_single() && cuts.get_internal_single() < 1) { - return; + if (geometry_set.has_grease_pencil()) { + GreasePencil &grease_pencil = *geometry_set.get_grease_pencil_for_write(); + subdivide_grease_pencil_curves(grease_pencil, cuts_field, propagation_info); } - - bke::CurvesGeometry dst_curves = geometry::subdivide_curves( - src_curves, src_curves.curves_range(), cuts, params.get_output_propagation_info("Curve")); - - Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); - bke::curves_copy_parameters(src_curves_id, *dst_curves_id); - geometry_set.replace_curves(dst_curves_id); }); params.set_output("Curve", geometry_set); }