Blender  V3.3
node_geo_edge_paths_to_curves.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BKE_curves.hh"
4 
5 #include "DNA_mesh_types.h"
6 #include "DNA_meshdata_types.h"
7 
8 #include "GEO_mesh_to_curve.hh"
9 
10 #include "node_geometry_util.hh"
11 
13 
15 {
16  b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
17  b.add_input<decl::Bool>(N_("Start Vertices")).default_value(true).hide_value().supports_field();
18  b.add_input<decl::Int>(N_("Next Vertex Index")).default_value(-1).hide_value().supports_field();
19  b.add_output<decl::Geometry>(N_("Curves"));
20 }
21 
23  const IndexMask start_verts_mask,
24  const Span<int> next_indices)
25 {
26  const Span<MVert> mvert{mesh.mvert, mesh.totvert};
27  Vector<int> vert_indices;
28  Vector<int> curve_offsets;
30  for (const int first_vert : start_verts_mask) {
31  const int second_vert = next_indices[first_vert];
32  if (first_vert == second_vert) {
33  continue;
34  }
35  if (second_vert < 0 || second_vert >= mesh.totvert) {
36  continue;
37  }
38 
39  curve_offsets.append(vert_indices.size());
40 
41  /* Iterate through path defined by #next_indices. */
42  int current_vert = first_vert;
43  while (!visited[current_vert]) {
44  visited[current_vert] = true;
45  vert_indices.append(current_vert);
46  const int next_vert = next_indices[current_vert];
47  if (next_vert < 0 || next_vert >= mesh.totvert) {
48  break;
49  }
50  current_vert = next_vert;
51  }
52 
53  /* Reset visited status. */
54  const int points_in_curve_num = vert_indices.size() - curve_offsets.last();
55  for (const int vert_in_curve : vert_indices.as_span().take_back(points_in_curve_num)) {
56  visited[vert_in_curve] = false;
57  }
58  }
59 
60  if (vert_indices.is_empty()) {
61  return nullptr;
62  }
63  Curves *curves_id = bke::curves_new_nomain(
64  geometry::create_curve_from_vert_indices(mesh, vert_indices, curve_offsets, IndexRange(0)));
65  return curves_id;
66 }
67 
69 {
70  GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
71 
72  geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
73  if (!geometry_set.has_mesh()) {
75  return;
76  }
77 
80  fn::FieldEvaluator evaluator{context, component.attribute_domain_size(ATTR_DOMAIN_POINT)};
81  evaluator.add(params.get_input<Field<int>>("Next Vertex Index"));
82  evaluator.add(params.get_input<Field<bool>>("Start Vertices"));
83  evaluator.evaluate();
84  const VArraySpan<int> next_vert = evaluator.get_evaluated<int>(0);
85  IndexMask start_verts = evaluator.get_evaluated_as_mask(1);
86 
87  if (start_verts.is_empty()) {
89  return;
90  }
91 
92  const Mesh &mesh = *component.get_for_read();
93  geometry_set.replace_curves(edge_paths_to_curves_convert(mesh, start_verts, next_vert));
95  });
96 
97  params.set_output("Curves", std::move(geometry_set));
98 }
99 
100 } // namespace blender::nodes::node_geo_edge_paths_to_curves_cc
101 
103 {
105 
106  static bNodeType ntype;
107 
109  &ntype, GEO_NODE_EDGE_PATHS_TO_CURVES, "Edge Paths to Curves", NODE_CLASS_GEOMETRY);
112  nodeRegisterType(&ntype);
113 }
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
Low-level operations for curves.
@ GEO_COMPONENT_TYPE_MESH
@ GEO_COMPONENT_TYPE_INSTANCES
@ GEO_COMPONENT_TYPE_CURVE
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
#define GEO_NODE_EDGE_PATHS_TO_CURVES
Definition: BKE_node.h:1510
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
constexpr Span take_back(int64_t n) const
Definition: BLI_span.hh:192
int64_t size() const
Definition: BLI_vector.hh:694
void append(const T &value)
Definition: BLI_vector.hh:433
const T & last(const int64_t n=0) const
Definition: BLI_vector.hh:663
Span< T > as_span() const
Definition: BLI_vector.hh:325
bool is_empty() const
Definition: BLI_vector.hh:706
Set< ComponentNode * > visited
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
Curves * curves_new_nomain(int points_num, int curves_num)
Definition: curves.cc:367
bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, Span< int > vert_indices, Span< int > curve_offsets, IndexRange cyclic_curves)
static Curves * edge_paths_to_curves_convert(const Mesh &mesh, const IndexMask start_verts_mask, const Span< int > next_indices)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_geo_edge_paths_to_curves()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const GeometryComponent * get_component_for_read(GeometryComponentType component_type) const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void keep_only(const blender::Span< GeometryComponentType > component_types)
bool has_mesh() const
struct MVert * mvert
int totvert
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)