1use std::borrow::Cow;
2
3use crate::item_style::{Plot3DItemStyle, plot3d_spec_with_style};
4use crate::plots::{
5 Plot3DError, SurfaceGrid, SurfaceGridShape, SurfaceLabel, submit_surface_grid,
6 submit_surface_raw,
7};
8use crate::{Item3DFlags, Plot3DDataLayout, Plot3DUi, Surface3DFlags, plot3d_spec_from};
9
10pub struct Surface3DBuilder<'ui> {
12 pub(crate) _ui: &'ui Plot3DUi<'ui>,
13 pub(crate) label: Cow<'ui, str>,
14 pub(crate) xs: &'ui [f32],
15 pub(crate) ys: &'ui [f32],
16 pub(crate) zs: &'ui [f32],
17 pub(crate) scale_min: f64,
18 pub(crate) scale_max: f64,
19 pub(crate) flags: Surface3DFlags,
20 pub(crate) item_flags: Item3DFlags,
21 pub(crate) style: Plot3DItemStyle,
22}
23
24impl<'ui> Surface3DBuilder<'ui> {
25 pub fn scale(mut self, min: f64, max: f64) -> Self {
26 self.scale_min = min;
27 self.scale_max = max;
28 self
29 }
30
31 pub fn flags(mut self, flags: Surface3DFlags) -> Self {
32 self.flags = flags;
33 self
34 }
35
36 #[must_use = "surface plot errors must be handled"]
38 pub fn plot(self) -> Result<(), Plot3DError> {
39 let Surface3DBuilder {
40 _ui,
41 label,
42 xs,
43 ys,
44 zs,
45 scale_min,
46 scale_max,
47 flags,
48 item_flags,
49 style,
50 } = self;
51
52 let label = SurfaceLabel::checked(label.as_ref())?;
53 let grid = SurfaceGrid::from_axes(xs, ys, zs)?;
54 submit_surface_grid(_ui, label, &grid, scale_min, scale_max, || {
55 plot3d_spec_with_style(
56 style,
57 flags.bits() | item_flags.bits(),
58 Plot3DDataLayout::DEFAULT,
59 )
60 });
61 Ok(())
62 }
63}
64
65impl<'ui> Plot3DUi<'ui> {
66 pub fn surface_f32(
68 &'ui self,
69 label: impl Into<Cow<'ui, str>>,
70 xs: &'ui [f32],
71 ys: &'ui [f32],
72 zs: &'ui [f32],
73 ) -> Surface3DBuilder<'ui> {
74 self.with_bound_context(|| Surface3DBuilder {
75 _ui: self,
76 label: label.into(),
77 xs,
78 ys,
79 zs,
80 scale_min: f64::NAN,
81 scale_max: f64::NAN,
82 flags: Surface3DFlags::NONE,
83 item_flags: Item3DFlags::NONE,
84 style: Plot3DItemStyle::default(),
85 })
86 }
87
88 #[must_use = "surface plot errors must be handled"]
115 pub fn surface_f32_flat<S: AsRef<str>>(
116 &self,
117 label: S,
118 xs_flat: &[f32],
119 ys_flat: &[f32],
120 zs: &[f32],
121 x_count: usize,
122 y_count: usize,
123 scale_min: f64,
124 scale_max: f64,
125 flags: Surface3DFlags,
126 ) -> Result<(), Plot3DError> {
127 let label = SurfaceLabel::checked(label.as_ref())?;
128 let grid = SurfaceGrid::from_flattened(xs_flat, ys_flat, zs, x_count, y_count)?;
129 submit_surface_grid(self, label, &grid, scale_min, scale_max, || {
130 plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT)
131 });
132 Ok(())
133 }
134
135 #[must_use = "surface plot errors must be handled"]
166 pub unsafe fn surface_f32_raw<S: AsRef<str>>(
167 &self,
168 label: S,
169 xs: &[f32],
170 ys: &[f32],
171 zs: &[f32],
172 x_count: usize,
173 y_count: usize,
174 scale_min: f64,
175 scale_max: f64,
176 flags: Surface3DFlags,
177 layout: Plot3DDataLayout,
178 ) -> Result<(), Plot3DError> {
179 let label = SurfaceLabel::checked(label.as_ref())?;
180 let shape = SurfaceGridShape::checked(x_count, y_count)?;
181 unsafe {
182 submit_surface_raw(
183 self, label, xs, ys, zs, shape, scale_min, scale_max, flags, layout,
184 );
185 }
186 Ok(())
187 }
188}