ifc_geometry/authoring/
placement.rs1use ifc_model::{Entity, EntityId, Transaction, Value};
7
8use crate::error::GeometryError;
9use crate::resource::direction::slot as direction_slot;
10use crate::resource::placement::slot as placement_slot;
11use crate::resource::point::slot as point_slot;
12
13use super::{invalid, reals, require_finite};
14
15pub fn cartesian_point(tx: &mut Transaction, coords: &[f64]) -> Result<EntityId, GeometryError> {
25 if coords.is_empty() || coords.len() > 3 {
26 return Err(invalid(
27 "IFCCARTESIANPOINT",
28 "Coordinates",
29 format!("expected 1..=3 coordinates, got {}", coords.len()),
30 ));
31 }
32 require_finite("IFCCARTESIANPOINT", "Coordinates", coords)?;
33 let mut attrs = vec![Value::Null];
34 attrs[point_slot::cartesian_point::COORDINATES] = reals(coords);
35 Ok(tx.create(Entity::new("IFCCARTESIANPOINT", attrs)))
36}
37
38pub fn direction(tx: &mut Transaction, ratios: &[f64]) -> Result<EntityId, GeometryError> {
50 if ratios.len() < 2 || ratios.len() > 3 {
51 return Err(invalid(
52 "IFCDIRECTION",
53 "DirectionRatios",
54 format!("expected 2..=3 ratios, got {}", ratios.len()),
55 ));
56 }
57 require_finite("IFCDIRECTION", "DirectionRatios", ratios)?;
58 if ratios.iter().all(|r| *r == 0.0) {
59 return Err(invalid(
60 "IFCDIRECTION",
61 "DirectionRatios",
62 "all ratios are zero, which denotes no direction",
63 ));
64 }
65 let mut attrs = vec![Value::Null];
66 attrs[direction_slot::direction::DIRECTION_RATIOS] = reals(ratios);
67 Ok(tx.create(Entity::new("IFCDIRECTION", attrs)))
68}
69
70pub fn axis2_placement_3d(
76 tx: &mut Transaction,
77 location: EntityId,
78 axis: Option<EntityId>,
79 ref_direction: Option<EntityId>,
80) -> EntityId {
81 let mut attrs = vec![Value::Null, Value::Null, Value::Null];
82 attrs[placement_slot::LOCATION] = Value::Ref(location);
83 attrs[placement_slot::axis2_3d::AXIS] = axis.map_or(Value::Null, Value::Ref);
84 attrs[placement_slot::axis2_3d::REF_DIRECTION] = ref_direction.map_or(Value::Null, Value::Ref);
85 tx.create(Entity::new("IFCAXIS2PLACEMENT3D", attrs))
86}
87
88pub fn axis2_placement_2d(
94 tx: &mut Transaction,
95 location: EntityId,
96 ref_direction: Option<EntityId>,
97) -> EntityId {
98 let mut attrs = vec![Value::Null, Value::Null];
99 attrs[placement_slot::LOCATION] = Value::Ref(location);
100 attrs[placement_slot::axis2_2d::REF_DIRECTION] = ref_direction.map_or(Value::Null, Value::Ref);
101 tx.create(Entity::new("IFCAXIS2PLACEMENT2D", attrs))
102}