12 return num_points >= 2;
14 return num_points >= 3;
16 return num_points >= 4;
19 return num_points >= 5;
21 return num_points == 4;
34 , m_max_points(max_points)
35 , m_auto_connect(auto_connect)
43 layout.vertex_count = 0;
51 "Created TopologyGeneratorNode with mode {}, auto_connect={}, capacity={}",
52 static_cast<int>(
mode), auto_connect, max_points);
60 , m_mode(Kinesis::ProximityMode::CUSTOM)
61 , m_custom_func(
std::move(custom_func))
62 , m_max_points(max_points)
63 , m_auto_connect(auto_connect)
71 layout.vertex_count = 0;
79 "Created TopologyGeneratorNode with custom function");
116 for (
const auto& pt :
points) {
132 std::span<const LineVertex>
points,
139 const size_t num_segments = num_points - 1;
141 const auto span =
static_cast<float>(
count - 1);
143 for (
size_t i = 0; i + 1 <
count; ++i) {
144 const float t0 =
static_cast<float>(i) / span;
145 const float t1 =
static_cast<float>(i + 1) / span;
147 const auto s0 = std::min<size_t>(
148 static_cast<size_t>(t0 *
static_cast<float>(num_segments)), num_segments - 1);
149 const auto s1 = std::min<size_t>(
150 static_cast<size_t>(t1 *
static_cast<float>(num_segments)), num_segments - 1);
169 const size_t num_points =
m_points.size();
184 "Point index {} out of range",
index);
202 "Point index {} out of range",
index);
221 "TopologyGeneratorNode: {} points exceed the capacity of {}, keeping the newest {}",
332 "Point index {} out of range",
index);
334 return default_point;
372 const size_t num_points =
m_points.size();
402 layout->vertex_count =
static_cast<uint32_t
>(
m_vertices.size());
408 std::span<LineVertex>
points,
414 for (
size_t i = 0; i < num_points; ++i) {
420 const size_t num_segments = num_points - 1;
421 const auto total_samples =
static_cast<Eigen::Index
>(
435 const auto count =
static_cast<size_t>(total_samples);
442 const double* x = curve->data();
443 const double* y = x +
count;
444 const double* z = y +
count;
451 const double* ty = tx +
count;
452 const double* tz = ty +
count;
454 const auto sample = [&](
size_t s) {
456 static_cast<float>(x[s]),
static_cast<float>(y[s]),
static_cast<float>(z[s])
460 const auto tangent = [&](
size_t s) {
462 static_cast<float>(tx[s]),
static_cast<float>(ty[s]),
static_cast<float>(tz[s])
466 for (
size_t i = 0; i + 1 <
count; ++i) {
469 m_vertices[i * 2 + 1].position = sample(i + 1);
477 std::span<LineVertex>
points,
480 size_t valid_connections = std::ranges::count_if(
m_connections,
481 [num_points](
const auto& conn) {
482 return conn.first < num_points && conn.second < num_points;
489 if (
a >= num_points ||
b >= num_points) {
504 .thickness = thick_a,
510 .thickness = thick_b,
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
void evaluate_planar(std::span< const double > control_points, size_t dim, Eigen::Index num_samples, std::vector< double > &out, std::vector< double > &tangents)
Evaluate a curve into coordinate-major position and tangent buffers.
void reparameterize_planar(std::span< const double > points, size_t dim, Eigen::Index point_count, Eigen::Index num_samples, std::vector< double > &out)
Resample a polyline to uniform arc length, coordinate-major.
void configure(InterpolationMode mode, double tension)
Re-resolve the kernel.
bool m_vertex_data_dirty
Flag: vertex data or layout changed since last GPU upload.
Portal::Graphics::PrimitiveTopology m_primitive_topology
std::optional< Kakshya::VertexLayout > get_vertex_layout() const
Get cached vertex layout.
void set_vertex_layout(const Kakshya::VertexLayout &layout)
Set cached vertex layout.
void resize_vertex_buffer(uint32_t vertex_count, bool preserve_data=false)
Resize vertex buffer to hold specified number of vertices.
void set_vertex_stride(size_t stride)
Set vertex stride (bytes per vertex)
bool m_needs_layout_update
Flag indicating if layout needs update.
Base class for nodes that generate 3D geometry data.
void set_line_color(const glm::vec3 &color, bool force_uniform=true)
Set line color (applied to all connections)
void force_uniform_color(bool should_force)
Force uniform color for all vertices.
std::vector< LineVertex > m_vertices
void add_points(std::span< const LineVertex > points)
Append several points, regenerating connections once.
std::function< std::vector< std::pair< size_t, size_t > >(const Eigen::MatrixXd &)> CustomConnectionFunction
void add_point(const LineVertex &point)
Add point to topology.
void set_path_interpolation_mode(Kinesis::InterpolationMode mode)
Set custom connection function (for CUSTOM mode)
void refresh_attributes()
Rewrite colour and thickness over existing positions.
Kinesis::CurveEvaluator m_evaluator
void set_line_thickness(float thickness, bool force_uniform=true)
Set line thickness.
CustomConnectionFunction m_custom_func
void regenerate_topology()
Manually trigger connection regeneration.
void build_direct_connections(std::span< LineVertex > points, size_t num_points)
std::vector< std::pair< size_t, size_t > > m_connections
void set_samples_per_segment(size_t samples)
Set number of samples per segment for interpolation.
void build_interpolated_path(std::span< LineVertex > points, size_t num_points)
std::vector< double > m_curve_primary
void remove_point(size_t index)
Remove point by index.
Eigen::MatrixXd m_positions
void set_arc_length_reparameterization(bool enable)
Enable or disable arc-length reparameterization for interpolation.
std::vector< double > m_control_scratch
void set_k_neighbors(size_t k)
Set K parameter for K_NEAREST mode.
std::vector< double > m_curve_secondary
void force_uniform_thickness(bool should_force)
Force uniform thickness for all vertices.
bool m_force_uniform_color
If true, all vertices use m_line_color instead of per-vertex color.
void build_vertex_buffer()
float m_connection_radius
void refresh_positions()
Refill m_positions from m_points, in place.
void set_points(const std::vector< LineVertex > &points)
Set all points at once.
std::vector< LineVertex > m_points
Points, newest first: index 0 is the most recently added.
Kinesis::ProximityMode m_mode
void compute_frame() override
Compute frame - generates vertex data from points and connections.
TopologyGeneratorNode(Kinesis::ProximityMode mode=Kinesis::ProximityMode::SEQUENTIAL, bool auto_connect=true, size_t max_points=256)
Create topology generator.
void set_connection_mode(Kinesis::ProximityMode mode)
Set connection mode.
void write_path_attributes(std::span< const LineVertex > points, size_t num_points)
Write colour and thickness for the interpolated path.
size_t m_samples_per_segment
Controls smoothness vs performance.
bool m_force_uniform_thickness
If true, all vertices use m_line_thickness instead of per-vertex thickness.
bool m_use_arc_length_reparameterization
Optional constant-speed.
const LineVertex & get_point(size_t index) const
Get point by index.
void update_point(size_t index, const LineVertex &point)
Update point data.
void set_auto_connect(bool enable)
Enable/disable automatic connection regeneration.
Kinesis::InterpolationMode m_path_interpolation_mode
void set_connection_radius(float radius)
Set radius for RADIUS_THRESHOLD mode.
std::vector< double > m_curve_tangents
std::vector< LineVertex > get_points() const
Get all points.
void clear()
Clear all points and connections.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
InterpolationMode
Mathematical interpolation methods.
void central_difference_tangents(std::span< const double > points, size_t dim, size_t count, std::vector< double > &tangents)
Tangents of a sampled curve by finite difference, coordinate-major.
EdgeList generate_proximity_graph(const Eigen::MatrixXd &points, const ProximityConfig &config)
Generate proximity graph using specified mode.
Kakshya::LineVertex LineVertex
Vertex type for line primitives (LINE_LIST / LINE_STRIP topology)
static VertexLayout for_lines(uint32_t stride=60)
Factory: layout for LineVertex (position, color, thickness, uv, normal, tangent)
std::function< EdgeList(const Eigen::MatrixXd &)> custom_function