MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
PathOperator.cpp
Go to the documentation of this file.
1#include "PathOperator.hpp"
3
5
6//-----------------------------------------------------------------------------
7// Construction
8//-----------------------------------------------------------------------------
9
12 Eigen::Index samples_per_segment)
13 : m_default_mode(mode)
14 , m_default_samples_per_segment(samples_per_segment)
15{
17 "PathOperator created with mode {}, {} samples per segment",
18 static_cast<int>(mode), samples_per_segment);
19}
20
21//-----------------------------------------------------------------------------
22// GraphicsOperator Interface (Simple Initialization)
23//-----------------------------------------------------------------------------
24
25void PathOperator::initialize(const std::vector<LineVertex>& vertices)
26{
27 if (vertices.empty()) {
29 "Cannot initialize PathOperator with zero vertices");
30 return;
31 }
32
33 m_paths.clear();
34 add_path(vertices, m_default_mode);
35
37 "PathOperator initialized with {} control vertices", vertices.size());
38}
39
40//-----------------------------------------------------------------------------
41// Advanced Initialization (Multiple Paths)
42//-----------------------------------------------------------------------------
43
45 const std::vector<std::vector<LineVertex>>& paths,
47{
48 for (const auto& path : paths) {
49 add_path(path, mode);
50 }
51
53 "PathOperator initialized with {} paths",
54 paths.size());
55}
56
58 const std::vector<LineVertex>& control_vertices,
60{
61 if (control_vertices.empty()) {
63 "Cannot add path with zero control vertices");
64 return;
65 }
66
67 auto path = std::make_shared<GpuSync::PathGeneratorNode>(
68 mode,
70 1024);
71
72 path->set_control_points(control_vertices);
73 path->set_path_thickness(m_default_thickness);
74 path->compute_frame();
75
76 m_paths.push_back(std::move(path));
77
79 "Added path #{} with {} control vertices, {} generated vertices",
80 m_paths.size(), control_vertices.size(),
81 m_paths.back()->get_generated_vertex_count());
82}
83
84//-----------------------------------------------------------------------------
85// Processing
86//-----------------------------------------------------------------------------
87
88void PathOperator::process(float /*dt*/)
89{
90 if (m_paths.empty()) {
91 return;
92 }
93
94 for (auto& path : m_paths) {
95 path->compute_frame();
96 }
97}
98
99//-----------------------------------------------------------------------------
100// GraphicsOperator Interface (Data Extraction)
101//-----------------------------------------------------------------------------
102
103std::vector<LineVertex> PathOperator::extract_vertices() const
104{
105 std::vector<LineVertex> positions;
106
107 for (const auto& path : m_paths) {
108 auto points = path->get_all_vertices();
109 for (const auto& pt : points) {
110 positions.push_back(pt);
111 }
112 }
113
114 return positions;
115}
116
117std::span<const uint8_t> PathOperator::get_vertex_data_for_collection(uint32_t idx) const
118{
119 if (m_paths.empty() || idx >= m_paths.size()) {
120 return {};
121 }
122 return m_paths[idx]->get_vertex_data();
123}
124
125std::span<const uint8_t> PathOperator::get_vertex_data() const
126{
128 for (const auto& group : m_paths) {
129 auto span = group->get_vertex_data();
132 span.begin(), span.end());
133 }
134 return { m_vertex_data_aggregate.data(), m_vertex_data_aggregate.size() };
135}
136
138{
139 if (m_paths.empty()) {
140 return {};
141 }
142
143 auto layout_opt = m_paths[0]->get_vertex_layout();
144 if (!layout_opt) {
145 return {};
146 }
147
148 return *layout_opt;
149}
150
152{
153 size_t total = 0;
154 for (const auto& path : m_paths) {
155 total += path->get_vertex_count();
156 }
157 return total;
158}
159
161{
162 return std::ranges::any_of(
163 m_paths,
164 [](const auto& group) { return group->needs_gpu_update(); });
165}
166
168{
169 for (auto& path : m_paths) {
170 path->clear_gpu_update_flag();
171 }
172}
173
175{
176 size_t total = 0;
177 for (const auto& path : m_paths) {
178 total += path->get_all_vertex_count();
179 }
180 return total;
181}
182
183//-----------------------------------------------------------------------------
184// Parameter Control
185//-----------------------------------------------------------------------------
186
187void PathOperator::set_parameter(std::string_view param, double value)
188{
189 if (param == "tension") {
190 for (auto& path : m_paths) {
191 path->set_tension(value);
192 }
193 } else if (param == "samples_per_segment") {
194 m_default_samples_per_segment = static_cast<Eigen::Index>(value);
195 for (auto& path : m_paths) {
196 path->set_samples_per_segment(static_cast<Eigen::Index>(value));
197 }
198 } else if (param == "thickness") {
199 m_default_thickness = static_cast<float>(value);
200 for (auto& path : m_paths) {
201 path->set_path_thickness(m_default_thickness);
202 }
203 }
204}
205
206std::optional<double> PathOperator::query_state(std::string_view query) const
207{
208 if (query == "control_point_count") {
209 return static_cast<double>(get_point_count());
210 }
211 if (query == "vertex_count") {
212 return static_cast<double>(get_vertex_count());
213 }
214 if (query == "path_count") {
215 return static_cast<double>(m_paths.size());
216 }
217 return std::nullopt;
218}
219
220//-----------------------------------------------------------------------------
221// Path Configuration
222//-----------------------------------------------------------------------------
223
225{
227 for (auto& path : m_paths) {
228 path->set_samples_per_segment(samples);
229 }
230}
231
232void PathOperator::set_tension(double tension)
233{
234 for (auto& path : m_paths) {
235 path->set_tension(tension);
236 }
237}
238
240{
241 m_default_thickness = thickness;
242 for (auto& path : m_paths) {
243 path->set_path_thickness(thickness);
244 }
245}
246
247void PathOperator::set_global_color(const glm::vec3& color)
248{
249 for (auto& path : m_paths) {
250 path->set_path_color(color);
251 }
252}
253
254void* PathOperator::get_data_at(size_t global_index)
255{
256 size_t offset = 0;
257 for (auto& group : m_paths) {
258 const auto& vertices = group->get_all_vertices();
259 if (global_index < offset + vertices.size()) {
260 size_t local_index = global_index - offset;
261 return const_cast<LineVertex*>(&vertices[local_index]);
262 }
263 offset += vertices.size();
264 }
265 return nullptr;
266}
267
268} // namespace MayaFlux::Nodes::Network
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void set_parameter(std::string_view param, double value) override
Set operator parameter.
void * get_data_at(size_t global_index) override
Get mutable access to point at global index.
std::vector< uint8_t > m_vertex_data_aggregate
Kinesis::InterpolationMode m_default_mode
void add_path(const std::vector< LineVertex > &control_vertices, Kinesis::InterpolationMode mode)
Add a new path with given control points and properties.
bool is_vertex_data_dirty() const override
Check if geometry changed this frame.
void initialize_paths(const std::vector< std::vector< LineVertex > > &paths, Kinesis::InterpolationMode mode)
Initialize multiple paths with given control points and properties.
std::vector< std::shared_ptr< GpuSync::PathGeneratorNode > > m_paths
void set_tension(double tension)
Set the tension parameter for all paths (if supported by mode).
size_t get_vertex_count() const override
Get number of vertices (may differ from point count for topology/path)
PathOperator(Kinesis::InterpolationMode mode=Kinesis::InterpolationMode::CATMULL_ROM, Eigen::Index samples_per_segment=32)
size_t get_point_count() const override
Get source point count (before topology expansion)
Kakshya::VertexLayout get_vertex_layout() const override
Get vertex layout describing vertex structure.
void set_samples_per_segment(Eigen::Index samples)
Set the number of samples per segment for all paths.
void set_global_color(const glm::vec3 &color)
Set the global color tint for all paths.
void initialize(const std::vector< LineVertex > &vertices)
Initialize a single path with given control points and properties.
void process(float dt) override
Process for one batch cycle.
void mark_vertex_data_clean() override
Clear dirty flag after GPU upload.
std::span< const uint8_t > get_vertex_data_for_collection(uint32_t idx) const override
Get vertex data for specific collection (if multiple)
std::vector< LineVertex > extract_vertices() const
Extract current vertex data as LineVertex array.
void set_global_thickness(float thickness)
Set the global thickness for all paths.
std::span< const uint8_t > get_vertex_data() const override
Get vertex data for GPU upload.
std::optional< double > query_state(std::string_view query) const override
Query operator internal state.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
InterpolationMode
Mathematical interpolation methods.
Complete description of vertex data layout in a buffer.