MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
LineSegmentsNode.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7/**
8 * @class LineSegmentsNode
9 * @brief Accumulates discrete unconnected line segments for LINE_LIST rendering.
10 *
11 * Specialisation of PathGeneratorNode that bypasses all interpolation machinery
12 * and emits raw vertex pairs. Every two vertices in the output buffer form one
13 * independent segment; there is no continuity between segments.
14 *
15 * Intended for:
16 * - Primitives equivalent to ofDrawLine / ofDrawAxis
17 * - Differential geometry annotation (normals, tangents, curvature vectors)
18 * derived from any vertex set produced elsewhere in the graph
19 * - Explicit connectors between named positions in a PointCloudNetwork
20 *
21 * The node slots directly into PathOperator (via PathOperator::add_node) and
22 * therefore participates in PointCloudNetwork alongside PathGeneratorNodes and
23 * TopologyGeneratorNodes. The buffer/render layer distinguishes topology through
24 * get_primitive_topology(), which this class fixes to LINE_LIST.
25 *
26 * Geometric helpers (add_tangent, add_normal, add_curvature, add_axis) delegate
27 * to the corresponding Kinesis::GeometryPrimitives functions and append the
28 * resulting pairs into this node's segment list. They do not modify the source
29 * vertex set.
30 *
31 * Color and thickness state set via set_color() / set_thickness() apply to
32 * segments added through the positional overloads of add_line() and add_axis().
33 * Per-vertex overloads that accept LineVertex directly carry their own attributes.
34 *
35 * Usage (standalone):
36 * @code
37 * auto segs = std::make_shared<LineSegmentsNode>();
38 * segs->add_line({ .position = { -0.5F, 0.0F, 0.0F }, .color = { 1.0F, 0.5F, 0.0F } },
39 * { .position = { 0.5F, 0.0F, 0.0F }, .color = { 1.0F, 0.5F, 0.0F } });
40 * segs->add_normal(path->get_all_vertices(), 0.05F);
41 *
42 * auto buffer = std::make_shared<GeometryBuffer>(segs);
43 * buffer->setup_rendering({ .target_window = window,
44 * .topology = PrimitiveTopology::LINE_LIST });
45 * @endcode
46 *
47 * Usage (inside PathOperator / PointCloudNetwork):
48 * @code
49 * auto segs = std::make_shared<LineSegmentsNode>();
50 * segs->add_line(cloud_point_a, cloud_point_b);
51 *
52 * path_op->add_node(segs);
53 * network_buffer->add_chain_operator_rendering(
54 * { .topology = PrimitiveTopology::LINE_LIST, .target_window = window });
55 * @endcode
56 */
57class MAYAFLUX_API LineSegmentsNode : public PathGeneratorNode {
58public:
59 /**
60 * @brief Construct an empty segment accumulator.
61 * @param initial_capacity Initial vertex capacity (in segment endpoints, always even).
62 */
63 explicit LineSegmentsNode(size_t initial_capacity = 256);
64
65 // -------------------------------------------------------------------------
66 // Core segment API
67 // -------------------------------------------------------------------------
68
69 /**
70 * @brief Add a segment between two vertices.
71 * @param a Start vertex (position, color, thickness).
72 * @param b End vertex (position, color, thickness).
73 */
74 void add_line(const LineVertex& a, const LineVertex& b);
75
76 /**
77 * @brief Add a directed axis segment originating from a point.
78 *
79 * Emits one segment from @p origin along @p direction scaled to @p length,
80 * using current color and thickness.
81 *
82 * @param origin Base position.
83 * @param direction Unit or non-unit direction vector (not normalised internally).
84 * @param length Scalar length of the emitted segment.
85 */
86 void add_axis(const LineVertex& origin, const glm::vec3& direction, float length);
87
88 /**
89 * @brief Remove all accumulated segments and reset the vertex buffer.
90 */
91 void clear_segments();
92
93 // -------------------------------------------------------------------------
94 // Differential geometry annotation
95 // -------------------------------------------------------------------------
96
97 /**
98 * @brief Append normal segments derived from a vertex path.
99 *
100 * Delegates to Kinesis::compute_path_normals. Each normal is emitted as
101 * one LINE_LIST segment centred on the midpoint between consecutive vertices.
102 * Appends to existing segments; does not clear first.
103 *
104 * @param path_vertices Source vertices defining the path.
105 * @param length Visual length of each normal segment.
106 * @param stride Sample every stride-th vertex (default: 1).
107 */
108 void add_normal(
109 const std::vector<LineVertex>& path_vertices,
110 float length,
111 size_t stride = 1);
112
113 /**
114 * @brief Append tangent segments derived from a vertex path.
115 *
116 * Delegates to Kinesis::compute_path_tangents. Each tangent is emitted as
117 * one LINE_LIST segment centred on the source vertex.
118 * Appends to existing segments; does not clear first.
119 *
120 * @param path_vertices Source vertices defining the path.
121 * @param length Visual length of each tangent segment.
122 * @param stride Sample every stride-th vertex (default: 1).
123 */
124 void add_tangent(
125 const std::vector<LineVertex>& path_vertices,
126 float length,
127 size_t stride = 1);
128
129 /**
130 * @brief Append curvature segments derived from a vertex path.
131 *
132 * Delegates to Kinesis::compute_path_curvature. Each curvature vector is
133 * emitted as one LINE_LIST segment originating at the source vertex.
134 * Appends to existing segments; does not clear first.
135 *
136 * @param path_vertices Source vertices defining the path.
137 * @param scale Magnitude scaling factor applied to the curvature vector.
138 * @param stride Sample every stride-th vertex (default: 1).
139 */
140 void add_curvature(
141 const std::vector<LineVertex>& path_vertices,
142 float scale,
143 size_t stride = 1);
144
145 /**
146 * @brief Number of segments currently accumulated.
147 *
148 * Each segment is two vertices; this returns vertex_count / 2.
149 */
150 [[nodiscard]] size_t get_segment_count() const { return m_segments.size() / 2; }
151
152 // -------------------------------------------------------------------------
153 // GeometryWriterNode / PathGeneratorNode overrides
154 // -------------------------------------------------------------------------
155
156 /**
157 * @brief Pack accumulated segments into the GPU vertex buffer.
158 *
159 * Bypasses all PathGeneratorNode interpolation. Copies m_segments
160 * directly via set_vertices<LineVertex>.
161 */
162 void compute_frame() override;
163
164 /**
165 * @brief Returns LINE_LIST; fixed for this node type.
166 */
168 {
169 return Portal::Graphics::PrimitiveTopology::LINE_LIST;
170 }
171
172private:
173 std::vector<LineVertex> m_segments;
174
175 void append_pairs(const std::vector<LineVertex>& pairs);
176};
177
178} // namespace MayaFlux::Nodes::GpuSync
size_t a
size_t b
size_t get_segment_count() const
Number of segments currently accumulated.
Portal::Graphics::PrimitiveTopology get_primitive_topology() const override
Returns LINE_LIST; fixed for this node type.
Accumulates discrete unconnected line segments for LINE_LIST rendering.
Generates dense vertex paths from sparse control points or freehand drawing.
PrimitiveTopology
Vertex assembly primitive topology.
Vertex type for line primitives (LINE_LIST / LINE_STRIP topology)