Skip to main content

dear_implot3d/
image_builder.rs

1use std::borrow::Cow;
2use std::marker::PhantomData;
3
4use dear_imgui_rs::texture::TextureRef;
5
6use crate::item_style::{Plot3DItemStyle, plot3d_spec_with_style};
7use crate::{
8    Image3DFlags, Item3DFlags, Plot3DDataLayout, Plot3DUi, debug_before_plot, imvec2, imvec4, sys,
9};
10
11/// Image by axes builder
12pub struct Image3DByAxesBuilder<'ui, 'tex> {
13    pub(crate) _ui: &'ui Plot3DUi<'ui>,
14    pub(crate) label: Cow<'ui, str>,
15    pub(crate) tex_ref: sys::ImTextureRef_c,
16    pub(crate) _texture: PhantomData<&'tex mut dear_imgui_rs::texture::TextureData>,
17    pub(crate) center: [f32; 3],
18    pub(crate) axis_u: [f32; 3],
19    pub(crate) axis_v: [f32; 3],
20    pub(crate) uv0: [f32; 2],
21    pub(crate) uv1: [f32; 2],
22    pub(crate) tint: [f32; 4],
23    pub(crate) flags: Image3DFlags,
24    pub(crate) item_flags: Item3DFlags,
25    pub(crate) style: Plot3DItemStyle,
26}
27
28impl<'ui, 'tex> Image3DByAxesBuilder<'ui, 'tex> {
29    pub fn uv(mut self, uv0: [f32; 2], uv1: [f32; 2]) -> Self {
30        self.uv0 = uv0;
31        self.uv1 = uv1;
32        self
33    }
34    pub fn tint(mut self, col: [f32; 4]) -> Self {
35        self.tint = col;
36        self
37    }
38    pub fn flags(mut self, flags: Image3DFlags) -> Self {
39        self.flags = flags;
40        self
41    }
42    pub fn plot(self) {
43        let _guard = self._ui.bind();
44        let label = self.label.as_ref();
45        let label = if label.contains('\0') { "image" } else { label };
46        dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
47            debug_before_plot();
48            let spec = plot3d_spec_with_style(
49                self.style,
50                self.flags.bits() | self.item_flags.bits(),
51                Plot3DDataLayout::DEFAULT,
52            );
53            sys::ImPlot3D_PlotImage_Vec2(
54                label_ptr,
55                self.tex_ref,
56                sys::ImPlot3DPoint_c {
57                    x: self.center[0] as f64,
58                    y: self.center[1] as f64,
59                    z: self.center[2] as f64,
60                },
61                sys::ImPlot3DPoint_c {
62                    x: self.axis_u[0] as f64,
63                    y: self.axis_u[1] as f64,
64                    z: self.axis_u[2] as f64,
65                },
66                sys::ImPlot3DPoint_c {
67                    x: self.axis_v[0] as f64,
68                    y: self.axis_v[1] as f64,
69                    z: self.axis_v[2] as f64,
70                },
71                imvec2(self.uv0[0], self.uv0[1]),
72                imvec2(self.uv1[0], self.uv1[1]),
73                imvec4(self.tint[0], self.tint[1], self.tint[2], self.tint[3]),
74                spec,
75            );
76        })
77    }
78}
79
80/// Image by corners builder
81pub struct Image3DByCornersBuilder<'ui, 'tex> {
82    pub(crate) _ui: &'ui Plot3DUi<'ui>,
83    pub(crate) label: Cow<'ui, str>,
84    pub(crate) tex_ref: sys::ImTextureRef_c,
85    pub(crate) _texture: PhantomData<&'tex mut dear_imgui_rs::texture::TextureData>,
86    pub(crate) p0: [f32; 3],
87    pub(crate) p1: [f32; 3],
88    pub(crate) p2: [f32; 3],
89    pub(crate) p3: [f32; 3],
90    pub(crate) uv0: [f32; 2],
91    pub(crate) uv1: [f32; 2],
92    pub(crate) uv2: [f32; 2],
93    pub(crate) uv3: [f32; 2],
94    pub(crate) tint: [f32; 4],
95    pub(crate) flags: Image3DFlags,
96    pub(crate) item_flags: Item3DFlags,
97    pub(crate) style: Plot3DItemStyle,
98}
99
100impl<'ui, 'tex> Image3DByCornersBuilder<'ui, 'tex> {
101    pub fn uvs(mut self, uv0: [f32; 2], uv1: [f32; 2], uv2: [f32; 2], uv3: [f32; 2]) -> Self {
102        self.uv0 = uv0;
103        self.uv1 = uv1;
104        self.uv2 = uv2;
105        self.uv3 = uv3;
106        self
107    }
108    pub fn tint(mut self, col: [f32; 4]) -> Self {
109        self.tint = col;
110        self
111    }
112    pub fn flags(mut self, flags: Image3DFlags) -> Self {
113        self.flags = flags;
114        self
115    }
116    pub fn plot(self) {
117        let _guard = self._ui.bind();
118        let label = self.label.as_ref();
119        let label = if label.contains('\0') { "image" } else { label };
120        dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
121            debug_before_plot();
122            let spec = plot3d_spec_with_style(
123                self.style,
124                self.flags.bits() | self.item_flags.bits(),
125                Plot3DDataLayout::DEFAULT,
126            );
127            sys::ImPlot3D_PlotImage_Plot3DPoint(
128                label_ptr,
129                self.tex_ref,
130                sys::ImPlot3DPoint_c {
131                    x: self.p0[0] as f64,
132                    y: self.p0[1] as f64,
133                    z: self.p0[2] as f64,
134                },
135                sys::ImPlot3DPoint_c {
136                    x: self.p1[0] as f64,
137                    y: self.p1[1] as f64,
138                    z: self.p1[2] as f64,
139                },
140                sys::ImPlot3DPoint_c {
141                    x: self.p2[0] as f64,
142                    y: self.p2[1] as f64,
143                    z: self.p2[2] as f64,
144                },
145                sys::ImPlot3DPoint_c {
146                    x: self.p3[0] as f64,
147                    y: self.p3[1] as f64,
148                    z: self.p3[2] as f64,
149                },
150                imvec2(self.uv0[0], self.uv0[1]),
151                imvec2(self.uv1[0], self.uv1[1]),
152                imvec2(self.uv2[0], self.uv2[1]),
153                imvec2(self.uv3[0], self.uv3[1]),
154                imvec4(self.tint[0], self.tint[1], self.tint[2], self.tint[3]),
155                spec,
156            );
157        })
158    }
159}
160
161impl<'ui> Plot3DUi<'ui> {
162    /// Image oriented by center and axes
163    pub fn image_by_axes<'tex, T: Into<TextureRef<'tex>>>(
164        &'ui self,
165        label: impl Into<Cow<'ui, str>>,
166        tex: T,
167        center: [f32; 3],
168        axis_u: [f32; 3],
169        axis_v: [f32; 3],
170    ) -> Image3DByAxesBuilder<'ui, 'tex> {
171        let _guard = self.bind();
172        let tr = tex.into().raw();
173        let tex_ref = sys::ImTextureRef_c {
174            _TexData: tr._TexData as *mut sys::ImTextureData,
175            _TexID: tr._TexID as sys::ImTextureID,
176        };
177        debug_before_plot();
178        Image3DByAxesBuilder {
179            _ui: self,
180            label: label.into(),
181            tex_ref,
182            _texture: PhantomData,
183            center,
184            axis_u,
185            axis_v,
186            uv0: [0.0, 0.0],
187            uv1: [1.0, 1.0],
188            tint: [1.0, 1.0, 1.0, 1.0],
189            flags: Image3DFlags::NONE,
190            item_flags: Item3DFlags::NONE,
191            style: Plot3DItemStyle::default(),
192        }
193    }
194
195    /// Image by 4 corner points (p0..p3)
196    pub fn image_by_corners<'tex, T: Into<TextureRef<'tex>>>(
197        &'ui self,
198        label: impl Into<Cow<'ui, str>>,
199        tex: T,
200        p0: [f32; 3],
201        p1: [f32; 3],
202        p2: [f32; 3],
203        p3: [f32; 3],
204    ) -> Image3DByCornersBuilder<'ui, 'tex> {
205        let _guard = self.bind();
206        let tr = tex.into().raw();
207        let tex_ref = sys::ImTextureRef_c {
208            _TexData: tr._TexData as *mut sys::ImTextureData,
209            _TexID: tr._TexID as sys::ImTextureID,
210        };
211        debug_before_plot();
212        Image3DByCornersBuilder {
213            _ui: self,
214            label: label.into(),
215            tex_ref,
216            _texture: PhantomData,
217            p0,
218            p1,
219            p2,
220            p3,
221            uv0: [0.0, 0.0],
222            uv1: [1.0, 0.0],
223            uv2: [1.0, 1.0],
224            uv3: [0.0, 1.0],
225            tint: [1.0, 1.0, 1.0, 1.0],
226            flags: Image3DFlags::NONE,
227            item_flags: Item3DFlags::NONE,
228            style: Plot3DItemStyle::default(),
229        }
230    }
231}