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