1use super::until::{Color, Map, must_translate};
2use crate::{translate, translate_enum};
3use anyhow::Result;
4use plotly::Mesh3D;
5
6pub fn parse_mesh3d_data(
7 mesh_obj: &mut serde_json::Value,
8 map: &Map,
9) -> Result<Box<Mesh3D<f64, f64, f64>>> {
10 let x: Vec<f64> = must_translate(mesh_obj, map, "x")?;
11 let y: Vec<f64> = must_translate(mesh_obj, map, "y")?;
12 let z: Vec<f64> = must_translate(mesh_obj, map, "z")?;
13 let i: Option<Vec<usize>> = if mesh_obj.get("i").is_some() {
14 Some(must_translate(mesh_obj, map, "i")?)
15 } else {
16 None
17 };
18 let j: Option<Vec<usize>> = if mesh_obj.get("j").is_some() {
19 Some(must_translate(mesh_obj, map, "j")?)
20 } else {
21 None
22 };
23 let k: Option<Vec<usize>> = if mesh_obj.get("k").is_some() {
24 Some(must_translate(mesh_obj, map, "k")?)
25 } else {
26 None
27 };
28 let mesh = Mesh3D::new(x, y, z, i, j, k);
29
30 let mesh = translate! {
31 mesh,
32 mesh_obj,
33 map,
34 (name, String),
35 (opacity, f64),
36 (ids, Vec<String>),
37 (text, String),
38 (text_array, Vec<String>),
39 (hover_text, String),
40 (hover_text_array, Vec<String>),
41 (hover_template, String),
42 (hover_template_array, Vec<String>),
43 (show_legend, bool),
44 (legend_group, String),
45 (legend_rank, usize),
46 (color, Color),
47 (face_color, Vec<Color>),
48 (vertex_color, Vec<Color>),
49 (intensity, Vec<f64>),
50 (scene, String),
51 (flat_shading, bool),
52 (alpha_hull, f64),
53 (meta, String),
54 (color_axis, String),
55 (auto_color_scale, bool),
56 (reverse_scale, bool),
57 (show_scale, bool),
58 (c_auto, bool),
59 (c_max, f64),
60 (c_min, f64),
61 (c_mid, f64),
62 }?;
63
64 use plotly::common::HoverInfo;
65 let mesh = translate_enum! {
66 mesh,
67 mesh_obj,
68 map,
69 (hover_info, {
70 "all" => HoverInfo::All,
71 "x" => HoverInfo::X,
72 "y" => HoverInfo::Y,
73 "z" => HoverInfo::Z,
74 "x+y" => HoverInfo::XAndY,
75 "x+z" => HoverInfo::XAndZ,
76 "y+z" => HoverInfo::YAndZ,
77 "x+y+z" => HoverInfo::XAndYAndZ,
78 "text" => HoverInfo::Text,
79 "name" => HoverInfo::Name,
80 "none" => HoverInfo::None,
81 "skip" => HoverInfo::Skip,
82 }),
83 }?;
84
85 use plotly::traces::mesh3d::{DelaunayAxis, IntensityMode};
86 let mesh = translate_enum! {
87 mesh,
88 mesh_obj,
89 map,
90 (intensity_mode, {
91 "vertex" => IntensityMode::Vertex,
92 "cell" => IntensityMode::Cell,
93 }),
94 (delaunay_axis, {
95 "x" => DelaunayAxis::X,
96 "y" => DelaunayAxis::Y,
97 "z" => DelaunayAxis::Z,
98 }),
99 }?;
100
101 let mesh = if let Some(color_bar_obj) = mesh_obj.get_mut("color_bar")
102 && color_bar_obj.is_object()
103 {
104 use plotly::common::ColorBar;
105 let color_bar = translate! {
106 ColorBar::new(),
107 color_bar_obj,
108 map,
109 (thickness, usize),
110 (len, usize),
111 (x, f64),
112 (y, f64),
113 (title, String),
114 }?;
115 mesh.color_bar(color_bar)
116 } else {
117 mesh
118 };
119
120 let mesh = if mesh_obj.get("color_scale").is_some() {
121 use plotly::common::{ColorScale, ColorScalePalette};
122 let color_scale_str: String = must_translate(mesh_obj, map, "color_scale")?;
123 let palette = match color_scale_str.to_lowercase().as_str() {
124 "greys" => ColorScalePalette::Greys,
125 "ylgnbu" => ColorScalePalette::YlGnBu,
126 "greens" => ColorScalePalette::Greens,
127 "ylorrd" => ColorScalePalette::YlOrRd,
128 "bluered" => ColorScalePalette::Bluered,
129 "rdbu" => ColorScalePalette::RdBu,
130 "reds" => ColorScalePalette::Reds,
131 "blues" => ColorScalePalette::Blues,
132 "picnic" => ColorScalePalette::Picnic,
133 "rainbow" => ColorScalePalette::Rainbow,
134 "portland" => ColorScalePalette::Portland,
135 "jet" => ColorScalePalette::Jet,
136 "hot" => ColorScalePalette::Hot,
137 "blackbody" => ColorScalePalette::Blackbody,
138 "earth" => ColorScalePalette::Earth,
139 "electric" => ColorScalePalette::Electric,
140 "viridis" => ColorScalePalette::Viridis,
141 "cividis" => ColorScalePalette::Cividis,
142 _ => return Err(anyhow::anyhow!("unknown color_scale: {}", color_scale_str)),
143 };
144 mesh.color_scale(ColorScale::Palette(palette))
145 } else {
146 mesh
147 };
148
149 let mesh = if let Some(lighting_obj) = mesh_obj.get_mut("lighting")
150 && lighting_obj.is_object()
151 {
152 use plotly::traces::mesh3d::Lighting;
153 let lighting = translate! {
154 Lighting::new(),
155 lighting_obj,
156 map,
157 (ambient, f64),
158 (diffuse, f64),
159 (specular, f64),
160 (roughness, f64),
161 (fresnel, f64),
162 }?;
163 mesh.lighting(lighting)
164 } else {
165 mesh
166 };
167
168 let mesh = if let Some(light_pos_obj) = mesh_obj.get_mut("light_position")
169 && light_pos_obj.is_object()
170 {
171 use plotly::traces::mesh3d::LightPosition;
172 let light_pos = translate! {
173 LightPosition::new(),
174 light_pos_obj,
175 map,
176 (x, Vec<f64>),
177 (y, Vec<f64>),
178 (z, Vec<f64>),
179 }?;
180 mesh.light_position(light_pos)
181 } else {
182 mesh
183 };
184
185 Ok(mesh)
186}