use ifc_model::{EntityId, Value};
use crate::error::GeometryError;
use crate::slots::profile_slot as base;
use super::profile::ProfileType;
use super::{invalid, require_finite};
#[derive(Debug, Clone, Copy, Default)]
pub struct ProfileHeader<'a> {
pub name: Option<&'a str>,
pub position: Option<EntityId>,
}
#[derive(Debug, Clone, Copy)]
pub struct IShapeDims {
pub width: f64,
pub depth: f64,
pub web_thickness: f64,
pub flange_thickness: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct FlangedDims {
pub depth: f64,
pub flange_width: f64,
pub web_thickness: f64,
pub flange_thickness: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct CShapeDims {
pub depth: f64,
pub width: f64,
pub wall_thickness: f64,
pub girth: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct AsymmetricIDims {
pub bottom_flange_width: f64,
pub overall_depth: f64,
pub web_thickness: f64,
pub bottom_flange_thickness: f64,
pub top_flange_width: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct RectangleHollowDims {
pub x_dim: f64,
pub y_dim: f64,
pub wall_thickness: f64,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct RectangleHollowFillets {
pub inner: Option<f64>,
pub outer: Option<f64>,
}
#[derive(Debug, Clone, Copy)]
pub struct TrapeziumDims {
pub bottom_x_dim: f64,
pub top_x_dim: f64,
pub y_dim: f64,
pub top_x_offset: f64,
}
pub(super) fn parameterized(
type_name: &'static str,
arity: usize,
header: ProfileHeader<'_>,
) -> Vec<Value> {
let mut attrs = vec![Value::Null; arity];
debug_assert!(!type_name.is_empty());
attrs[base::PROFILE_TYPE] = Value::Enum(ProfileType::Area.token().into());
attrs[base::PROFILE_NAME] = header.name.map_or(Value::Null, |n| Value::Text(n.into()));
attrs[base::POSITION] = header.position.map_or(Value::Null, Value::Ref);
attrs
}
pub(super) fn positive(
type_name: &'static str,
attribute: &'static str,
value: f64,
) -> Result<(), GeometryError> {
require_finite(type_name, attribute, &[value])?;
if value <= 0.0 {
return Err(invalid(
type_name,
attribute,
format!("expected a positive length, got {value}"),
));
}
Ok(())
}
pub(super) fn non_negative(
type_name: &'static str,
attribute: &'static str,
value: Option<f64>,
) -> Result<(), GeometryError> {
let Some(value) = value else { return Ok(()) };
require_finite(type_name, attribute, &[value])?;
if value < 0.0 {
return Err(invalid(
type_name,
attribute,
format!("expected a non-negative length, got {value}"),
));
}
Ok(())
}
pub(super) fn rule(
type_name: &'static str,
attribute: &'static str,
detail: String,
) -> GeometryError {
invalid(type_name, attribute, detail)
}
pub(super) fn put_opt(attrs: &mut [Value], index: usize, value: Option<f64>) {
if let Some(value) = value {
attrs[index] = Value::Real(value);
}
}
mod closed_section;
mod flanged_section;
pub use closed_section::{
circle_hollow_profile, ellipse_profile, rectangle_hollow_profile, trapezium_profile,
};
pub use flanged_section::{
asymmetric_i_shape, c_shape, i_shape, l_shape, t_shape, u_shape, z_shape, AsymmetricIExtras,
IShapeExtras, LShapeExtras, TShapeExtras, UShapeExtras, ZShapeExtras,
};