MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TopologyOperator.hpp
Go to the documentation of this file.
1#pragma once
4
6
7class MAYAFLUX_API TopologyOperator : public GraphicsOperator {
8public:
9 explicit TopologyOperator(
10 Kinesis::ProximityMode mode = Kinesis::ProximityMode::K_NEAREST);
11
12 ~TopologyOperator() override { m_shutdown.store(true, std::memory_order_release); }
13
14 /**
15 * @brief Initialize a single topology with single set of vertices
16 */
17 void initialize(const std::vector<LineVertex>& vertices);
18
19 /**
20 * @brief Initialize multiple topologies with given positions and properties.
21 * @param topologies Vector of position vectors, one per topology.
22 * @param mode Proximity mode for all topologies.
23 */
24 void initialize_topologies(
25 const std::vector<std::vector<LineVertex>>& topologies,
27
28 /**
29 * @brief Add a single topology with full per-vertex control.
30 * @param vertices Vector of LineVertex defining the topology's points and attributes.
31 * @param mode Proximity mode for this topology.
32 */
33 void add_topology(
34 const std::vector<LineVertex>& vertices,
36
37 void process(float dt) override;
38
39 [[nodiscard]] std::span<const uint8_t> get_vertex_data() const override;
40 [[nodiscard]] std::span<const uint8_t> get_vertex_data_for_collection(uint32_t idx) const override;
41 [[nodiscard]] Kakshya::VertexLayout get_vertex_layout() const override;
42 [[nodiscard]] size_t get_vertex_count() const override;
43 [[nodiscard]] bool is_vertex_data_dirty() const override;
44 void mark_vertex_data_clean() override;
45
46 /**
47 * @brief One DirtyVertexRange per topology whose TopologyGeneratorNode
48 * needs a GPU update, so add_topology() or a point edit on one
49 * graph re-uploads only that graph's expanded line vertices.
50 *
51 * Ranges are in add_topology() order, matching get_vertex_data() and
52 * build_cluster_ids(); group_index is the topology index and feeds
53 * get_vertex_data_for_collection(). Empty when no topology changed. A
54 * point edit within one graph still re-uploads that whole graph's range,
55 * since its connectivity rebuild is global; isolation here is across
56 * graphs, not within one.
57 */
58 [[nodiscard]] std::vector<DirtyVertexRange> dirty_vertex_ranges() const override;
59
60 /**
61 * @brief True: point edits, add_topology() and every proximity-parameter
62 * change route through a TopologyGeneratorNode dirty flag, so
63 * per-graph ranges are complete. Isolation is across graphs only;
64 * a change inside one graph re-uploads that graph's whole range.
65 */
66 [[nodiscard]] bool supports_incremental_upload() const override { return true; }
67
68 /**
69 * @brief Extract current vertex data as LineVertex array
70 * @return Vector of LineVertex with current positions, colors, thicknesses
71 */
72 [[nodiscard]] std::vector<LineVertex> extract_vertices() const;
73
74 void set_parameter(std::string_view param, double value) override;
75 [[nodiscard]] std::optional<double> query_state(std::string_view query) const override;
76 [[nodiscard]] std::string_view get_type_name() const override { return "Topology"; }
77 [[nodiscard]] size_t get_point_count() const override;
78
79 /**
80 * @brief Overrides GraphicsOperator::build_cluster_ids() for real
81 * multi-topology scenes.
82 * @return get_vertex_count() elements: entry i is the index of the
83 * topology (in initialize_topologies()/add_topology() order)
84 * vertex i belongs to, in the same concatenation order
85 * get_vertex_data() itself produces. All zero when there is at
86 * most one topology, matching the base class default exactly.
87 *
88 * A single TopologyOperator holding several independent topologies
89 * (initialize_topologies/add_topology, each its own connected MST/KNN
90 * graph) is the same "many complete vertex-array packs" shape
91 * PhysicsOperator's collections are. Overriding this is what lets a
92 * cluster-scoped GpuFieldOperator binding, or the spatial hash's own
93 * cluster guard, treat each topology as its own population without a
94 * dynamic_cast anywhere in the buffer layer.
95 */
96 [[nodiscard]] std::vector<uint32_t> build_cluster_ids() const override;
97
98 /**
99 * @brief Forwards to the first topology's own get_primitive_topology().
100 * @return nullopt when there is no topology yet; otherwise
101 * m_topologies[0]->get_primitive_topology()
102 * (TopologyGeneratorNode defaults to LINE_LIST: expanded edges,
103 * not one continuous strip through the whole graph). Same
104 * first-element choice get_vertex_layout() already makes for
105 * the aggregate.
106 */
107 [[nodiscard]] std::optional<Portal::Graphics::PrimitiveTopology> declared_topology() const override;
108
109 /**
110 * @brief Coalesces adjacent topology graphs sharing a concatenable topology
111 * into one run. Strip and fan graphs are always reported separately.
112 */
113 std::vector<DrawRun> topology_runs() const override;
114
115 /**
116 * @brief Access a specific topology node directly.
117 * @param i Collection index.
118 * @return Shared pointer to the TopologyGeneratorNode, or nullptr if out of range.
119 */
120 [[nodiscard]] std::shared_ptr<GpuSync::TopologyGeneratorNode> get_topology(size_t i) const
121 {
122 if (i >= m_topologies.size()) {
123 return nullptr;
124 }
125 return m_topologies[i];
126 }
127
128 /**
129 * @brief Set the connection radius for topology generation.
130 * @param radius Connection radius.
131 */
132 void set_connection_radius(float radius);
133
134 /**
135 * @brief Set the number of neighbors (k) for K-Nearest topology mode.
136 * @param k Number of neighbors.
137 */
138 void set_global_line_thickness(float thickness);
139
140 /**
141 * @brief Set the line color for all topologies.
142 * @param color RGB color.
143 */
144 void set_global_line_color(const glm::vec3& color);
145
146 /**
147 * @brief Replace every point, in extract_vertices() order, keeping the topologies.
148 * @param vertices One vertex per point across all topologies.
149 *
150 * When the count differs from the current total this falls back to initialize().
151 */
152 void set_vertices(const std::vector<LineVertex>& vertices);
153
154 /**
155 * @brief Set number of samples per segment for interpolation for all topologies.
156 * @param samples Number of samples to generate per connection segment
157 *
158 * Higher values produce smoother curves but increase vertex count.
159 */
160 void set_samples_per_segment(size_t samples);
161
162 /**
163 * @brief Get number of topologies currently stored
164 * @return Topology count
165 */
166 [[nodiscard]] size_t get_topology_count() const { return m_topologies.size(); }
167
168 const char* get_vertex_type_name() const override { return "PathVertex"; }
169
170protected:
171 void* get_data_at(size_t global_index) override;
172
173private:
174 std::vector<std::shared_ptr<GpuSync::TopologyGeneratorNode>> m_topologies;
175
176 mutable std::vector<uint8_t> m_vertex_data_aggregate;
177
179
180 mutable std::atomic<uint32_t> m_access_token { 0 };
181 std::atomic<bool> m_shutdown { false };
182};
183
184} // namespace MayaFlux::Nodes::Network
glm::vec3 color
Definition Decoder.cpp:97
float radius
uint32_t mode
glm::vec3 value
Operator that produces GPU-renderable geometry.
size_t get_topology_count() const
Get number of topologies currently stored.
std::string_view get_type_name() const override
Type name for introspection.
bool supports_incremental_upload() const override
True: point edits, add_topology() and every proximity-parameter change route through a TopologyGenera...
const char * get_vertex_type_name() const override
Get human-readable vertex type name (for validation/debugging)
std::vector< std::shared_ptr< GpuSync::TopologyGeneratorNode > > m_topologies
std::shared_ptr< GpuSync::TopologyGeneratorNode > get_topology(size_t i) const
Access a specific topology node directly.
void initialize()
Definition main.cpp:10
Complete description of vertex data layout in a buffer.