/
bottle.rs
67 lines (59 loc) · 2.72 KB
/
bottle.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Modeling a bottle.
//!
//! This is a technical indicator for comparing with Open CASCADE Technology, a great senior.
//! We want to reproduce the bottle made in the [OCCT tutorial].
//! Now, one cannot make a fillet or run boolean operations by truck.
//! So, the bottle made by this script is not completed.
//!
//! Generated json file can be visualized by `simple-shape-viewer`, an example of `truck-rendimpl`.
//!
//! [OCCT tutorial]: https://dev.opencascade.org/doc/overview/html/occt__tutorial.html
use std::f64::consts::PI;
use truck_modeling::*;
fn body_shell(bottom: f64, height: f64, width: f64, thickness: f64) -> Shell {
let vertex0 = builder::vertex(Point3::new(-width / 2.0, bottom, thickness / 4.0));
let vertex1 = builder::vertex(Point3::new(width / 2.0, bottom, thickness / 4.0));
let transit = Point3::new(0.0, bottom, thickness / 2.0);
let arc0 = builder::circle_arc(&vertex0, &vertex1, transit);
let arc1 = builder::rotated(&arc0, Point3::origin(), Vector3::unit_y(), Rad(PI));
let face = builder::homotopy(&arc0, &arc1.inverse());
let solid = builder::tsweep(&face, Vector3::new(0.0, height, 0.0));
solid.into_boundaries().pop().unwrap()
}
fn cylinder(bottom: f64, height: f64, radius: f64) -> Shell {
let vertex = builder::vertex(Point3::new(0.0, bottom, radius));
let circle = builder::rsweep(&vertex, Point3::origin(), Vector3::unit_y(), Rad(7.0));
let disk = builder::try_attach_plane(&[circle]).unwrap();
let solid = builder::tsweep(&disk, Vector3::new(0.0, height, 0.0));
solid.into_boundaries().pop().unwrap()
}
fn grue_body_neck(body: &mut Shell, neck: Shell) {
let body_seiling = body.last_mut().unwrap();
let wire = neck[0].boundaries()[0].clone();
body_seiling.add_boundary(wire);
body.extend(neck.into_iter().skip(1));
}
fn bottle(height: f64, width: f64, thickness: f64) -> Solid {
let mut body = body_shell(0.0, height, width, thickness);
let neck = cylinder(height, height / 10.0, thickness / 4.0);
grue_body_neck(&mut body, neck);
let eps = height / 50.0;
let mut inner_body = body_shell(
eps,
height - 2.0 * eps,
width - 2.0 * eps,
thickness - 2.0 * eps,
);
let inner_neck = cylinder(height - eps, height / 10.0 + eps, thickness / 4.0 - eps);
grue_body_neck(&mut inner_body, inner_neck);
let inner_hat = inner_body.pop().unwrap();
let wire = inner_hat.into_boundaries()[0].inverse();
body.last_mut().unwrap().add_boundary(wire);
body.extend(inner_body.into_iter().map(|face| face.inverse()));
Solid::new(vec![body])
}
fn main() {
let bottle = bottle(1.4, 1.0, 0.6);
let json = serde_json::to_vec_pretty(&bottle).unwrap();
std::fs::write("bottle.json", json).unwrap();
}