1use crate::{
2 Axis3D, Axis3DFlags, Plot3DCond, Plot3DUi, axis_tick_count_to_i32, compat_ffi,
3 debug_before_plot, debug_before_setup, imvec2, len_i32, sys,
4};
5
6impl<'ui> Plot3DUi<'ui> {
8 pub fn setup_axes(
9 &self,
10 x_label: &str,
11 y_label: &str,
12 z_label: &str,
13 x_flags: Axis3DFlags,
14 y_flags: Axis3DFlags,
15 z_flags: Axis3DFlags,
16 ) {
17 self.bind();
18 debug_before_setup();
19 if x_label.contains('\0') || y_label.contains('\0') || z_label.contains('\0') {
20 return;
21 }
22 dear_imgui_rs::with_scratch_txt_three(
23 x_label,
24 y_label,
25 z_label,
26 |x_ptr, y_ptr, z_ptr| unsafe {
27 sys::ImPlot3D_SetupAxes(
28 x_ptr,
29 y_ptr,
30 z_ptr,
31 x_flags.bits() as i32,
32 y_flags.bits() as i32,
33 z_flags.bits() as i32,
34 )
35 },
36 )
37 }
38
39 pub fn setup_axis(&self, axis: Axis3D, label: &str, flags: Axis3DFlags) {
40 self.bind();
41 debug_before_setup();
42 if label.contains('\0') {
43 return;
44 }
45 dear_imgui_rs::with_scratch_txt(label, |ptr| unsafe {
46 sys::ImPlot3D_SetupAxis(axis as i32, ptr, flags.bits() as i32)
47 })
48 }
49
50 pub fn setup_axis_limits(&self, axis: Axis3D, min: f64, max: f64, cond: Plot3DCond) {
51 self.bind();
52 debug_before_setup();
53 unsafe { sys::ImPlot3D_SetupAxisLimits(axis as i32, min, max, cond as i32) }
54 }
55
56 pub fn setup_axes_limits(
57 &self,
58 x_min: f64,
59 x_max: f64,
60 y_min: f64,
61 y_max: f64,
62 z_min: f64,
63 z_max: f64,
64 cond: Plot3DCond,
65 ) {
66 self.bind();
67 debug_before_setup();
68 unsafe {
69 sys::ImPlot3D_SetupAxesLimits(x_min, x_max, y_min, y_max, z_min, z_max, cond as i32)
70 }
71 }
72
73 pub fn setup_axis_limits_constraints(&self, axis: Axis3D, v_min: f64, v_max: f64) {
74 self.bind();
75 debug_before_setup();
76 unsafe { sys::ImPlot3D_SetupAxisLimitsConstraints(axis as i32, v_min, v_max) }
77 }
78
79 pub fn setup_axis_zoom_constraints(&self, axis: Axis3D, z_min: f64, z_max: f64) {
80 self.bind();
81 debug_before_setup();
82 unsafe { sys::ImPlot3D_SetupAxisZoomConstraints(axis as i32, z_min, z_max) }
83 }
84
85 pub fn setup_axis_ticks_values(
89 &self,
90 axis: Axis3D,
91 values: &[f64],
92 labels: Option<&[&str]>,
93 keep_default: bool,
94 ) {
95 self.bind();
96 debug_before_setup();
97 let Some(n_ticks) = len_i32(values.len()) else {
98 return;
99 };
100 if let Some(lbls) = labels {
101 if lbls.len() != values.len() {
102 return;
103 }
104 let cleaned: Vec<&str> = lbls
105 .iter()
106 .map(|&s| if s.contains('\0') { "" } else { s })
107 .collect();
108 dear_imgui_rs::with_scratch_txt_slice(&cleaned, |ptrs| unsafe {
109 sys::ImPlot3D_SetupAxisTicks_doublePtr(
110 axis as i32,
111 values.as_ptr(),
112 n_ticks,
113 ptrs.as_ptr(),
114 keep_default,
115 )
116 });
117 } else {
118 unsafe {
119 sys::ImPlot3D_SetupAxisTicks_doublePtr(
120 axis as i32,
121 values.as_ptr(),
122 n_ticks,
123 std::ptr::null(),
124 keep_default,
125 )
126 };
127 }
128 }
129
130 pub fn setup_axis_ticks_range(
131 &self,
132 axis: Axis3D,
133 v_min: f64,
134 v_max: f64,
135 n_ticks: usize,
136 labels: Option<&[&str]>,
137 keep_default: bool,
138 ) {
139 let n_ticks_i32 = axis_tick_count_to_i32("Plot3DUi::setup_axis_ticks_range()", n_ticks);
140 self.bind();
141 debug_before_setup();
142 if let Some(lbls) = labels {
143 if lbls.len() != n_ticks {
144 return;
145 }
146 let cleaned: Vec<&str> = lbls
147 .iter()
148 .map(|&s| if s.contains('\0') { "" } else { s })
149 .collect();
150 dear_imgui_rs::with_scratch_txt_slice(&cleaned, |ptrs| unsafe {
151 sys::ImPlot3D_SetupAxisTicks_double(
152 axis as i32,
153 v_min,
154 v_max,
155 n_ticks_i32,
156 ptrs.as_ptr(),
157 keep_default,
158 )
159 });
160 } else {
161 unsafe {
162 sys::ImPlot3D_SetupAxisTicks_double(
163 axis as i32,
164 v_min,
165 v_max,
166 n_ticks_i32,
167 std::ptr::null(),
168 keep_default,
169 )
170 };
171 }
172 }
173
174 pub fn setup_box_scale(&self, x: f32, y: f32, z: f32) {
175 self.bind();
176 debug_before_setup();
177 unsafe { sys::ImPlot3D_SetupBoxScale(x as f64, y as f64, z as f64) }
178 }
179
180 pub fn setup_box_rotation(
181 &self,
182 elevation: f32,
183 azimuth: f32,
184 animate: bool,
185 cond: Plot3DCond,
186 ) {
187 self.bind();
188 debug_before_setup();
189 unsafe {
190 sys::ImPlot3D_SetupBoxRotation_double(
191 elevation as f64,
192 azimuth as f64,
193 animate,
194 cond as i32,
195 )
196 }
197 }
198
199 pub fn setup_box_initial_rotation(&self, elevation: f32, azimuth: f32) {
200 self.bind();
201 debug_before_setup();
202 unsafe { sys::ImPlot3D_SetupBoxInitialRotation_double(elevation as f64, azimuth as f64) }
203 }
204
205 pub fn plot_text(&self, text: &str, x: f32, y: f32, z: f32, angle: f32, pix_offset: [f32; 2]) {
206 self.bind();
207 if text.contains('\0') {
208 return;
209 }
210 dear_imgui_rs::with_scratch_txt(text, |text_ptr| unsafe {
211 debug_before_plot();
212 sys::ImPlot3D_PlotText(
213 text_ptr,
214 x as f64,
215 y as f64,
216 z as f64,
217 angle as f64,
218 imvec2(pix_offset[0], pix_offset[1]),
219 )
220 })
221 }
222
223 pub fn plot_to_pixels(&self, point: [f32; 3]) -> [f32; 2] {
224 self.bind();
225 unsafe {
226 let out = compat_ffi::ImPlot3D_PlotToPixels_double(
227 point[0] as f64,
228 point[1] as f64,
229 point[2] as f64,
230 );
231 [out.x, out.y]
232 }
233 }
234
235 pub fn get_plot_draw_list(&self) -> *mut sys::ImDrawList {
236 self.bind();
237 unsafe { sys::ImPlot3D_GetPlotDrawList() }
238 }
239
240 pub fn get_frame_pos(&self) -> [f32; 2] {
241 self.bind();
242 unsafe {
243 let out = compat_ffi::ImPlot3D_GetPlotRectPos();
244 [out.x, out.y]
245 }
246 }
247
248 pub fn get_frame_size(&self) -> [f32; 2] {
249 self.bind();
250 unsafe {
251 let out = compat_ffi::ImPlot3D_GetPlotRectSize();
252 [out.x, out.y]
253 }
254 }
255}