Skip to main content

ecitygml_core/model/construction/
wall_surface.rs

1use crate::model::construction::{
2    AbstractConstructionSurface, AsAbstractConstructionSurface, AsAbstractConstructionSurfaceMut,
3    DoorSurface, WindowSurface,
4};
5use crate::model::core::{
6    AsAbstractFeature, AsAbstractFeatureMut, AsAbstractThematicSurface,
7    AsAbstractThematicSurfaceMut, CityObjectKind, CityObjectRef,
8};
9use crate::operations::{Visitable, Visitor};
10use egml::model::geometry::Envelope;
11use nalgebra::Isometry3;
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct WallSurface {
15    pub abstract_construction_surface: AbstractConstructionSurface,
16    pub door_surface: Vec<DoorSurface>,
17    pub window_surface: Vec<WindowSurface>,
18}
19
20impl WallSurface {
21    pub fn new(abstract_construction_surface: AbstractConstructionSurface) -> Self {
22        Self {
23            abstract_construction_surface,
24            door_surface: Vec::new(),
25            window_surface: Vec::new(),
26        }
27    }
28
29    pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
30        std::iter::once(CityObjectRef::WallSurface(self))
31            .chain(self.door_surface.iter().flat_map(|x| x.iter_city_object()))
32            .chain(
33                self.window_surface
34                    .iter()
35                    .flat_map(|x| x.iter_city_object()),
36            )
37    }
38
39    pub fn refresh_bounded_by_recursive(&mut self) {
40        self.door_surface
41            .iter_mut()
42            .for_each(|x| x.refresh_bounded_by());
43        self.window_surface
44            .iter_mut()
45            .for_each(|x| x.refresh_bounded_by());
46
47        let own_envelope = self.compute_envelope();
48        let envelopes: Vec<Envelope> = own_envelope
49            .as_ref()
50            .into_iter()
51            .chain(self.door_surface.iter().filter_map(|x| x.bounded_by()))
52            .chain(self.window_surface.iter().filter_map(|x| x.bounded_by()))
53            .cloned()
54            .collect();
55
56        self.set_bounded_by(Envelope::from_envelopes(&envelopes));
57    }
58
59    pub fn apply_transform_recursive(&mut self, m: &Isometry3<f64>) {
60        self.abstract_construction_surface.apply_transform(m);
61
62        self.door_surface
63            .iter_mut()
64            .for_each(|x| x.apply_transform(m));
65        self.window_surface
66            .iter_mut()
67            .for_each(|x| x.apply_transform(m));
68    }
69}
70
71impl AsAbstractConstructionSurface for WallSurface {
72    fn abstract_construction_surface(&self) -> &AbstractConstructionSurface {
73        &self.abstract_construction_surface
74    }
75}
76
77impl AsAbstractConstructionSurfaceMut for WallSurface {
78    fn abstract_construction_surface_mut(&mut self) -> &mut AbstractConstructionSurface {
79        &mut self.abstract_construction_surface
80    }
81}
82
83crate::impl_abstract_construction_surface_traits!(WallSurface);
84
85impl From<WallSurface> for CityObjectKind {
86    fn from(item: WallSurface) -> Self {
87        CityObjectKind::WallSurface(item)
88    }
89}
90
91impl Visitable for WallSurface {
92    fn accept<V: Visitor>(&self, visitor: &mut V) {
93        visitor.visit_wall_surface(self);
94        self.door_surface.iter().for_each(|x| x.accept(visitor));
95        self.window_surface.iter().for_each(|x| x.accept(visitor));
96    }
97}