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

node_geo_curve_topology_curve_of_point.cc « nodes « geometry « nodes « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 459f45ef8fbe0b82f18d98f8e1676de403007a1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include "BKE_curves.hh"

#include "node_geometry_util.hh"

namespace blender::nodes::node_geo_curve_topology_curve_of_point_cc {

static void node_declare(NodeDeclarationBuilder &b)
{
  b.add_input<decl::Int>(N_("Point Index"))
      .implicit_field(implicit_field_inputs::index)
      .description(N_("The control point to retrieve data from"));
  b.add_output<decl::Int>(N_("Curve Index"))
      .dependent_field()
      .description(N_("The curve the control point is part of"));
  b.add_output<decl::Int>(N_("Index in Curve"))
      .dependent_field()
      .description(N_("How far along the control point is along its curve"));
}

class CurveOfPointInput final : public bke::CurvesFieldInput {
 public:
  CurveOfPointInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point Curve Index")
  {
    category_ = Category::Generated;
  }

  GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
                                 const eAttrDomain domain,
                                 const IndexMask /*mask*/) const final
  {
    if (domain != ATTR_DOMAIN_POINT) {
      return {};
    }
    return VArray<int>::ForContainer(curves.point_to_curve_map());
  }

  uint64_t hash() const override
  {
    return 413209687345908697;
  }

  bool is_equal_to(const fn::FieldNode &other) const override
  {
    if (dynamic_cast<const CurveOfPointInput *>(&other)) {
      return true;
    }
    return false;
  }

  std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/) const final
  {
    return ATTR_DOMAIN_POINT;
  }
};

class PointIndexInCurveInput final : public bke::CurvesFieldInput {
 public:
  PointIndexInCurveInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point Index in Curve")
  {
    category_ = Category::Generated;
  }

  GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
                                 const eAttrDomain domain,
                                 const IndexMask /*mask*/) const final
  {
    if (domain != ATTR_DOMAIN_POINT) {
      return {};
    }
    const Span<int> offsets = curves.offsets();
    Array<int> point_to_curve_map = curves.point_to_curve_map();
    return VArray<int>::ForFunc(
        curves.points_num(),
        [offsets, point_to_curve_map = std::move(point_to_curve_map)](const int point_i) {
          const int curve_i = point_to_curve_map[point_i];
          return point_i - offsets[curve_i];
        });
  }

  uint64_t hash() const final
  {
    return 9834765987345677;
  }

  bool is_equal_to(const fn::FieldNode &other) const final
  {
    if (dynamic_cast<const PointIndexInCurveInput *>(&other)) {
      return true;
    }
    return false;
  }

  std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
  {
    return ATTR_DOMAIN_POINT;
  }
};

static void node_geo_exec(GeoNodeExecParams params)
{
  const Field<int> point_index = params.extract_input<Field<int>>("Point Index");
  if (params.output_is_required("Curve Index")) {
    params.set_output(
        "Curve Index",
        Field<int>(std::make_shared<FieldAtIndexInput>(
            point_index, Field<int>(std::make_shared<CurveOfPointInput>()), ATTR_DOMAIN_POINT)));
  }
  if (params.output_is_required("Index in Curve")) {
    params.set_output("Index in Curve",
                      Field<int>(std::make_shared<FieldAtIndexInput>(
                          point_index,
                          Field<int>(std::make_shared<PointIndexInCurveInput>()),
                          ATTR_DOMAIN_POINT)));
  }
}

}  // namespace blender::nodes::node_geo_curve_topology_curve_of_point_cc

void register_node_type_geo_curve_topology_curve_of_point()
{
  namespace file_ns = blender::nodes::node_geo_curve_topology_curve_of_point_cc;

  static bNodeType ntype;
  geo_node_type_base(
      &ntype, GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT, "Curve of Point", NODE_CLASS_INPUT);
  ntype.geometry_node_execute = file_ns::node_geo_exec;
  ntype.declare = file_ns::node_declare;
  nodeRegisterType(&ntype);
}