Skip to main content

dear_implot3d/
mesh_builder.rs

1use std::borrow::Cow;
2
3use crate::item_style::{Plot3DItemStyle, plot3d_spec_with_style};
4use crate::{
5    Item3DFlags, Mesh3DFlags, Plot3DDataLayout, Plot3DUi, debug_before_plot, len_i32, sys,
6};
7
8/// Mesh plot builder
9pub struct Mesh3DBuilder<'ui> {
10    pub(crate) _ui: &'ui Plot3DUi<'ui>,
11    pub(crate) label: Cow<'ui, str>,
12    pub(crate) vertices: &'ui [[f32; 3]],
13    pub(crate) indices: &'ui [u32],
14    pub(crate) flags: Mesh3DFlags,
15    pub(crate) item_flags: Item3DFlags,
16    pub(crate) style: Plot3DItemStyle,
17}
18
19impl<'ui> Mesh3DBuilder<'ui> {
20    pub fn flags(mut self, flags: Mesh3DFlags) -> Self {
21        self.flags = flags;
22        self
23    }
24    pub fn plot(self) {
25        self._ui.with_bound_context(|| {
26            let Some(vtx_count) = len_i32(self.vertices.len()) else {
27                return;
28            };
29            let Some(idx_count) = len_i32(self.indices.len()) else {
30                return;
31            };
32            let mut xs = Vec::with_capacity(self.vertices.len());
33            let mut ys = Vec::with_capacity(self.vertices.len());
34            let mut zs = Vec::with_capacity(self.vertices.len());
35            for [x, y, z] in self.vertices.iter().copied() {
36                xs.push(x);
37                ys.push(y);
38                zs.push(z);
39            }
40
41            let label = self.label.as_ref();
42            let label = if label.contains('\0') { "mesh" } else { label };
43            dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
44                debug_before_plot();
45                let spec = plot3d_spec_with_style(
46                    self.style,
47                    self.flags.bits() | self.item_flags.bits(),
48                    Plot3DDataLayout::DEFAULT,
49                );
50                sys::ImPlot3D_PlotMesh_FloatPtr(
51                    label_ptr,
52                    xs.as_ptr(),
53                    ys.as_ptr(),
54                    zs.as_ptr(),
55                    self.indices.as_ptr(),
56                    vtx_count,
57                    idx_count,
58                    spec,
59                );
60            })
61        })
62    }
63}
64
65impl<'ui> Plot3DUi<'ui> {
66    /// Start a mesh plot from vertices (x,y,z) and triangle indices
67    pub fn mesh(
68        &'ui self,
69        label: impl Into<Cow<'ui, str>>,
70        vertices: &'ui [[f32; 3]],
71        indices: &'ui [u32],
72    ) -> Mesh3DBuilder<'ui> {
73        self.with_bound_context(|| Mesh3DBuilder {
74            _ui: self,
75            label: label.into(),
76            vertices,
77            indices,
78            flags: Mesh3DFlags::NONE,
79            item_flags: Item3DFlags::NONE,
80            style: Plot3DItemStyle::default(),
81        })
82    }
83}