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
119
120
121
122
123
124
125
126
127
128
/*
 * File: mod.rs
 * Project: geometry
 * Created Date: 04/05/2022
 * Author: Shun Suzuki
 * -----
 * Last Modified: 06/12/2022
 * Modified By: Shun Suzuki (suzuki@hapis.k.u-tokyo.ac.jp)
 * -----
 * Copyright (c) 2022 Shun Suzuki. All rights reserved.
 *
 */

mod builder;
mod device;
mod legacy_transducer;
mod normal_phase_transducer;
mod normal_transducer;
mod transducer;

pub type Vector3 = nalgebra::Vector3<f64>;
pub type Vector4 = nalgebra::Vector4<f64>;
pub type Quaternion = nalgebra::Quaternion<f64>;
pub type UnitQuaternion = nalgebra::UnitQuaternion<f64>;
pub type Matrix3 = nalgebra::Matrix3<f64>;
pub type Matrix4 = nalgebra::Matrix4<f64>;

use std::ops::{Index, IndexMut};

pub use builder::*;
pub use device::*;
pub use legacy_transducer::*;
pub use normal_phase_transducer::*;
pub use normal_transducer::*;
pub use transducer::*;

use crate::error::AUTDInternalError;

#[derive(Default)]
pub struct Geometry<T: Transducer> {
    transducers: Vec<T>,
    device_map: Vec<usize>,
}

impl<T: Transducer> Geometry<T> {
    fn new() -> Geometry<T> {
        Geometry {
            transducers: vec![],
            device_map: vec![],
        }
    }

    pub fn add_device<D: Device<T>>(&mut self, dev: D) -> anyhow::Result<()> {
        let id = self.transducers.len();
        let mut transducers = dev.get_transducers(id);
        if transducers.len() > 256 {
            return Err(AUTDInternalError::TransducersNumInDeviceOutOfRange.into());
        }
        self.device_map.push(transducers.len());
        self.transducers.append(&mut transducers);
        Ok(())
    }

    pub fn num_devices(&self) -> usize {
        self.device_map.len()
    }

    pub fn num_transducers(&self) -> usize {
        self.transducers.len()
    }

    pub fn transducers(&self) -> std::slice::Iter<'_, T> {
        self.transducers.iter()
    }

    pub fn transducers_mut(&mut self) -> std::slice::IterMut<'_, T> {
        self.transducers.iter_mut()
    }

    pub fn center(&self) -> Vector3 {
        self.transducers
            .iter()
            .map(|d| d.position())
            .sum::<Vector3>()
            / self.transducers.len() as f64
    }

    pub fn device_map(&self) -> &[usize] {
        &self.device_map
    }
}

impl<T: Transducer> Index<usize> for Geometry<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {
        &self.transducers[idx]
    }
}

impl<T: Transducer> IndexMut<usize> for Geometry<T> {
    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
        &mut self.transducers[idx]
    }
}

impl<'a, T> IntoIterator for &'a Geometry<T>
where
    T: Transducer,
{
    type Item = &'a T;
    type IntoIter = std::slice::Iter<'a, T>;

    fn into_iter(self) -> std::slice::Iter<'a, T> {
        self.transducers()
    }
}

impl<'a, T> IntoIterator for &'a mut Geometry<T>
where
    T: Transducer,
{
    type Item = &'a mut T;
    type IntoIter = std::slice::IterMut<'a, T>;

    fn into_iter(self) -> std::slice::IterMut<'a, T> {
        self.transducers_mut()
    }
}