1use super::{Plot3D, Plot3DError, validate_lengths, validate_multiple, validate_nonempty};
2use crate::{Plot3DDataLayout, Plot3DDataOffset, Plot3DDataStride, Plot3DUi, Triangle3DFlags};
3
4pub struct Triangles3D<'a> {
5 pub label: &'a str,
6 pub xs_f32: Option<&'a [f32]>,
7 pub ys_f32: Option<&'a [f32]>,
8 pub zs_f32: Option<&'a [f32]>,
9 pub xs_f64: Option<&'a [f64]>,
10 pub ys_f64: Option<&'a [f64]>,
11 pub zs_f64: Option<&'a [f64]>,
12 pub flags: Triangle3DFlags,
13 pub layout: Plot3DDataLayout,
14 pub points_f32: Option<&'a [[f32; 3]]>,
15 pub points_f64: Option<&'a [[f64; 3]]>,
16}
17
18impl<'a> Triangles3D<'a> {
19 pub fn f32(label: &'a str, xs: &'a [f32], ys: &'a [f32], zs: &'a [f32]) -> Self {
20 Self {
21 label,
22 xs_f32: Some(xs),
23 ys_f32: Some(ys),
24 zs_f32: Some(zs),
25 xs_f64: None,
26 ys_f64: None,
27 zs_f64: None,
28 flags: Triangle3DFlags::NONE,
29 layout: Plot3DDataLayout::DEFAULT,
30 points_f32: None,
31 points_f64: None,
32 }
33 }
34 pub fn f64(label: &'a str, xs: &'a [f64], ys: &'a [f64], zs: &'a [f64]) -> Self {
35 Self {
36 label,
37 xs_f32: None,
38 ys_f32: None,
39 zs_f32: None,
40 xs_f64: Some(xs),
41 ys_f64: Some(ys),
42 zs_f64: Some(zs),
43 flags: Triangle3DFlags::NONE,
44 layout: Plot3DDataLayout::DEFAULT,
45 points_f32: None,
46 points_f64: None,
47 }
48 }
49 pub fn points_f32(label: &'a str, pts: &'a [[f32; 3]]) -> Self {
50 Self {
51 label,
52 xs_f32: None,
53 ys_f32: None,
54 zs_f32: None,
55 xs_f64: None,
56 ys_f64: None,
57 zs_f64: None,
58 flags: Triangle3DFlags::NONE,
59 layout: Plot3DDataLayout::DEFAULT,
60 points_f32: Some(pts),
61 points_f64: None,
62 }
63 }
64 pub fn points_f64(label: &'a str, pts: &'a [[f64; 3]]) -> Self {
65 Self {
66 label,
67 xs_f32: None,
68 ys_f32: None,
69 zs_f32: None,
70 xs_f64: None,
71 ys_f64: None,
72 zs_f64: None,
73 flags: Triangle3DFlags::NONE,
74 layout: Plot3DDataLayout::DEFAULT,
75 points_f32: None,
76 points_f64: Some(pts),
77 }
78 }
79 pub fn flags(mut self, flags: Triangle3DFlags) -> Self {
80 self.flags = flags;
81 self
82 }
83 pub fn data_layout(mut self, layout: Plot3DDataLayout) -> Self {
84 self.layout = layout;
85 self
86 }
87 pub fn offset(mut self, offset: Plot3DDataOffset) -> Self {
88 self.layout = self.layout.with_offset(offset);
89 self
90 }
91 pub fn stride(mut self, stride: Plot3DDataStride) -> Self {
92 self.layout = self.layout.with_stride(stride);
93 self
94 }
95}
96
97impl<'a> Plot3D for Triangles3D<'a> {
98 fn label(&self) -> &str {
99 self.label
100 }
101 fn try_plot(&self, ui: &Plot3DUi<'_>) -> Result<(), Plot3DError> {
102 if let Some(pts) = self.points_f32 {
103 validate_nonempty(pts)?;
104 validate_multiple(pts.len(), 3, "triangles(points)")?;
105 let mut xs = Vec::with_capacity(pts.len());
106 let mut ys = Vec::with_capacity(pts.len());
107 let mut zs = Vec::with_capacity(pts.len());
108 for p in pts {
109 xs.push(p[0]);
110 ys.push(p[1]);
111 zs.push(p[2]);
112 }
113 ui.plot_triangles_f32(self.label, &xs, &ys, &zs, self.flags);
114 return Ok(());
115 }
116 if let Some(pts) = self.points_f64 {
117 validate_nonempty(pts)?;
118 validate_multiple(pts.len(), 3, "triangles(points)")?;
119 let mut xs = Vec::with_capacity(pts.len());
120 let mut ys = Vec::with_capacity(pts.len());
121 let mut zs = Vec::with_capacity(pts.len());
122 for p in pts {
123 xs.push(p[0]);
124 ys.push(p[1]);
125 zs.push(p[2]);
126 }
127 ui.plot_triangles_f64(self.label, &xs, &ys, &zs, self.flags);
128 return Ok(());
129 }
130 if let (Some(x), Some(y), Some(z)) = (self.xs_f32, self.ys_f32, self.zs_f32) {
131 validate_nonempty(x)?;
132 validate_lengths(x, y, "x/y")?;
133 validate_lengths(y, z, "y/z")?;
134 validate_multiple(x.len(), 3, "triangles")?;
135 ui.plot_triangles_f32_raw(self.label, x, y, z, self.flags, self.layout);
136 return Ok(());
137 }
138 if let (Some(x), Some(y), Some(z)) = (self.xs_f64, self.ys_f64, self.zs_f64) {
139 validate_nonempty(x)?;
140 validate_lengths(x, y, "x/y")?;
141 validate_lengths(y, z, "y/z")?;
142 validate_multiple(x.len(), 3, "triangles")?;
143 ui.plot_triangles_f64_raw(self.label, x, y, z, self.flags, self.layout);
144 return Ok(());
145 }
146 Err(Plot3DError::EmptyData)
147 }
148}