1use crate::model::Unit;
2use crate::utils::hardware::HardwareCapabilities;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Default, Serialize, Deserialize)]
12pub struct ModelStats {
13 pub unit: Unit,
15 pub generator: Option<String>,
17 pub metadata: HashMap<String, String>,
19 pub geometry: GeometryStats,
21 pub materials: MaterialsStats,
23 pub production: ProductionStats,
25 pub displacement: DisplacementStats,
27 pub vendor: VendorData,
29 pub system_info: HardwareCapabilities,
31 pub thumbnails: ThumbnailStats,
33}
34
35#[derive(Debug, Clone, Default, Serialize, Deserialize)]
36pub struct ThumbnailStats {
37 pub package_thumbnail_present: bool,
38 pub object_thumbnail_count: usize,
39}
40
41#[derive(Debug, Clone, Default, Serialize, Deserialize)]
42pub struct MaterialsStats {
43 pub base_materials_count: usize,
44 pub color_groups_count: usize,
45 pub texture_2d_groups_count: usize,
46 pub composite_materials_count: usize,
47 pub multi_properties_count: usize,
48}
49
50#[derive(Debug, Clone, Default, Serialize, Deserialize)]
55pub struct GeometryStats {
56 pub object_count: usize,
58 pub instance_count: usize,
60 pub triangle_count: u64,
62 pub vertex_count: u64,
64 pub bounding_box: Option<BoundingBox>,
66 pub surface_area: f64,
68 pub volume: f64,
70 pub is_manifold: bool,
72 #[serde(default)]
74 pub type_counts: HashMap<String, usize>,
75}
76
77#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
83pub struct BoundingBox {
84 pub min: [f32; 3],
86 pub max: [f32; 3],
88}
89
90impl BoundingBox {
91 pub fn transform(&self, matrix: glam::Mat4) -> Self {
92 let corners = [
93 glam::Vec3::new(self.min[0], self.min[1], self.min[2]),
94 glam::Vec3::new(self.min[0], self.min[1], self.max[2]),
95 glam::Vec3::new(self.min[0], self.max[1], self.min[2]),
96 glam::Vec3::new(self.min[0], self.max[1], self.max[2]),
97 glam::Vec3::new(self.max[0], self.min[1], self.min[2]),
98 glam::Vec3::new(self.max[0], self.min[1], self.max[2]),
99 glam::Vec3::new(self.max[0], self.max[1], self.min[2]),
100 glam::Vec3::new(self.max[0], self.max[1], self.max[2]),
101 ];
102
103 let mut transformed_min = glam::Vec3::splat(f32::INFINITY);
104 let mut transformed_max = glam::Vec3::splat(f32::NEG_INFINITY);
105
106 for corner in corners {
107 let transformed = matrix.transform_point3(corner);
108 transformed_min = transformed_min.min(transformed);
109 transformed_max = transformed_max.max(transformed);
110 }
111
112 Self {
113 min: [transformed_min.x, transformed_min.y, transformed_min.z],
114 max: [transformed_max.x, transformed_max.y, transformed_max.z],
115 }
116 }
117}
118
119#[derive(Debug, Clone, Default, Serialize, Deserialize)]
120pub struct ProductionStats {
121 pub uuid_count: usize,
122}
123
124#[derive(Debug, Clone, Default, Serialize, Deserialize)]
125pub struct DisplacementStats {
126 pub mesh_count: usize,
127 pub texture_count: usize,
128 pub normal_count: u64,
129 pub gradient_count: u64,
130 pub displaced_triangle_count: u64,
131 pub total_triangle_count: u64,
132}
133
134#[derive(Debug, Clone, Default, Serialize, Deserialize)]
135pub struct VendorData {
136 pub printer_model: Option<String>,
137 pub filaments: Vec<FilamentInfo>,
138 pub plates: Vec<PlateInfo>,
139 pub print_time_estimate: Option<String>,
140}
141
142#[derive(Debug, Clone, Default, Serialize, Deserialize)]
143pub struct FilamentInfo {
144 pub type_: String,
145 pub color: Option<String>,
146}
147
148#[derive(Debug, Clone, Default, Serialize, Deserialize)]
149pub struct PlateInfo {
150 pub id: u32,
151 pub name: Option<String>,
152 }