Blender V5.0
node_geo_edge_paths_to_curves.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_curves.hh"
6
7#include "DNA_mesh_types.h"
8
10#include "GEO_mesh_to_curve.hh"
11
12#include "node_geometry_util.hh"
13
15
17{
18 b.add_input<decl::Geometry>("Mesh")
19 .supported_type(GeometryComponent::Type::Mesh)
20 .description("Edges to convert to curves");
21 b.add_input<decl::Bool>("Start Vertices").default_value(true).hide_value().field_on_all();
22 b.add_input<decl::Int>("Next Vertex Index").default_value(-1).hide_value().field_on_all();
23 b.add_output<decl::Geometry>("Curves").propagate_all();
24}
25
27 const IndexMask &start_verts_mask,
28 const Span<int> next_indices,
29 const AttributeFilter &attribute_filter)
30{
31 Vector<int> vert_indices;
32 Vector<int> curve_offsets;
33 Array<bool> visited(mesh.verts_num, false);
34 start_verts_mask.foreach_index([&](const int first_vert) {
35 const int second_vert = next_indices[first_vert];
36 if (first_vert == second_vert) {
37 return;
38 }
39 if (second_vert < 0 || second_vert >= mesh.verts_num) {
40 return;
41 }
42
43 curve_offsets.append(vert_indices.size());
44
45 /* Iterate through path defined by #next_indices. */
46 int current_vert = first_vert;
47 while (!visited[current_vert]) {
48 visited[current_vert] = true;
49 vert_indices.append(current_vert);
50 const int next_vert = next_indices[current_vert];
51 if (next_vert < 0 || next_vert >= mesh.verts_num) {
52 break;
53 }
54 current_vert = next_vert;
55 }
56
57 /* Reset visited status. */
58 const int points_in_curve_num = vert_indices.size() - curve_offsets.last();
59 for (const int vert_in_curve : vert_indices.as_span().take_back(points_in_curve_num)) {
60 visited[vert_in_curve] = false;
61 }
62 });
63
64 if (vert_indices.is_empty()) {
65 return nullptr;
66 }
68 mesh.attributes(), vert_indices, curve_offsets, IndexRange(0), attribute_filter));
69 return curves_id;
70}
71
73{
74 GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
75
76 geometry::foreach_real_geometry(geometry_set, [&](GeometrySet &geometry_set) {
77 const Mesh *mesh = geometry_set.get_mesh();
78 if (mesh == nullptr) {
79 geometry_set.keep_only({GeometryComponent::Type::Edit});
80 return;
81 }
82
83 const bke::MeshFieldContext context{*mesh, AttrDomain::Point};
84 fn::FieldEvaluator evaluator{context, mesh->verts_num};
85 evaluator.add(params.get_input<Field<int>>("Next Vertex Index"));
86 evaluator.add(params.get_input<Field<bool>>("Start Vertices"));
87 evaluator.evaluate();
88 const VArraySpan<int> next_vert = evaluator.get_evaluated<int>(0);
89 IndexMask start_verts = evaluator.get_evaluated_as_mask(1);
90
91 if (start_verts.is_empty()) {
92 geometry_set.keep_only({GeometryComponent::Type::Edit});
93 return;
94 }
95
97 *mesh, start_verts, next_vert, params.get_attribute_filter("Curves")));
98 geometry_set.keep_only({GeometryComponent::Type::Curve, GeometryComponent::Type::Edit});
99 });
100
101 params.set_output("Curves", std::move(geometry_set));
102}
103
104static void node_register()
105{
106 static blender::bke::bNodeType ntype;
107
108 geo_node_type_base(&ntype, "GeometryNodeEdgePathsToCurves", GEO_NODE_EDGE_PATHS_TO_CURVES);
109 ntype.ui_name = "Edge Paths to Curves";
110 ntype.ui_description = "Output curves following paths across mesh edges";
111 ntype.enum_name_legacy = "EDGE_PATHS_TO_CURVES";
113 ntype.declare = node_declare;
116}
118
119} // namespace blender::nodes::node_geo_edge_paths_to_curves_cc
Low-level operations for curves.
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_EDGE_PATHS_TO_CURVES
#define NOD_REGISTER_NODE(REGISTER_FUNC)
AttributeSet attributes
int64_t size() const
void append(const T &value)
const T & last(const int64_t n=0) const
bool is_empty() const
Span< T > as_span() const
int add(GField field, GVArray *varray_ptr)
Definition field.cc:751
IndexMask get_evaluated_as_mask(int field_index)
Definition field.cc:804
const GVArray & get_evaluated(const int field_index) const
Definition FN_field.hh:448
void foreach_index(Fn &&fn) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
Curves * curves_new_nomain(int points_num, int curves_num)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
bke::CurvesGeometry create_curve_from_vert_indices(const bke::AttributeAccessor &mesh_attributes, Span< int > vert_indices, Span< int > curve_offsets, IndexRange cyclic_curves, const bke::AttributeFilter &attribute_filter)
static Curves * edge_paths_to_curves_convert(const Mesh &mesh, const IndexMask &start_verts_mask, const Span< int > next_indices, const AttributeFilter &attribute_filter)
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
int verts_num
void keep_only(Span< GeometryComponent::Type > component_types)
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Mesh * get_mesh() const
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362