kittycad_modeling_cmds/format/
mod.rs1use parse_display_derive::{Display, FromStr};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4
5use crate::shared::{FileExportFormat, FileExportFormat2d, FileImportFormat};
6
7pub mod dxf;
9pub mod fbx;
11pub mod gltf;
16pub mod obj;
18pub mod ply;
20pub mod step;
22pub mod stl;
24
25pub mod sldprt;
27
28#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
30#[serde(tag = "type", rename_all = "snake_case")]
31#[display(style = "snake_case")]
32#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
33#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
34pub enum OutputFormat2d {
35 #[display("{}: {0}")]
37 Dxf(dxf::export::Options),
38}
39
40#[deprecated(since = "0.2.96", note = "use `OutputFormat3d` instead")]
42pub type OutputFormat = OutputFormat3d;
43
44#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
46#[serde(tag = "type", rename_all = "snake_case")]
47#[display(style = "snake_case")]
48#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
49#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
50pub enum OutputFormat3d {
51 #[display("{}: {0}")]
53 Fbx(fbx::export::Options),
54 #[display("{}: {0}")]
59 Gltf(gltf::export::Options),
60 #[display("{}: {0}")]
62 Obj(obj::export::Options),
63 #[display("{}: {0}")]
65 Ply(ply::export::Options),
66 #[display("{}: {0}")]
68 Step(step::export::Options),
69 #[display("{}: {0}")]
71 Stl(stl::export::Options),
72}
73
74#[deprecated(since = "0.2.96", note = "use `InputFormat3d` instead")]
76pub type InputFormat = InputFormat3d;
77
78#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
80#[serde(tag = "type", rename_all = "snake_case")]
81#[display(style = "snake_case")]
82#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
83#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
84pub enum InputFormat3d {
85 #[display("{}: {0}")]
87 Fbx(fbx::import::Options),
88 #[display("{}: {0}")]
92 Gltf(gltf::import::Options),
93 #[display("{}: {0}")]
95 Obj(obj::import::Options),
96 #[display("{}: {0}")]
98 Ply(ply::import::Options),
99 #[display("{}: {0}")]
101 Sldprt(sldprt::import::Options),
102 #[display("{}: {0}")]
104 Step(step::import::Options),
105 #[display("{}: {0}")]
107 Stl(stl::import::Options),
108}
109
110#[derive(Clone, Debug, Default, Display, Eq, FromStr, Hash, PartialEq, JsonSchema, Deserialize, Serialize)]
112#[display(style = "snake_case")]
113#[serde(rename_all = "snake_case", tag = "type")]
114#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
115#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
116pub enum Selection {
117 #[default]
119 DefaultScene,
120
121 #[display("{}: {index}")]
123 SceneByIndex {
124 index: usize,
126 },
127
128 #[display("{}: {name}")]
130 SceneByName {
131 name: String,
133 },
134
135 #[display("{}: {index}")]
137 MeshByIndex {
138 index: usize,
140 },
141
142 #[display("{}: {name}")]
144 MeshByName {
145 name: String,
147 },
148}
149
150#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
152pub struct VirtualFile {
153 pub path: std::path::PathBuf,
155 pub data: Vec<u8>,
157}
158
159impl VirtualFile {
160 pub fn has_extension(&self, required_extension: &str) -> bool {
162 self.path
163 .extension()
164 .and_then(std::ffi::OsStr::to_str)
165 .map(|extension| extension.eq_ignore_ascii_case(required_extension))
166 .unwrap_or(false)
167 }
168
169 fn read_fs_impl(path: std::path::PathBuf) -> std::io::Result<Self> {
170 let data = std::fs::read(&path)?;
171 Ok(Self { path, data })
172 }
173
174 pub fn read_fs<P>(path: P) -> std::io::Result<Self>
176 where
177 P: Into<std::path::PathBuf>,
178 {
179 Self::read_fs_impl(path.into())
180 }
181}
182
183impl From<OutputFormat3d> for FileExportFormat {
184 fn from(output_format: OutputFormat3d) -> Self {
185 match output_format {
186 OutputFormat3d::Fbx(_) => Self::Fbx,
187 OutputFormat3d::Gltf(_) => Self::Gltf,
188 OutputFormat3d::Obj(_) => Self::Obj,
189 OutputFormat3d::Ply(_) => Self::Ply,
190 OutputFormat3d::Step(_) => Self::Step,
191 OutputFormat3d::Stl(_) => Self::Stl,
192 }
193 }
194}
195
196impl From<OutputFormat2d> for FileExportFormat2d {
197 fn from(output_format: OutputFormat2d) -> Self {
198 match output_format {
199 OutputFormat2d::Dxf(_) => Self::Dxf,
200 }
201 }
202}
203
204impl From<FileExportFormat2d> for OutputFormat2d {
205 fn from(export_format: FileExportFormat2d) -> Self {
206 match export_format {
207 FileExportFormat2d::Dxf => OutputFormat2d::Dxf(Default::default()),
208 }
209 }
210}
211
212impl From<FileExportFormat> for OutputFormat3d {
213 fn from(export_format: FileExportFormat) -> Self {
214 match export_format {
215 FileExportFormat::Fbx => OutputFormat3d::Fbx(Default::default()),
216 FileExportFormat::Glb => OutputFormat3d::Gltf(gltf::export::Options {
217 storage: gltf::export::Storage::Binary,
218 ..Default::default()
219 }),
220 FileExportFormat::Gltf => OutputFormat3d::Gltf(gltf::export::Options {
221 storage: gltf::export::Storage::Embedded,
222 presentation: gltf::export::Presentation::Pretty,
223 }),
224 FileExportFormat::Obj => OutputFormat3d::Obj(Default::default()),
225 FileExportFormat::Ply => OutputFormat3d::Ply(Default::default()),
226 FileExportFormat::Step => OutputFormat3d::Step(Default::default()),
227 FileExportFormat::Stl => OutputFormat3d::Stl(stl::export::Options {
228 storage: stl::export::Storage::Ascii,
229 ..Default::default()
230 }),
231 }
232 }
233}
234
235impl From<InputFormat3d> for FileImportFormat {
236 fn from(input_format: InputFormat3d) -> Self {
237 match input_format {
238 InputFormat3d::Fbx(_) => Self::Fbx,
239 InputFormat3d::Gltf(_) => Self::Gltf,
240 InputFormat3d::Obj(_) => Self::Obj,
241 InputFormat3d::Ply(_) => Self::Ply,
242 InputFormat3d::Sldprt(_) => Self::Sldprt,
243 InputFormat3d::Step(_) => Self::Step,
244 InputFormat3d::Stl(_) => Self::Stl,
245 }
246 }
247}
248
249impl From<FileImportFormat> for InputFormat3d {
250 fn from(import_format: FileImportFormat) -> Self {
251 match import_format {
252 FileImportFormat::Fbx => InputFormat3d::Fbx(Default::default()),
253 FileImportFormat::Gltf => InputFormat3d::Gltf(Default::default()),
254 FileImportFormat::Obj => InputFormat3d::Obj(Default::default()),
255 FileImportFormat::Ply => InputFormat3d::Ply(Default::default()),
256 FileImportFormat::Sldprt => InputFormat3d::Sldprt(Default::default()),
257 FileImportFormat::Step => InputFormat3d::Step(Default::default()),
258 FileImportFormat::Stl => InputFormat3d::Stl(Default::default()),
259 }
260 }
261}