ifc_lite_processing/analytic_export/
occurrence.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Derived occurrence measurements and their serialized representation.
6
7use super::{DirectrixMetrics, SweptDiskNominalQuantities, SweptDiskOccurrence};
8use ifc_lite_geometry::analytic::AnalyticStatus;
9use serde::{ser::SerializeStruct, Serialize, Serializer};
10
11impl SweptDiskOccurrence {
12    /// Measurements of a complete world-space directrix, or `None` when its
13    /// description or derived measurements are unsupported.
14    pub fn directrix_metrics(&self) -> Option<DirectrixMetrics> {
15        if !matches!(self.status, AnalyticStatus::Complete) {
16            return None;
17        }
18        DirectrixMetrics::from_segments(&self.directrix).ok()
19    }
20
21    /// Nominal uncut tube measurements derived from the circular section and
22    /// complete centreline. These are not IFC-authored quantities or the final
23    /// volume of a boolean-modified or self-overlapping solid.
24    pub fn nominal_quantities(&self) -> Option<SweptDiskNominalQuantities> {
25        self.directrix_metrics()
26            .as_ref()
27            .and_then(|metrics| SweptDiskNominalQuantities::from_occurrence(self, metrics))
28    }
29}
30
31impl Serialize for SweptDiskOccurrence {
32    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33    where
34        S: Serializer,
35    {
36        let metrics = self.directrix_metrics();
37        let nominal_quantities = metrics
38            .as_ref()
39            .and_then(|metrics| SweptDiskNominalQuantities::from_occurrence(self, metrics));
40        let mut record = serializer.serialize_struct("SweptDiskOccurrence", 10)?;
41        record.serialize_field("solid_id", &self.solid_id)?;
42        record.serialize_field("directrix_id", &self.directrix_id)?;
43        record.serialize_field("mapping_path", &self.mapping_path)?;
44        record.serialize_field("source_modified", &self.source_modified)?;
45        record.serialize_field("Radius", &self.radius)?;
46        record.serialize_field("InnerRadius", &self.inner_radius)?;
47        record.serialize_field("Directrix", &self.directrix)?;
48        record.serialize_field("directrix_metrics", &metrics)?;
49        record.serialize_field("nominal_quantities", &nominal_quantities)?;
50        record.serialize_field("status", &self.status)?;
51        record.end()
52    }
53}