Skip to main content

mdbook_plotly/code_handler/plot_obj_parser/
mesh3d_parser.rs

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}