MayaFlux 0.5.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, true, 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
185std::vector<GraphicsOperator::DirtyVertexRange> TopologyOperator::dirty_vertex_ranges() const
186{
187 std::vector<DirtyVertexRange> ranges;
188
189 uint32_t offset = 0;
190 uint32_t index = 0;
191 for (const auto& topology : m_topologies) {
192 const auto count = static_cast<uint32_t>(topology->get_vertex_count());
193 if (topology->needs_gpu_update()) {
194 ranges.push_back(DirtyVertexRange {
196 .vertex_offset = offset,
197 .vertex_count = count });
198 }
199 offset += count;
200 ++index;
201 }
202
203 return ranges;
204}
205
207{
208 size_t total = 0;
209 for (const auto& topology : m_topologies) {
210 total += topology->get_point_count();
211 }
212 return total;
213}
214
215std::vector<uint32_t> TopologyOperator::build_cluster_ids() const
216{
217 std::vector<uint32_t> ids(get_vertex_count(), 0U);
218
219 if (m_topologies.size() <= 1) {
220 return ids;
221 }
222
223 size_t offset = 0;
224 uint32_t cluster = 0;
225 for (const auto& topology : m_topologies) {
226 const size_t count = topology->get_vertex_count();
227 for (size_t i = 0; i < count && offset + i < ids.size(); ++i) {
228 ids[offset + i] = cluster;
229 }
230 offset += count;
231 ++cluster;
232 }
233
234 return ids;
235}
236
237//-----------------------------------------------------------------------------
238// Parameter Control
239//-----------------------------------------------------------------------------
240
241void TopologyOperator::set_parameter(std::string_view param, double value)
242{
243 if (param == "connection_radius") {
244 for (auto& topology : m_topologies) {
245 topology->set_connection_radius(static_cast<float>(value));
246 }
247 } else if (param == "k_neighbors") {
248 for (auto& topology : m_topologies) {
249 topology->set_k_neighbors(static_cast<size_t>(value));
250 }
251 } else if (param == "line_thickness") {
252 m_default_thickness = static_cast<float>(value);
253 for (auto& topology : m_topologies) {
254 topology->set_line_thickness(m_default_thickness);
255 }
256 }
257}
258
259std::optional<double> TopologyOperator::query_state(std::string_view query) const
260{
261 if (query == "point_count") {
262 return static_cast<double>(get_point_count());
263 }
264
265 if (query == "connection_count") {
266 size_t total_connections = 0;
267 for (const auto& topology : m_topologies) {
268 total_connections += topology->get_connection_count();
269 }
270 return static_cast<double>(total_connections);
271 }
272
273 if (query == "topology_count") {
274 return static_cast<double>(m_topologies.size());
275 }
276 return std::nullopt;
277}
278
279//-----------------------------------------------------------------------------
280// Topology Configuration
281//-----------------------------------------------------------------------------
282
284{
285 for (auto& topology : m_topologies) {
286 topology->set_connection_radius(radius);
287 }
288}
289
291{
292 m_default_thickness = thickness;
293 for (auto& topology : m_topologies) {
294 topology->set_line_thickness(thickness);
295 }
296}
297
298void TopologyOperator::set_global_line_color(const glm::vec3& color)
299{
300 for (auto& topology : m_topologies) {
301 topology->set_line_color(color);
302 }
303}
304
306{
307 for (auto& topology : m_topologies) {
308 topology->set_samples_per_segment(samples);
309 }
310}
311
312void* TopologyOperator::get_data_at(size_t global_index)
313{
314 size_t offset = 0;
315 for (auto& group : m_topologies) {
316 if (global_index < offset + group->get_point_count()) {
317 size_t local_index = global_index - offset;
318 return &group->get_points()[local_index];
319 }
320 offset += group->get_point_count();
321 }
322 return nullptr;
323}
324
325} // namespace MayaFlux::Nodes::Network
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
float radius
uint32_t index
Definition VKDevice.cpp:142
size_t count
float value
float offset
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.
std::vector< uint32_t > build_cluster_ids() const override
Overrides GraphicsOperator::build_cluster_ids() for real multi-topology scenes.
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< DirtyVertexRange > dirty_vertex_ranges() const override
One DirtyVertexRange per topology whose TopologyGeneratorNode needs a GPU update, so add_topology() o...
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.
A contiguous span of vertex records that changed since the last mark_vertex_data_clean().