MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ done()

SeriesSpec MayaFlux::Portal::Forma::Plot::WaveformBuilder::done ( ) const

Definition at line 207 of file SeriesBuilder.cpp.

208{
209 auto x_mappings = m_state.x_mappings();
210 auto y_mappings = m_state.y_mappings();
211 auto z_mappings = m_state.z_mappings();
212 const auto global_palette = m_state.palette();
213 const float thickness = m_thickness;
214
215 return fitted(SeriesSpec {
216 .fn = [x_mappings, y_mappings, z_mappings, global_palette, thickness](
217 const std::shared_ptr<Kakshya::PlotContainer>& container,
218 std::vector<uint8_t>& out,
219 Element&) mutable {
220 if (!container)
221 return;
222
223 container->process_default();
224
225 struct SeriesEntry {
226 std::span<const double> data;
227 size_t mapping_index;
228 size_t index_within_mapping;
229 };
230
231 std::vector<SeriesEntry> y_entries;
232 for (size_t mi = 0; mi < y_mappings.size(); ++mi) {
233 auto series = series_for_mapping(*container, y_mappings[mi]);
234 for (size_t si = 0; si < series.size(); ++si)
235 y_entries.push_back({ .data = series[si], .mapping_index = mi, .index_within_mapping = si });
236 }
237 if (y_entries.empty())
238 return;
239
240 AxisRange x_range = merge_axis(x_mappings);
241 AxisRange z_range = z_mappings.empty() ? AxisRange {} : merge_axis(z_mappings);
242
243 std::vector<std::span<const double>> all_x, all_z;
244 for (auto& m : x_mappings) {
245 auto s = series_for_mapping(*container, m);
246 all_x.insert(all_x.end(), s.begin(), s.end());
247 }
248 for (auto& m : z_mappings) {
249 auto s = series_for_mapping(*container, m);
250 all_z.insert(all_z.end(), s.begin(), s.end());
251 }
252
253 apply_auto_scale(x_range, all_x.empty() ? std::vector<std::span<const double>> { y_entries[0].data } : all_x);
254 apply_auto_scale(z_range, all_z);
255
256 out.clear();
257
258 for (size_t ei = 0; ei < y_entries.size(); ++ei) {
259 const auto& entry = y_entries[ei];
260 const auto& ys = entry.data;
261 const size_t n = ys.size();
262 if (n == 0)
263 continue;
264
265 const glm::vec3 color = resolve_color(
266 y_mappings[entry.mapping_index], global_palette, entry.index_within_mapping);
267
268 auto y_range = y_mappings[entry.mapping_index].range;
269 apply_auto_scale(y_range, { ys });
270
271 const bool has_x = ei < all_x.size() && all_x[ei].size() == n;
272 const bool has_z = ei < all_z.size() && all_z[ei].size() == n;
273
274 const std::vector<float> xs = has_x
275 ? [&] {
276 std::vector<float> v;
277 v.reserve(n);
278 for (double val : all_x[ei])
279 v.push_back(x_range.to_ndc(static_cast<float>(val)));
280 return v;
281 }()
282 : uniform_x(n, x_range);
283
284 for (size_t i = 0; i < n; ++i) {
285 write_vertex(out,
286 { xs[i],
287 y_range.to_ndc(static_cast<float>(ys[i])),
288 has_z ? z_range.to_ndc(static_cast<float>(all_z[ei][i])) : 0.F },
289 color,
290 thickness);
291 }
292
293 if (ei + 1 < y_entries.size()) {
294 const glm::vec3 sep_pos {
295 xs[n - 1],
296 y_range.to_ndc(static_cast<float>(ys[n - 1])),
297 has_z ? z_range.to_ndc(static_cast<float>(all_z[ei][n - 1])) : 0.F,
298 };
299 write_vertex(out, sep_pos, color, 0.F);
300 write_vertex(out, sep_pos, color, 0.F);
301 }
302 } },
304 .capacity_for = [](uint64_t n) { return (n + 2) * k_stride; },
305 .background_fn = m_state.has_background()
306 ? std::optional<GeometryFn<float>> { background(m_state.background_bounds(), m_state.background_color()) }
307 : std::nullopt,
308 .plot_bounds = m_state.plot_bounds(),
309 .labels = m_state.labels(),
310 .tick_labels = m_state.resolved_tick_labels(),
311 .legend = m_state.legend_spec(),
312 });
313}
glm::vec3 color
Definition Decoder.cpp:97
std::vector< float > * out
const std::vector< LabelSpec > & labels() const
std::vector< TickLabelsSpec > resolved_tick_labels() const
Resolve pending fluent tick requests into concrete tick label specs.
Kinesis::AABB2D background_bounds() const
const std::vector< AxisMapping > & z_mappings() const
const std::vector< AxisMapping > & x_mappings() const
const std::optional< LegendSpec > & legend_spec() const
const std::optional< Kinesis::AABB2D > & plot_bounds() const
const std::vector< glm::vec3 > & palette() const
const std::vector< AxisMapping > & y_mappings() const
WaveformBuilder & thickness(float t)
Line thickness in pixels.
glm::vec3 to_ndc(double window_x, double window_y, uint32_t width, uint32_t height)
Convert window pixel coordinates to NDC.
Series series()
Begin a Series chain.
Definition Plot.hpp:108
void apply_auto_scale(AxisRange &range, const std::vector< std::span< const double > > &series)
Apply auto-scaling to an AxisRange from a set of series.
Definition PlotSpec.cpp:53
GeometryFn< float > background(Kinesis::AABB2D bounds, glm::vec3 color, const std::shared_ptr< Core::VKImage > &texture)
TRIANGLE_STRIP background quad for a plot area.
Definition PlotSpec.cpp:88

References MayaFlux::Portal::Forma::Plot::apply_auto_scale(), MayaFlux::Portal::Forma::Plot::background(), MayaFlux::Portal::Forma::Plot::Series::background_bounds(), MayaFlux::Portal::Forma::Plot::Series::background_color(), color, MayaFlux::Portal::Forma::Plot::SeriesSpec::fn, MayaFlux::Portal::Forma::Plot::Series::has_background(), MayaFlux::Portal::Forma::Plot::Series::labels(), MayaFlux::Portal::Forma::Plot::Series::legend_spec(), MayaFlux::Portal::Graphics::LINE_STRIP, m_state, m_thickness, out, MayaFlux::Portal::Forma::Plot::Series::palette(), MayaFlux::Portal::Forma::Plot::Series::plot_bounds(), MayaFlux::Portal::Forma::Plot::Series::resolved_tick_labels(), MayaFlux::Portal::Forma::Plot::series(), thickness(), MayaFlux::Portal::Forma::Plot::AxisRange::to_ndc(), MayaFlux::Portal::Forma::Plot::Series::x_mappings(), MayaFlux::Portal::Forma::Plot::Series::y_mappings(), and MayaFlux::Portal::Forma::Plot::Series::z_mappings().

+ Here is the call graph for this function: