1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::errors::Error;
use crate::*;

impl StructuredMesh {
    /// Creates new structured mesh.
    /// Checks whether the size of vectors are compatible before creation.
    #[inline(always)]
    pub fn new(
        positions: Vec<Vec<Point3>>,
        (u_div, v_div): (Vec<f64>, Vec<f64>),
        normals: Vec<Vec<Vector3>>,
    ) -> StructuredMesh
    {
        if positions.len() != u_div.len() || normals.len() != u_div.len() {
            panic!("{}", Error::DifferentLengthArrays);
        }
        for arr in &positions {
            if arr.len() != v_div.len() {
                panic!("{}", Error::IrregularArray);
            }
        }
        for arr in &normals {
            if arr.len() != v_div.len() {
                panic!("{}", Error::IrregularArray);
            }
        }
        for i in 1..u_div.len() {
            if u_div[i - 1] > u_div[i] {
                panic!("{}", Error::UnsortedDivision);
            }
        }
        for i in 1..v_div.len() {
            if v_div[i - 1] > v_div[i] {
                panic!("{}", Error::UnsortedDivision);
            }
        }
        StructuredMesh {
            positions,
            uv_division: (u_div, v_div),
            normals,
        }
    }

    /// Creates new structured mesh.
    /// Does not check whether the size of vectors are compatible before creation.
    #[inline(always)]
    pub fn new_unchecked(
        positions: Vec<Vec<Point3>>,
        (u_div, v_div): (Vec<f64>, Vec<f64>),
        normals: Vec<Vec<Vector3>>,
    ) -> StructuredMesh
    {
        StructuredMesh {
            positions,
            uv_division: (u_div, v_div),
            normals,
        }
    }
    
    /// Creates structured polygon without `uv_division` and `normal`.
    #[inline(always)]
    pub fn by_positions(positions: Vec<Vec<Point3>>) -> StructuredMesh {
        for arr in &positions {
            if arr.len() != positions[0].len() {
                panic!("{}", Error::IrregularArray);
            }
        }

        StructuredMesh {
            positions,
            uv_division: (Vec::new(), Vec::new()),
            normals: Vec::new(),
        }
    }

    /// Creates new polygon by destructing `self`.
    #[inline(always)]
    pub fn destruct(self) -> PolygonMesh {
        let StructuredMesh {
            positions,
            uv_division: (udiv, vdiv),
            normals,
        } = self;
        let m = positions.len();
        let n = positions[0].len();
        let positions = positions
            .into_iter()
            .flat_map(move |vec| vec.into_iter())
            .collect();
        let uv_coords = udiv
            .iter()
            .flat_map(|u| vdiv.iter().map(move |v| Vector2::new(*u, *v)))
            .collect();
        let normals = normals
            .into_iter()
            .flat_map(move |vec| vec.into_iter())
            .collect();
        let quad_faces = (1..m)
            .flat_map(|i| (1..n).map(move |j| (i, j)))
            .map(move |(i, j)| {
                [
                    [(i - 1) * n + j - 1; 3],
                    [i * n + j - 1; 3],
                    [i * n + j; 3],
                    [(i - 1) * n + j; 3],
                ]
            })
            .collect();
        PolygonMesh {
            positions,
            uv_coords,
            normals,
            tri_faces: Vec::new(),
            quad_faces,
            other_faces: Vec::new(),
        }
    }
}