MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TopologyOperator.cpp
Go to the documentation of this file.
3
5
6//-----------------------------------------------------------------------------
7// Construction
8//-----------------------------------------------------------------------------
9
11 : m_default_mode(mode)
12{
14 "TopologyOperator created with mode {}", static_cast<int>(mode));
15}
16
17//-----------------------------------------------------------------------------
18// GraphicsOperator Interface (Simple Initialization)
19//-----------------------------------------------------------------------------
20
21void TopologyOperator::initialize(const std::vector<LineVertex>& vertices)
22{
23 if (vertices.empty()) {
25 "Cannot initialize topology with zero vertices");
26 return;
27 }
28
29 m_topologies.clear();
31
33 "TopologyOperator initialized with {} points in 1 topology",
34 vertices.size());
35}
36
37//-----------------------------------------------------------------------------
38// Advanced Initialization (Multiple Topologies)
39//-----------------------------------------------------------------------------
40
42 const std::vector<std::vector<LineVertex>>& topologies,
44{
45 for (const auto& topo : topologies) {
46 add_topology(topo, mode);
47 }
48
50 "TopologyOperator initialized with {} topologies",
51 topologies.size());
52}
53
55 const std::vector<LineVertex>& vertices,
57{
58 if (vertices.empty()) {
60 "Cannot add topology with zero vertices");
61 return;
62 }
63
64 auto topology = std::make_shared<GpuSync::TopologyGeneratorNode>(mode, 1024);
65
66 topology->set_points(vertices);
67 topology->compute_frame();
68
69 uint32_t expected = 0;
70 while (!m_access_token.compare_exchange_weak(expected, 1,
71 std::memory_order_acquire, std::memory_order_relaxed)) {
72 if (m_shutdown.load(std::memory_order_relaxed))
73 return;
74 expected = 0;
75 }
76
77 m_topologies.push_back(std::move(topology));
78
79 m_access_token.store(0, std::memory_order_release);
80
82 "Added topology #{} with {} points, {} connections",
83 m_topologies.size(), vertices.size(),
84 m_topologies.back()->get_connection_count());
85}
86
87//-----------------------------------------------------------------------------
88// Processing
89//-----------------------------------------------------------------------------
90
91void TopologyOperator::process(float /*dt*/)
92{
93 uint32_t expected = 0;
94 while (!m_access_token.compare_exchange_weak(expected, 1,
95 std::memory_order_acquire, std::memory_order_relaxed)) {
96 if (m_shutdown.load(std::memory_order_relaxed))
97 return;
98 expected = 0;
99 }
100
101 for (auto& topology : m_topologies) {
102 topology->compute_frame();
103 }
104
105 m_access_token.store(0, std::memory_order_release);
106}
107
108//-----------------------------------------------------------------------------
109// GraphicsOperator Interface (Data Extraction)
110//-----------------------------------------------------------------------------
111
112std::vector<LineVertex> TopologyOperator::extract_vertices() const
113{
114 std::vector<LineVertex> positions;
115
116 for (const auto& topology : m_topologies) {
117 auto points = topology->get_points();
118 for (const auto& pt : points) {
119 positions.push_back(pt);
120 }
121 }
122
123 return positions;
124}
125
126std::span<const uint8_t> TopologyOperator::get_vertex_data_for_collection(uint32_t idx) const
127{
128 if (m_topologies.empty() || idx >= m_topologies.size()) {
129 return {};
130 }
131 return m_topologies[idx]->get_vertex_data();
132}
133
134std::span<const uint8_t> TopologyOperator::get_vertex_data() const
135{
137 for (const auto& group : m_topologies) {
138 auto span = group->get_vertex_data();
141 span.begin(), span.end());
142 }
143 return { m_vertex_data_aggregate.data(), m_vertex_data_aggregate.size() };
144}
145
147{
148 if (m_topologies.empty()) {
149 return {};
150 }
151
152 auto layout_opt = m_topologies[0]->get_vertex_layout();
153 if (!layout_opt) {
154 return {};
155 }
156
157 auto layout = *layout_opt;
158 layout.vertex_count = static_cast<uint32_t>(get_vertex_count());
159 return layout;
160}
161
163{
164 size_t total = 0;
165 for (const auto& topology : m_topologies) {
166 total += topology->get_vertex_count();
167 }
168 return total;
169}
170
172{
173 return std::ranges::any_of(
175 [](const auto& group) { return group->needs_gpu_update(); });
176}
177
179{
180 for (auto& topology : m_topologies) {
181 topology->mark_vertex_data_dirty(false);
182 }
183}
184
186{
187 size_t total = 0;
188 for (const auto& topology : m_topologies) {
189 total += topology->get_point_count();
190 }
191 return total;
192}
193
194//-----------------------------------------------------------------------------
195// Parameter Control
196//-----------------------------------------------------------------------------
197
198void TopologyOperator::set_parameter(std::string_view param, double value)
199{
200 if (param == "connection_radius") {
201 for (auto& topology : m_topologies) {
202 topology->set_connection_radius(static_cast<float>(value));
203 }
204 } else if (param == "k_neighbors") {
205 for (auto& topology : m_topologies) {
206 topology->set_k_neighbors(static_cast<size_t>(value));
207 }
208 } else if (param == "line_thickness") {
209 m_default_thickness = static_cast<float>(value);
210 for (auto& topology : m_topologies) {
211 topology->set_line_thickness(m_default_thickness);
212 }
213 }
214}
215
216std::optional<double> TopologyOperator::query_state(std::string_view query) const
217{
218 if (query == "point_count") {
219 return static_cast<double>(get_point_count());
220 }
221
222 if (query == "connection_count") {
223 size_t total_connections = 0;
224 for (const auto& topology : m_topologies) {
225 total_connections += topology->get_connection_count();
226 }
227 return static_cast<double>(total_connections);
228 }
229
230 if (query == "topology_count") {
231 return static_cast<double>(m_topologies.size());
232 }
233 return std::nullopt;
234}
235
236//-----------------------------------------------------------------------------
237// Topology Configuration
238//-----------------------------------------------------------------------------
239
241{
242 for (auto& topology : m_topologies) {
243 topology->set_connection_radius(radius);
244 }
245}
246
248{
249 m_default_thickness = thickness;
250 for (auto& topology : m_topologies) {
251 topology->set_line_thickness(thickness);
252 }
253}
254
255void TopologyOperator::set_global_line_color(const glm::vec3& color)
256{
257 for (auto& topology : m_topologies) {
258 topology->set_line_color(color);
259 }
260}
261
263{
264 for (auto& topology : m_topologies) {
265 topology->set_samples_per_segment(samples);
266 }
267}
268
269void* TopologyOperator::get_data_at(size_t global_index)
270{
271 size_t offset = 0;
272 for (auto& group : m_topologies) {
273 if (global_index < offset + group->get_point_count()) {
274 size_t local_index = global_index - offset;
275 return &group->get_points()[local_index];
276 }
277 offset += group->get_point_count();
278 }
279 return nullptr;
280}
281
282} // namespace MayaFlux::Nodes::Network
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
void * get_data_at(size_t global_index) override
Get mutable access to point at global index.
void set_samples_per_segment(size_t samples)
Set number of samples per segment for interpolation for all topologies.
void add_topology(const std::vector< LineVertex > &vertices, Kinesis::ProximityMode mode)
Add a single topology with full per-vertex control.
std::span< const uint8_t > get_vertex_data_for_collection(uint32_t idx) const override
Get vertex data for specific collection (if multiple)
void initialize(const std::vector< LineVertex > &vertices)
Initialize a single topology with single set of vertices.
void process(float dt) override
Process for one batch cycle.
bool is_vertex_data_dirty() const override
Check if geometry changed this frame.
void set_parameter(std::string_view param, double value) override
Set operator parameter.
void set_connection_radius(float radius)
Set the connection radius for topology generation.
size_t get_vertex_count() const override
Get number of vertices (may differ from point count for topology/path)
std::vector< LineVertex > extract_vertices() const
Extract current vertex data as LineVertex array.
void set_global_line_color(const glm::vec3 &color)
Set the line color for all topologies.
Kakshya::VertexLayout get_vertex_layout() const override
Get vertex layout describing vertex structure.
std::vector< std::shared_ptr< GpuSync::TopologyGeneratorNode > > m_topologies
std::span< const uint8_t > get_vertex_data() const override
Get vertex data for GPU upload.
void set_global_line_thickness(float thickness)
Set the number of neighbors (k) for K-Nearest topology mode.
void mark_vertex_data_clean() override
Clear dirty flag after GPU upload.
size_t get_point_count() const override
Get source point count (before topology expansion)
void initialize_topologies(const std::vector< std::vector< LineVertex > > &topologies, Kinesis::ProximityMode mode)
Initialize multiple topologies with given positions and properties.
std::optional< double > query_state(std::string_view query) const override
Query operator internal state.
TopologyOperator(Kinesis::ProximityMode mode=Kinesis::ProximityMode::K_NEAREST)
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
uint32_t vertex_count
Total number of vertices in this buffer.
Complete description of vertex data layout in a buffer.