Skip to main content

ecitygml_core/model/appearance/
appearance.rs

1use crate::model::appearance::AbstractSurfaceDataProperty;
2use crate::model::common::{ForEachFeatureMut, IterFeatures};
3use crate::model::core::refs::AbstractFeatureKindRef;
4use crate::model::core::refs::AbstractFeatureKindRefMut;
5use crate::model::core::{AbstractAppearance, AsAbstractAppearance, AsAbstractAppearanceMut};
6use egml::model::base::Id;
7use egml::model::common::{ApplyTransform, ComputeEnvelope};
8use egml::model::geometry::Envelope;
9use nalgebra::{Isometry3, Rotation3, Scale3, Transform3, Vector3};
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct Appearance {
13    pub(crate) abstract_appearance: AbstractAppearance,
14    theme: Option<String>,
15    surface_data: Vec<AbstractSurfaceDataProperty>,
16}
17
18impl Appearance {
19    pub fn new(id: Id) -> Self {
20        Self::from_abstract_appearance(AbstractAppearance::new(id))
21    }
22
23    pub fn from_abstract_appearance(abstract_appearance: AbstractAppearance) -> Self {
24        Self {
25            abstract_appearance,
26            theme: None,
27            surface_data: Vec::new(),
28        }
29    }
30
31    pub fn theme(&self) -> Option<&str> {
32        self.theme.as_deref()
33    }
34
35    pub fn set_theme(&mut self, theme: String) {
36        self.theme = Some(theme);
37    }
38
39    pub fn set_theme_opt(&mut self, theme: Option<String>) {
40        self.theme = theme;
41    }
42
43    pub fn clear_theme(&mut self) {
44        self.theme = None;
45    }
46
47    pub fn surface_data(&self) -> &[AbstractSurfaceDataProperty] {
48        &self.surface_data
49    }
50
51    pub fn surface_data_mut(&mut self) -> &mut [AbstractSurfaceDataProperty] {
52        &mut self.surface_data
53    }
54
55    pub fn set_surface_data(&mut self, surface_data: Vec<AbstractSurfaceDataProperty>) {
56        self.surface_data = surface_data;
57    }
58
59    pub fn push_surface_data(&mut self, surface_data: AbstractSurfaceDataProperty) {
60        self.surface_data.push(surface_data);
61    }
62
63    pub fn extend_surface_data(
64        &mut self,
65        surface_data: impl IntoIterator<Item = AbstractSurfaceDataProperty>,
66    ) {
67        self.surface_data.extend(surface_data);
68    }
69}
70
71impl AsAbstractAppearance for Appearance {
72    fn abstract_appearance(&self) -> &AbstractAppearance {
73        &self.abstract_appearance
74    }
75}
76
77impl AsAbstractAppearanceMut for Appearance {
78    fn abstract_appearance_mut(&mut self) -> &mut AbstractAppearance {
79        &mut self.abstract_appearance
80    }
81}
82
83crate::impl_abstract_appearance_traits!(Appearance);
84crate::impl_abstract_appearance_mut_traits!(Appearance);
85crate::impl_has_feature_type!(Appearance, Appearance);
86
87impl IterFeatures for Appearance {
88    fn iter_features(&self) -> Box<dyn Iterator<Item = AbstractFeatureKindRef<'_>> + '_> {
89        Box::new(
90            std::iter::once(self.into())
91                .chain(self.abstract_appearance.iter_features())
92                .chain(
93                    self.surface_data
94                        .iter()
95                        .filter_map(|x| x.object())
96                        .flat_map(|x| x.iter_features()),
97                ),
98        )
99    }
100}
101
102impl ForEachFeatureMut for Appearance {
103    fn for_each_feature_mut<F: FnMut(AbstractFeatureKindRefMut<'_>)>(&mut self, f: &mut F) {
104        f((&mut *self).into());
105        self.abstract_appearance.for_each_feature_mut(f);
106
107        for prop in &mut self.surface_data {
108            if let Some(x) = prop.object_mut() {
109                x.for_each_feature_mut(f);
110            }
111        }
112    }
113}
114
115impl ComputeEnvelope for Appearance {
116    fn compute_envelope(&self) -> Option<Envelope> {
117        self.abstract_appearance.compute_envelope()
118    }
119}
120
121impl ApplyTransform for Appearance {
122    fn apply_transform(&mut self, m: Transform3<f64>) {
123        self.abstract_appearance.apply_transform(m);
124    }
125
126    fn apply_isometry(&mut self, isometry: Isometry3<f64>) {
127        self.abstract_appearance.apply_isometry(isometry);
128    }
129
130    fn apply_translation(&mut self, vector: Vector3<f64>) {
131        self.abstract_appearance.apply_translation(vector);
132    }
133
134    fn apply_rotation(&mut self, rotation: Rotation3<f64>) {
135        self.abstract_appearance.apply_rotation(rotation);
136    }
137
138    fn apply_scale(&mut self, scale: Scale3<f64>) {
139        self.abstract_appearance.apply_scale(scale);
140    }
141}