use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MeshTextureData {
pub rgba: Vec<u8>,
pub width: u32,
pub height: u32,
pub repeat_s: bool,
pub repeat_t: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MeshData {
pub express_id: u32,
pub ifc_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub global_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_layer: Option<String>,
pub positions: Vec<f32>,
pub normals: Vec<f32>,
pub indices: Vec<u32>,
pub color: [f32; 4],
#[serde(skip_serializing_if = "Option::is_none")]
pub material_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub geometry_item_id: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<BTreeMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uvs: Option<Vec<f32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub texture: Option<MeshTextureData>,
#[serde(default, skip_serializing_if = "geometry_class_is_occurrence")]
pub geometry_class: u8,
#[serde(default, skip_serializing_if = "origin_is_zero")]
pub origin: [f64; 3],
}
fn geometry_class_is_occurrence(class: &u8) -> bool {
*class == 0
}
fn origin_is_zero(origin: &[f64; 3]) -> bool {
origin[0] == 0.0 && origin[1] == 0.0 && origin[2] == 0.0
}
impl MeshData {
pub fn new(
express_id: u32,
ifc_type: String,
positions: Vec<f32>,
normals: Vec<f32>,
indices: Vec<u32>,
color: [f32; 4],
) -> Self {
Self {
express_id,
ifc_type,
global_id: None,
name: None,
presentation_layer: None,
positions,
normals,
indices,
color,
material_name: None,
geometry_item_id: None,
properties: None,
uvs: None,
texture: None,
geometry_class: 0,
origin: [0.0; 3],
}
}
pub fn with_geometry_class(mut self, geometry_class: u8) -> Self {
self.geometry_class = geometry_class;
self
}
pub fn with_origin(mut self, origin: [f64; 3]) -> Self {
self.origin = origin;
self
}
pub fn with_texture(mut self, uvs: Vec<f32>, texture: MeshTextureData) -> Self {
self.uvs = Some(uvs);
self.texture = Some(texture);
self
}
pub fn with_element_metadata(
mut self,
global_id: Option<String>,
name: Option<String>,
presentation_layer: Option<String>,
) -> Self {
self.global_id = global_id;
self.name = name;
self.presentation_layer = presentation_layer;
self
}
pub fn with_style_metadata(
mut self,
material_name: Option<String>,
geometry_item_id: Option<u32>,
) -> Self {
self.material_name = material_name;
self.geometry_item_id = geometry_item_id;
self
}
pub fn with_properties(mut self, properties: Option<BTreeMap<String, String>>) -> Self {
self.properties = properties;
self
}
pub fn vertex_count(&self) -> usize {
self.positions.len() / 3
}
pub fn triangle_count(&self) -> usize {
self.indices.len() / 3
}
pub fn is_empty(&self) -> bool {
self.positions.is_empty() || self.indices.is_empty()
}
}