density_mesh_core/mesh/
points_separation.rs

1use crate::Scalar;
2use serde::{Deserialize, Serialize};
3use std::{num::ParseFloatError, ops::Range, str::FromStr};
4
5/// Point separation source.
6#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
7pub enum PointsSeparation {
8    /// Each point has constant point separation.
9    Constant(Scalar),
10    /// Each point has local point separation that depends on the steepness value.
11    /// When steepness is in range from 0 to 1, then steepness 0 maps to max and 1 maps to min.
12    /// `(min, max)`
13    SteepnessMapping(Scalar, Scalar),
14}
15
16impl PointsSeparation {
17    /// Returns maximum of possible values.
18    pub fn maximum(&self) -> Scalar {
19        match self {
20            Self::Constant(v) => *v,
21            Self::SteepnessMapping(_, v) => *v,
22        }
23    }
24}
25
26impl From<Scalar> for PointsSeparation {
27    fn from(value: Scalar) -> Self {
28        Self::Constant(value)
29    }
30}
31
32impl From<(Scalar, Scalar)> for PointsSeparation {
33    fn from(value: (Scalar, Scalar)) -> Self {
34        Self::SteepnessMapping(value.0, value.1)
35    }
36}
37
38impl From<[Scalar; 2]> for PointsSeparation {
39    fn from(value: [Scalar; 2]) -> Self {
40        Self::SteepnessMapping(value[0], value[1])
41    }
42}
43
44impl From<Range<Scalar>> for PointsSeparation {
45    fn from(value: Range<Scalar>) -> Self {
46        Self::SteepnessMapping(value.start, value.end)
47    }
48}
49
50impl FromStr for PointsSeparation {
51    type Err = ParseFloatError;
52
53    fn from_str(s: &str) -> Result<Self, Self::Err> {
54        if let Some(found) = s.find("..") {
55            let f = &s[..found];
56            let t = &s[(found + 2)..];
57            Ok(Self::SteepnessMapping(
58                f.parse::<Scalar>()?,
59                t.parse::<Scalar>()?,
60            ))
61        } else {
62            Ok(Self::Constant(s.parse::<Scalar>()?))
63        }
64    }
65}
66
67impl ToString for PointsSeparation {
68    fn to_string(&self) -> String {
69        match self {
70            Self::Constant(v) => v.to_string(),
71            Self::SteepnessMapping(f, t) => format!("{}..{}", f, t),
72        }
73    }
74}