use std::marker::PhantomData;
use crate::builder::Plot3DBuilder;
use crate::{
Line3DFlags, Plot3DDataLayout, Plot3DFlags, Quad3DFlags, Scatter3DFlags, Triangle3DFlags,
len_i32, plot3d_spec_from, sys,
};
use dear_imgui_rs::Ui;
use super::binding::Plot3DContextBinding;
pub struct Plot3DUi<'ui> {
pub(crate) _ui: &'ui Ui,
pub(crate) binding: Plot3DContextBinding,
pub(crate) imgui_alive: Option<dear_imgui_rs::ContextAliveToken>,
}
impl<'ui> Plot3DUi<'ui> {
pub(crate) fn bind(&self) -> super::binding::Plot3DContextBindingGuard {
if let Some(alive) = &self.imgui_alive {
assert!(
alive.is_alive(),
"dear-implot3d: ImGui context has been dropped"
);
}
self.binding.bind()
}
pub fn begin_plot<S: AsRef<str>>(&self, title: S) -> Plot3DBuilder<'ui> {
let _guard = self.bind();
Plot3DBuilder {
binding: self.binding,
imgui_alive: self.imgui_alive.clone(),
ui: self._ui,
title: title.as_ref().into(),
size: None,
flags: Plot3DFlags::empty(),
_lifetime: PhantomData,
}
}
pub fn plot_line_f32<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Line3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotLine_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_line_f32_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Line3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotLine_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_line_f64<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Line3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotLine_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_line_f64_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Line3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotLine_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_scatter_f32<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Scatter3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotScatter_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_scatter_f32_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Scatter3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotScatter_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_scatter_f64<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Scatter3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotScatter_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_scatter_f64_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Scatter3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotScatter_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_triangles_f32<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Triangle3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotTriangle_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_triangles_f32_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Triangle3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotTriangle_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_quads_f32<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Quad3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotQuad_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_quads_f32_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f32],
ys: &[f32],
zs: &[f32],
flags: Quad3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotQuad_FloatPtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_triangles_f64<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Triangle3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotTriangle_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_triangles_f64_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Triangle3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotTriangle_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_quads_f64<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Quad3DFlags,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), Plot3DDataLayout::DEFAULT);
sys::ImPlot3D_PlotQuad_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
pub fn plot_quads_f64_raw<S: AsRef<str>>(
&self,
label: S,
xs: &[f64],
ys: &[f64],
zs: &[f64],
flags: Quad3DFlags,
layout: Plot3DDataLayout,
) {
let _guard = self.bind();
if xs.len() != ys.len() || ys.len() != zs.len() {
return;
}
let Some(count) = len_i32(xs.len()) else {
return;
};
let label = label.as_ref();
if label.contains('\0') {
return;
}
dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
let spec = plot3d_spec_from(flags.bits(), layout);
sys::ImPlot3D_PlotQuad_doublePtr(
label_ptr,
xs.as_ptr(),
ys.as_ptr(),
zs.as_ptr(),
count,
spec,
);
})
}
}