1use geom3d::{
2 surface::{BSplineSurface, SurfacePatch},
3 Float, Grid, Model, Point3,
4};
5
6fn load_teapot(
7 degree: (usize, usize),
8 division: (usize, usize),
9) -> std::io::Result<Model<SurfacePatch<BSplineSurface<Point3>>>> {
10 use std::fs::File;
11 use std::io::{BufRead, BufReader};
12 use std::path::Path;
13 use std::str::FromStr;
14
15 let file = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("assets/teapot.bpt");
16 let reader = BufReader::new(File::open(file)?);
17
18 let mut model = Model::new();
19 let mut points = Vec::new();
20 let mut current_cols = 0;
21
22 for line in reader.lines() {
23 let numbers = line?;
24 let items = numbers.split_whitespace().collect::<Vec<_>>();
25 if items.len() == 1 {
26 model
27 .faces
28 .reserve_exact(usize::from_str(items[0]).unwrap());
29 } else if items.len() == 2 {
30 if points.len() > 0 {
31 let surface = SurfacePatch {
32 surface: BSplineSurface::uniform_clamped(
33 Grid::from_vec(points, current_cols),
34 degree,
35 ),
36 parameter_range: ((0.0, 1.0), (0.0, 1.0)),
37 parameter_division: division,
38 };
39 model.add_face(surface);
40 }
41 let m = usize::from_str(items[0]).unwrap();
42 let n = usize::from_str(items[1]).unwrap();
43 points = Vec::with_capacity((m + 1) * (n + 1));
44 current_cols = n + 1;
45 } else if items.len() == 3 {
46 let point = Point3::new(
47 Float::from_str(items[0]).unwrap(),
48 Float::from_str(items[1]).unwrap(),
49 Float::from_str(items[2]).unwrap(),
50 );
51 points.push(point);
52 }
53 }
54 let surface = SurfacePatch {
56 surface: BSplineSurface::uniform_clamped(Grid::from_vec(points, current_cols), degree),
57 parameter_range: ((0.0, 1.0), (0.0, 1.0)),
58 parameter_division: division,
59 };
60 model.add_face(surface);
61 Ok(model)
62}
63
64fn main() {
65 let teapot = load_teapot((2, 2), (16, 16)).unwrap();
66 teapot.save_as_stl("teapot.stl").unwrap();
67 let teapot = load_teapot((3, 1), (16, 16)).unwrap();
68 teapot.save_as_obj("teapot.obj").unwrap();
69}