Skip to main content

ifc_style/light/
goniometric.rs

1//! `IfcLightSourceGoniometric`: the photometric light source.
2
3use ifc_model::EntityId;
4
5use crate::error::StyleResult;
6use crate::light::source::LightSource;
7use crate::view::Record;
8
9/// Members of the `IfcLightDistributionDataSourceSelect` type.
10///
11/// Kept beside the accessor that validates against it so the select's
12/// membership is stated once, in the same place it is enforced.
13const DISTRIBUTION_DATA_SOURCE: &[&str] =
14    &["IfcExternalReference", "IfcLightIntensityDistribution"];
15
16/// Borrowed projection of `IfcLightSourceGoniometric`: a real luminaire
17/// described by photometric data rather than a renderer's approximation.
18///
19/// This is the only light source carrying absolute photometric quantities
20/// (luminous flux, colour temperature, lamp technology). Every other subtype
21/// is a normalized shading construct. The values are reported exactly as
22/// authored; this crate performs no photometric or colour-space conversion.
23#[derive(Debug, Clone, Copy)]
24pub struct LightSourceGoniometric<'m, 's> {
25    record: Record<'m, 's>,
26}
27
28impl<'m, 's> LightSourceGoniometric<'m, 's> {
29    pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
30        Self { record }
31    }
32
33    /// The inherited `IfcLightSource` colour and intensity attributes.
34    pub fn light_source(&self) -> LightSource<'m, 's> {
35        LightSource::from_record(self.record)
36    }
37
38    /// The `Position` attribute: a mandatory `IfcAxis2Placement3D` reference.
39    ///
40    /// A full placement, not a bare point: a luminaire's intensity
41    /// distribution is defined in its own local axes, so the orientation is
42    /// what makes `IfcLightIntensityDistribution` angles meaningful.
43    pub fn position(&self) -> StyleResult<EntityId> {
44        self.record.required_ref("Position", "IfcAxis2Placement3D")
45    }
46
47    /// The `ColourAppearance` attribute, when authored: an `IfcColourRgb`
48    /// reference giving the perceived colour.
49    ///
50    /// Distinct from the inherited `LightColour`, which is the shading colour.
51    /// A lamp can have one chromaticity and be rendered with another.
52    pub fn colour_appearance(&self) -> StyleResult<Option<EntityId>> {
53        self.record.optional_ref("ColourAppearance", "IfcColourRgb")
54    }
55
56    /// The `ColourTemperature` attribute, an
57    /// `IfcThermodynamicTemperatureMeasure`.
58    ///
59    /// Mandatory. Reported in the file's own temperature unit; IFC's SI
60    /// default is kelvin, but the value is not converted here.
61    pub fn colour_temperature(&self) -> StyleResult<f64> {
62        self.record.required_number("ColourTemperature")
63    }
64
65    /// The `LuminousFlux` attribute, an `IfcLuminousFluxMeasure` (lumen under
66    /// the SI default). Mandatory.
67    pub fn luminous_flux(&self) -> StyleResult<f64> {
68        self.record.required_number("LuminousFlux")
69    }
70
71    /// The `LightEmissionSource` attribute: the lamp technology token from
72    /// `IfcLightEmissionSourceEnum`.
73    ///
74    /// Returned as the raw schema token rather than a Rust enum. The
75    /// enumeration is schema-versioned, and this crate's census marks such
76    /// tokens `SchemaValue` -- promoting one to a closed Rust type would make
77    /// a future schema's new member unrepresentable.
78    pub fn light_emission_source(&self) -> StyleResult<&'m str> {
79        self.record.required_enum("LightEmissionSource")
80    }
81
82    /// The `LightDistributionDataSource` attribute: a mandatory reference to
83    /// either an `IfcLightIntensityDistribution` (inline photometric data) or
84    /// an `IfcExternalReference` (e.g. an EULUMDAT or IES file).
85    ///
86    /// The select is validated, so a reference to an unrelated entity is a
87    /// typed [`crate::StyleError::ReferenceType`] rather than a surprise at
88    /// the point of use.
89    pub fn light_distribution_data_source(&self) -> StyleResult<EntityId> {
90        self.record.required_ref_select(
91            "LightDistributionDataSource",
92            "IfcLightDistributionDataSourceSelect",
93            DISTRIBUTION_DATA_SOURCE,
94        )
95    }
96}