use poincare_lib::PlotStyle;
pub(crate) const DEFAULT_ISO_PALETTE: [[f32; 4]; 6] = [
[0.2, 0.6, 1.0, 0.7],
[1.0, 0.4, 0.2, 0.7],
[0.2, 0.9, 0.4, 0.7],
[0.9, 0.8, 0.1, 0.7],
[0.7, 0.2, 0.9, 0.7],
[0.1, 0.9, 0.9, 0.7],
];
#[derive(Clone)]
pub(crate) enum SeedMode {
Grid {
nx: u32,
ny: u32,
nz: u32,
},
Plane {
axis: usize,
offset: f32,
},
ManualCsv {
csv_text: String,
},
}
impl Default for SeedMode {
fn default() -> Self {
Self::Grid {
nx: 3,
ny: 3,
nz: 3,
}
}
}
#[derive(Clone, Copy)]
pub(crate) struct StyleCaps {
pub(crate) mesh: bool,
pub(crate) line: bool,
pub(crate) point: bool,
pub(crate) glyph: bool,
}
#[derive(Clone, PartialEq, Eq)]
pub(crate) enum DomainLabels {
None,
Xy,
Xyz,
Uv,
ThetaPhi,
ThetaZ,
Theta,
T,
SingleVar(String),
}
#[derive(Clone)]
pub(crate) enum PlotKind {
ContouredSurface {
contour_values: Vec<f32>,
contour_style: PlotStyle,
},
SphericalHarmonic,
HelixCurve,
ScatterCloud,
VectorField,
GridSurface,
Streamlines {
seeds: Vec<glam::Vec3>,
},
VolumeRender {
resolution: [u32; 3],
},
Isosurface {
isovalues: Vec<f64>,
resolution: [u32; 3],
},
ExprCartesian {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprCurve {
expression: String,
parameters: Vec<(String, f64)>,
t_range: (f64, f64),
},
ExprCartesianLine {
dep_var: String,
ind_var: String,
expression: String,
parameters: Vec<(String, f64)>,
},
ExprSpherical {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprCylindrical {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprPolar {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprParametricSurface {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprDataGrid {
csv_text: String,
parse_error: String,
},
ExprCurvePoints {
csv_text: String,
parse_error: String,
},
ExprScatter {
csv_text: String,
parse_error: String,
},
ExprVectorField {
expression: String,
parameters: Vec<(String, f64)>,
},
ExprVolume {
expression: String,
parameters: Vec<(String, f64)>,
vol_resolution: [u32; 3],
},
ExprIsosurface {
expression: String,
parameters: Vec<(String, f64)>,
isovalues: Vec<f64>,
iso_colours: Vec<[f32; 4]>,
vol_resolution: [u32; 3],
},
ExprStreamlines {
expression: String,
parameters: Vec<(String, f64)>,
seed_mode: SeedMode,
step_size: f32,
max_steps: u32,
},
}
impl PlotKind {
pub(crate) fn style_caps(&self) -> StyleCaps {
match self {
Self::ContouredSurface { .. }
| Self::SphericalHarmonic
| Self::GridSurface
| Self::Isosurface { .. }
| Self::ExprCartesian { .. }
| Self::ExprSpherical { .. }
| Self::ExprCylindrical { .. }
| Self::ExprPolar { .. }
| Self::ExprParametricSurface { .. }
| Self::ExprDataGrid { .. } => StyleCaps {
mesh: true,
line: false,
point: false,
glyph: false,
},
Self::HelixCurve
| Self::Streamlines { .. }
| Self::ExprCurve { .. }
| Self::ExprCartesianLine { .. }
| Self::ExprCurvePoints { .. }
| Self::ExprStreamlines { .. } => StyleCaps {
mesh: false,
line: true,
point: false,
glyph: false,
},
Self::ScatterCloud | Self::ExprScatter { .. } => StyleCaps {
mesh: false,
line: false,
point: true,
glyph: false,
},
Self::VectorField | Self::ExprVectorField { .. } => StyleCaps {
mesh: false,
line: false,
point: false,
glyph: true,
},
Self::VolumeRender { .. } | Self::ExprVolume { .. } => StyleCaps {
mesh: false,
line: false,
point: false,
glyph: false,
},
Self::ExprIsosurface { .. } => StyleCaps {
mesh: true,
line: false,
point: false,
glyph: false,
},
}
}
pub(crate) fn domain_labels(&self) -> DomainLabels {
match self {
Self::ExprCartesian { .. } | Self::ContouredSurface { .. } | Self::GridSurface => {
DomainLabels::Xy
}
Self::ExprSpherical { .. } => DomainLabels::ThetaPhi,
Self::ExprCylindrical { .. } => DomainLabels::ThetaZ,
Self::ExprPolar { .. } => DomainLabels::Theta,
Self::ExprParametricSurface { .. } => DomainLabels::Uv,
Self::ExprCurve { .. } => DomainLabels::T,
Self::ExprCartesianLine { ind_var, .. } => DomainLabels::SingleVar(ind_var.clone()),
Self::VectorField
| Self::Streamlines { .. }
| Self::VolumeRender { .. }
| Self::Isosurface { .. }
| Self::ExprVectorField { .. }
| Self::ExprVolume { .. }
| Self::ExprIsosurface { .. }
| Self::ExprStreamlines { .. } => DomainLabels::Xyz,
_ => DomainLabels::None,
}
}
pub(crate) fn uses_resolution(&self) -> bool {
!matches!(
self,
Self::ScatterCloud
| Self::Streamlines { .. }
| Self::ExprScatter { .. }
| Self::ExprCurvePoints { .. }
| Self::ExprDataGrid { .. }
)
}
pub(crate) fn uses_seed_resolution(&self) -> bool {
matches!(self, Self::VectorField | Self::ExprVectorField { .. })
}
pub(crate) fn parameters_mut(&mut self) -> Option<&mut Vec<(String, f64)>> {
match self {
Self::ExprCartesian { parameters, .. }
| Self::ExprCurve { parameters, .. }
| Self::ExprCartesianLine { parameters, .. }
| Self::ExprSpherical { parameters, .. }
| Self::ExprCylindrical { parameters, .. }
| Self::ExprPolar { parameters, .. }
| Self::ExprParametricSurface { parameters, .. }
| Self::ExprVectorField { parameters, .. }
| Self::ExprVolume { parameters, .. }
| Self::ExprIsosurface { parameters, .. }
| Self::ExprStreamlines { parameters, .. } => Some(parameters),
_ => None,
}
}
}
pub(crate) fn evenly_spaced_isovalues(count: usize) -> Vec<f32> {
let count = count.max(1);
if count == 1 {
return vec![0.0];
}
(0..count)
.map(|i| -0.9 + 1.8 * i as f32 / (count - 1) as f32)
.collect()
}