ifc_style/extent.rs
1//! `IfcPlanarExtent` and its `IfcPlanarBox` subtype.
2//!
3//! These are `IfcGeometricRepresentationItem` subtypes that carry no shape:
4//! they describe the 2D area a presentation element occupies. `ifc-geometry`
5//! classifies both `non-shape` with `ifc-style` as owner, so the typed reads
6//! live here rather than in a lowering path.
7
8use ifc_model::EntityId;
9
10use crate::error::StyleResult;
11use crate::view::Record;
12
13/// Borrowed projection of `IfcPlanarExtent`: a rectangular presentation area.
14///
15/// `SizeInX`/`SizeInY` are `IfcLengthMeasure`, which unlike the positive
16/// measures elsewhere in this crate permits zero and negative values, so they
17/// are read as plain numbers without a range guard.
18#[derive(Debug, Clone, Copy)]
19pub struct PlanarExtent<'m, 's> {
20 record: Record<'m, 's>,
21}
22
23impl<'m, 's> PlanarExtent<'m, 's> {
24 pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
25 Self { record }
26 }
27
28 /// The `SizeInX` attribute. Mandatory.
29 pub fn size_in_x(&self) -> StyleResult<f64> {
30 self.record.required_number("SizeInX")
31 }
32
33 /// The `SizeInY` attribute. Mandatory.
34 pub fn size_in_y(&self) -> StyleResult<f64> {
35 self.record.required_number("SizeInY")
36 }
37}
38
39/// Borrowed projection of `IfcPlanarBox`: a planar extent plus the placement
40/// that positions it.
41#[derive(Debug, Clone, Copy)]
42pub struct PlanarBox<'m, 's> {
43 record: Record<'m, 's>,
44}
45
46impl<'m, 's> PlanarBox<'m, 's> {
47 pub(crate) fn from_record(record: Record<'m, 's>) -> Self {
48 Self { record }
49 }
50
51 /// The inherited `IfcPlanarExtent` attributes.
52 #[must_use]
53 pub fn planar_extent(&self) -> PlanarExtent<'m, 's> {
54 PlanarExtent::from_record(self.record)
55 }
56
57 /// The `Placement` attribute. Mandatory.
58 ///
59 /// `IfcAxis2Placement` is a select over the 2D and 3D placements, so both
60 /// are admitted; the id is returned for a geometry-side reader to resolve
61 /// rather than interpreted here.
62 pub fn placement(&self) -> StyleResult<EntityId> {
63 self.record.required_ref_select(
64 "Placement",
65 "IfcAxis2Placement",
66 &["IfcAxis2Placement2D", "IfcAxis2Placement3D"],
67 )
68 }
69}