Skip to main content

ifc_style/texture/
surface.rs

1//! Base surface texture projection across IFC2x3, IFC4, and IFC4X3.
2
3use ifc_model::{EntityId, Value};
4
5use crate::error::StyleResult;
6use crate::view::Record;
7
8/// Borrowed projection of `IfcSurfaceTexture`, the abstract base attributes
9/// shared by `IfcBlobTexture`, `IfcPixelTexture`, and `IfcImageTexture`.
10#[derive(Debug, Clone, Copy)]
11pub struct SurfaceTexture<'m, 's> {
12    record: Record<'m, 's>,
13}
14
15impl<'m, 's> SurfaceTexture<'m, 's> {
16    pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
17        Self { record }
18    }
19
20    /// The entity id of this surface texture.
21    pub fn id(&self) -> EntityId {
22        self.record.id
23    }
24
25    /// The concrete IFC entity type name (e.g. `"IFCIMAGETEXTURE"`).
26    pub fn type_name(&self) -> &'m str {
27        &self.record.entity.type_name
28    }
29
30    /// The `RepeatS` flag: whether the texture tiles along its S axis. Mandatory.
31    pub fn repeat_s(&self) -> StyleResult<bool> {
32        self.record.required_bool("RepeatS")
33    }
34
35    /// The `RepeatT` flag: whether the texture tiles along its T axis. Mandatory.
36    pub fn repeat_t(&self) -> StyleResult<bool> {
37        self.record.required_bool("RepeatT")
38    }
39
40    /// IFC4/IFC4X3 texture mode; absent by schema in IFC2x3.
41    pub fn mode(&self) -> StyleResult<Option<&'m str>> {
42        self.record.optional_text("Mode")
43    }
44
45    /// IFC2x3 texture type; absent by schema in IFC4 and IFC4X3.
46    pub fn texture_type(&self) -> StyleResult<Option<&'m str>> {
47        self.record.optional_enum("TextureType")
48    }
49
50    /// The `TextureTransform` attribute, when authored.
51    pub fn texture_transform(&self) -> StyleResult<Option<EntityId>> {
52        self.record
53            .optional_ref("TextureTransform", "IfcCartesianTransformationOperator2D")
54    }
55
56    /// The `Parameter` attribute (a list of texture-specific parameter
57    /// strings), when authored.
58    pub fn parameters(&self) -> StyleResult<Option<&'m Value>> {
59        self.record.optional_raw("Parameter")
60    }
61}
62
63/// Borrowed projection of `IfcBlobTexture`: a raster image embedded inline as binary data.
64#[derive(Debug, Clone, Copy)]
65pub struct BlobTexture<'m, 's> {
66    record: Record<'m, 's>,
67}
68
69impl<'m, 's> BlobTexture<'m, 's> {
70    pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
71        Self { record }
72    }
73
74    /// The base `IfcSurfaceTexture` attributes shared with other texture kinds.
75    pub fn surface_texture(&self) -> SurfaceTexture<'m, 's> {
76        SurfaceTexture::from_record(self.record)
77    }
78
79    /// The `RasterFormat` attribute (e.g. `"PNG"`, `"JPEG"`). Mandatory.
80    pub fn raster_format(&self) -> StyleResult<&'m str> {
81        self.record.required_text("RasterFormat")
82    }
83
84    /// The `RasterCode` attribute: the raw binary image data. Mandatory.
85    pub fn raster_code(&self) -> StyleResult<&'m Value> {
86        self.record.value("RasterCode")
87    }
88}
89
90/// Borrowed projection of `IfcPixelTexture`: an explicit width/height/colour raster.
91#[derive(Debug, Clone, Copy)]
92pub struct PixelTexture<'m, 's> {
93    record: Record<'m, 's>,
94}
95
96impl<'m, 's> PixelTexture<'m, 's> {
97    pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
98        Self { record }
99    }
100
101    /// The `Width` attribute in pixels. Mandatory.
102    pub fn width(&self) -> StyleResult<i64> {
103        self.record.required_integer("Width")
104    }
105
106    /// The `Height` attribute in pixels. Mandatory.
107    pub fn height(&self) -> StyleResult<i64> {
108        self.record.required_integer("Height")
109    }
110
111    /// The `ColourComponents` attribute: the number of colour channels per pixel. Mandatory.
112    pub fn colour_components(&self) -> StyleResult<i64> {
113        self.record.required_integer("ColourComponents")
114    }
115
116    /// The `Pixel` attribute: the raw pixel byte list. Mandatory.
117    pub fn pixel(&self) -> StyleResult<&'m Value> {
118        self.record.value("Pixel")
119    }
120}