:3
This commit is contained in:
commit
ddc7e4f6ce
9 changed files with 741 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
250
Cargo.lock
generated
Normal file
250
Cargo.lock
generated
Normal file
|
@ -0,0 +1,250 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "deckbox"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glam",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17fcdf9683c406c2fc4d124afd29c0d595e22210d633cbdb8695ba9935ab1dc6"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.170"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"zerocopy 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "deckbox"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
glam = "0.30.0"
|
||||
rand = "0.9.0"
|
BIN
deckbox.stl
Normal file
BIN
deckbox.stl
Normal file
Binary file not shown.
BIN
deckbox_part2.stl
Normal file
BIN
deckbox_part2.stl
Normal file
Binary file not shown.
BIN
deckbox_part3.stl
Normal file
BIN
deckbox_part3.stl
Normal file
Binary file not shown.
1
output/output.scad
Normal file
1
output/output.scad
Normal file
|
@ -0,0 +1 @@
|
|||
$fa= 0.1;$fn= 150;difference(){ union(){ translate([-3, -3, -3]) { cube([25, 25, 15], center=false); } translate([1.5, 1.5, 12]) { cube([20.5, 20.5, 1], center=false); } } cube([50, 50, 7], center=false); {translate([-3, -3, 0]) { rotate([0, 0, 45]) { cube([2, 50, 50], center=true); } }mirror([0, 1, 0]) { rotate([90, 0, 0]) { translate([-3, -3, 0]) { rotate([0, 0, 45]) { cube([2, 50, 50], center=true); } } } }mirror([1, 0, 0]) { rotate([0, -90, 0]) { translate([-3, -3, 0]) { rotate([0, 0, 45]) { cube([2, 50, 50], center=true); } } } }} {translate([22, -3, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } }mirror([0, 1, 0]) { rotate([90, 0, 0]) { translate([22, -3, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } } } }mirror([1, 0, 0]) { rotate([0, -90, 0]) { translate([22, -3, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } } } }} {translate([-3, 22, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } }mirror([0, 1, 0]) { rotate([90, 0, 0]) { translate([-3, 22, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } } } }mirror([1, 0, 0]) { rotate([0, -90, 0]) { translate([-3, 22, 0]) { rotate([0, 0, -45]) { cube([2, 50, 50], center=true); } } } }} translate([10, 10, 0]) { cube([50, 50, 50], center=false); } translate([5, 5, 8.9]) { cylinder(h=2.2, r1=3.2, r2=3.2); } translate([5, 5, 8.9]) { rotate([0, 0, 45]) { translate([0, -3.2, 0]) { cube([50, 6.4, 2.2], center=false); } } } }translate([7, 7, 0]) { cube([15, 15, 3], center=false); }translate([-0.001, -0.001, -0.001]) { cube([7.001, 7.001, 7.001], center=false); }
|
288
src/main.rs
Normal file
288
src/main.rs
Normal file
|
@ -0,0 +1,288 @@
|
|||
mod rcad;
|
||||
use crate::rcad::*;
|
||||
|
||||
const STICK: f32 = 7.;
|
||||
const WOOD: f32 = 4.;
|
||||
const SIDEPLATE_LENGTH: f32 = 25.;
|
||||
const SIDEPLATE_THICK: f32 = 3.;
|
||||
const TAMPER: f32 = 2.;
|
||||
const TOP_HEIGHT: f32 = 10.;
|
||||
const TOP_OVERLAP_TOP: f32 = 5.;
|
||||
const TOP_OVERLAP_MIDDLE: f32 = 3.;
|
||||
const TOP_OVERLAP_INNER: f32 = 3.;
|
||||
const MAGNET_RADIUS: f32 = 3.2;
|
||||
const MAGNET_THICK: f32 = 2.2;
|
||||
const INSET_HEIGHT: f32 = 1.;
|
||||
const INSET_RIM: f32 = 1.;
|
||||
const INSET_GAP: f32 = 0.5;
|
||||
const TOP_TOP_HEIGHT: f32 = 15.;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
let mut data = init()?;
|
||||
data.push_str(&top_top()?);
|
||||
|
||||
process(data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn top_top() -> Result<String, std::io::Error> {
|
||||
let mut data = String::new();
|
||||
|
||||
data.push_str(&difference(&vec![
|
||||
union(&vec![
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
cube(SIDEPLATE_LENGTH, SIDEPLATE_LENGTH, TOP_TOP_HEIGHT, false),
|
||||
),
|
||||
translate(
|
||||
INSET_RIM + INSET_GAP,
|
||||
INSET_RIM + INSET_GAP,
|
||||
TOP_TOP_HEIGHT - SIDEPLATE_THICK,
|
||||
cube(
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK - INSET_RIM - INSET_GAP,
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK - INSET_RIM - INSET_GAP,
|
||||
INSET_HEIGHT,
|
||||
false,
|
||||
),
|
||||
),
|
||||
]),
|
||||
cube(INF, INF, STICK, false),
|
||||
corner_mirror(translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., 45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
corner_mirror(translate(
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
corner_mirror(translate(
|
||||
-SIDEPLATE_THICK,
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
translate(
|
||||
TOP_OVERLAP_MIDDLE + STICK,
|
||||
TOP_OVERLAP_MIDDLE + STICK,
|
||||
0.,
|
||||
cube(INF, INF, INF, false),
|
||||
),
|
||||
translate(
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_TOP_HEIGHT - SIDEPLATE_THICK + INSET_HEIGHT - MAGNET_THICK + STICK) / 2.,
|
||||
cylinder(MAGNET_THICK, MAGNET_RADIUS),
|
||||
),
|
||||
translate(
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_TOP_HEIGHT - SIDEPLATE_THICK + INSET_HEIGHT - MAGNET_THICK + STICK) / 2.,
|
||||
rotate(
|
||||
0.,
|
||||
0.,
|
||||
45.,
|
||||
translate(
|
||||
0.,
|
||||
-MAGNET_RADIUS,
|
||||
0.,
|
||||
cube(INF, MAGNET_RADIUS * 2., MAGNET_THICK, false),
|
||||
),
|
||||
),
|
||||
),
|
||||
]));
|
||||
data.push_str(&translate(
|
||||
STICK,
|
||||
STICK,
|
||||
0.,
|
||||
cube(
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
STICK - WOOD,
|
||||
false,
|
||||
),
|
||||
));
|
||||
data.push_str(
|
||||
&(translate(
|
||||
-EPS,
|
||||
-EPS,
|
||||
-EPS,
|
||||
cube(STICK + EPS, STICK + EPS, STICK + EPS, false),
|
||||
)),
|
||||
);
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
fn top() -> Result<String, std::io::Error> {
|
||||
let mut data = String::new();
|
||||
data.push_str(&difference(&vec![
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
cube(
|
||||
SIDEPLATE_LENGTH,
|
||||
SIDEPLATE_LENGTH,
|
||||
TOP_HEIGHT + TOP_OVERLAP_TOP,
|
||||
false,
|
||||
),
|
||||
),
|
||||
translate(0., 0., -EPS, cube(INF, INF, TOP_HEIGHT + EPS, false)),
|
||||
translate(
|
||||
TOP_OVERLAP_MIDDLE + STICK,
|
||||
TOP_OVERLAP_MIDDLE + STICK,
|
||||
0.,
|
||||
cube(INF, INF, INF, false),
|
||||
),
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., 45., cube(TAMPER, INF, INF, true)),
|
||||
),
|
||||
translate(
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
),
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
),
|
||||
mirror(
|
||||
1.,
|
||||
-1.,
|
||||
0.,
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
0.,
|
||||
rotate(0., -45., 0., cube(TAMPER, INF, INF, true)),
|
||||
),
|
||||
),
|
||||
translate(
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
TOP_HEIGHT + TOP_OVERLAP_TOP / 2. - MAGNET_THICK / 2. - INSET_HEIGHT / 2.,
|
||||
cylinder(MAGNET_THICK, MAGNET_RADIUS),
|
||||
),
|
||||
translate(
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
(TOP_OVERLAP_MIDDLE + STICK) / 2.,
|
||||
TOP_HEIGHT + TOP_OVERLAP_TOP / 2. - MAGNET_THICK / 2. - INSET_HEIGHT / 2.,
|
||||
rotate(
|
||||
0.,
|
||||
0.,
|
||||
45.,
|
||||
translate(
|
||||
0.,
|
||||
-MAGNET_RADIUS,
|
||||
0.,
|
||||
cube(INF, MAGNET_RADIUS * 2., MAGNET_THICK, false),
|
||||
),
|
||||
),
|
||||
),
|
||||
translate(
|
||||
INSET_RIM,
|
||||
INSET_RIM,
|
||||
TOP_HEIGHT + TOP_OVERLAP_TOP - INSET_HEIGHT,
|
||||
cube(INF, INF, INSET_HEIGHT + EPS, false),
|
||||
),
|
||||
]));
|
||||
data.push_str(&mirror(
|
||||
1.,
|
||||
-1.,
|
||||
0.,
|
||||
translate(
|
||||
0.,
|
||||
STICK,
|
||||
0.,
|
||||
cube(
|
||||
STICK - WOOD,
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
TOP_HEIGHT,
|
||||
false,
|
||||
),
|
||||
),
|
||||
));
|
||||
data.push_str(&mirror(
|
||||
1.,
|
||||
-1.,
|
||||
0.,
|
||||
translate(
|
||||
STICK,
|
||||
STICK,
|
||||
TOP_HEIGHT - TOP_OVERLAP_INNER,
|
||||
cube(
|
||||
TOP_OVERLAP_MIDDLE,
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
TOP_OVERLAP_INNER,
|
||||
false,
|
||||
),
|
||||
),
|
||||
));
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
fn full_corner() -> Result<(), std::io::Error> {
|
||||
let mut data = init()?;
|
||||
|
||||
data.push_str(&difference(&vec![
|
||||
translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
cube(SIDEPLATE_LENGTH, SIDEPLATE_LENGTH, SIDEPLATE_LENGTH, false),
|
||||
),
|
||||
cube(INF, INF, INF, false),
|
||||
corner_mirror(translate(
|
||||
-SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., 45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
corner_mirror(translate(
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
-SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
corner_mirror(translate(
|
||||
-SIDEPLATE_THICK,
|
||||
SIDEPLATE_LENGTH - SIDEPLATE_THICK,
|
||||
0.,
|
||||
rotate(0., 0., -45., cube(TAMPER, INF, INF, true)),
|
||||
)),
|
||||
]));
|
||||
data.push_str(&corner_mirror(translate(
|
||||
STICK,
|
||||
STICK,
|
||||
0.,
|
||||
cube(
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
SIDEPLATE_LENGTH - STICK - SIDEPLATE_THICK,
|
||||
STICK - WOOD,
|
||||
false,
|
||||
),
|
||||
)));
|
||||
data.push_str(
|
||||
&(translate(
|
||||
-EPS,
|
||||
-EPS,
|
||||
-EPS,
|
||||
cube(STICK + EPS, STICK + EPS, STICK + EPS, false),
|
||||
)),
|
||||
);
|
||||
|
||||
process(data)?;
|
||||
Ok(())
|
||||
}
|
193
src/rcad/mod.rs
Normal file
193
src/rcad/mod.rs
Normal file
|
@ -0,0 +1,193 @@
|
|||
use glam::f32::Vec2;
|
||||
use rand::Rng;
|
||||
use std::process::Command;
|
||||
use std::{fs, io};
|
||||
|
||||
pub const EPS: f32 = 0.001;
|
||||
pub const INF: f32 = 50.;
|
||||
|
||||
pub fn init() -> Result<String, io::Error> {
|
||||
if fs::exists("output")? {
|
||||
println!("output dir already exists, emptying");
|
||||
fs::remove_dir_all("output")?;
|
||||
}
|
||||
if let Ok(_) = fs::create_dir("output") {
|
||||
println!("successfully created output directory");
|
||||
} else {
|
||||
println!("could not create output directory");
|
||||
}
|
||||
|
||||
let mut data = String::new();
|
||||
data.push_str(&set("fa".into(), 0.1));
|
||||
data.push_str(&set("fn".into(), 150.));
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
pub fn process(data: String) -> Result<(), io::Error> {
|
||||
fs::write("./output/output.scad", data)?;
|
||||
let output = Command::new("flatpak")
|
||||
.arg("run")
|
||||
.arg("org.openscad.OpenSCAD")
|
||||
.arg("./output/output.scad")
|
||||
.output()?;
|
||||
println!("{:?}", output);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn corner_mirror(what: String) -> String {
|
||||
let mut res = String::new();
|
||||
res.push_str("{");
|
||||
res.push_str(&what);
|
||||
res.push_str(&mirror_nocopy(
|
||||
0.,
|
||||
1.,
|
||||
0.,
|
||||
rotate(90., 0., 0., what.clone()),
|
||||
));
|
||||
res.push_str(&mirror_nocopy(1., 0., 0., rotate(0., -90., 0., what)));
|
||||
res.push_str("}");
|
||||
res
|
||||
}
|
||||
|
||||
fn process_svg(path: &str) {
|
||||
let output = Command::new("inkscape")
|
||||
.arg(format!(
|
||||
"--actions=select:path1; object-stroke-to-path; export-filename:{};export-do",
|
||||
path
|
||||
))
|
||||
.arg(format!("{path}"))
|
||||
.output()
|
||||
.expect("Could not execute command");
|
||||
print!("{:?}", output);
|
||||
}
|
||||
|
||||
pub enum Path {
|
||||
Move(Vec2),
|
||||
Line(Vec2),
|
||||
Bezier((Vec2, Vec2, Vec2)),
|
||||
Close,
|
||||
}
|
||||
|
||||
fn path_to_svg(path: &Vec<Path>, stroke: Option<f32>) -> String {
|
||||
let mut s = String::from("<svg xmlns='http://www.w3.org/2000/svg'><path id='path1' ");
|
||||
if let Some(w) = stroke {
|
||||
s.push_str(&format!("fill='none' stroke='black' stroke-width='{w}' "));
|
||||
} else {
|
||||
s.push_str("fill='black' stroke='none' ");
|
||||
}
|
||||
s.push_str("d='");
|
||||
|
||||
for i in path {
|
||||
match i {
|
||||
Path::Move(p) => s.push_str(&format!("M {} {} ", p.x, p.y)),
|
||||
Path::Line(p) => s.push_str(&format!("L {} {} ", p.x, p.y)),
|
||||
Path::Bezier((c1, c2, p)) => s.push_str(&format!(
|
||||
"C {} {}, {} {}, {} {} ",
|
||||
c1.x, c1.y, c2.x, c2.y, p.x, p.y
|
||||
)),
|
||||
Path::Close => s.push_str("Z "),
|
||||
}
|
||||
}
|
||||
|
||||
s.push_str("'/></svg>");
|
||||
s
|
||||
}
|
||||
|
||||
fn path(path: &Vec<Path>, stroke: Option<f32>) -> String {
|
||||
let mut name = String::from("blah");
|
||||
let mut rng = rand::rng();
|
||||
name.push_str(&rng.random::<u32>().to_string());
|
||||
name.push_str(".svg");
|
||||
fs::write(format!("output/{}", name), path_to_svg(&path, stroke))
|
||||
.expect("Unable to write file");
|
||||
process_svg(&name);
|
||||
include(&name)
|
||||
}
|
||||
|
||||
pub fn set(var: String, value: f32) -> String {
|
||||
format!("${var}= {value};")
|
||||
}
|
||||
|
||||
pub struct ExOptions {
|
||||
height: f32,
|
||||
center: bool,
|
||||
convexity: f32,
|
||||
twist: f32,
|
||||
slices: f32,
|
||||
scale: f32,
|
||||
}
|
||||
impl Default for ExOptions {
|
||||
fn default() -> ExOptions {
|
||||
ExOptions {
|
||||
height: 1.0,
|
||||
center: true,
|
||||
convexity: 10.0,
|
||||
twist: 0.0,
|
||||
slices: 20.0,
|
||||
scale: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn include(what: &str) -> String {
|
||||
format!("import(file=\"{what}\");")
|
||||
}
|
||||
|
||||
pub fn linear_extrude(opt: ExOptions, what: String) -> String {
|
||||
format!("linear_extrude(height={height}, center={center}, convexity={convexity}, twist={twist}, slices={slices}, scale={scale}) {{ {what} }}",
|
||||
height=opt.height, center=opt.center,convexity=opt.convexity,twist=opt.twist,slices=opt.slices,scale=opt.scale)
|
||||
}
|
||||
pub fn rotate_extrude(angle: f32, convexity: f32, what: String) -> String {
|
||||
format!("rotate_extrude(angle={angle}, convexity={convexity}) {{ {what} }}")
|
||||
}
|
||||
pub fn circle(radius: f32) -> String {
|
||||
format!("circle({radius});")
|
||||
}
|
||||
pub fn sphere(radius: f32) -> String {
|
||||
format!("sphere({});", radius)
|
||||
}
|
||||
pub fn cube(width: f32, depth: f32, height: f32, center: bool) -> String {
|
||||
format!(
|
||||
"cube([{}, {}, {}], center={});",
|
||||
width, depth, height, center
|
||||
)
|
||||
}
|
||||
pub fn cylinder(height: f32, radius: f32) -> String {
|
||||
format!("cylinder(h={height}, r1={radius}, r2={radius});")
|
||||
}
|
||||
pub fn translate(x: f32, y: f32, z: f32, what: String) -> String {
|
||||
format!("translate([{}, {}, {}]) {{ {} }}", x, y, z, what)
|
||||
}
|
||||
pub fn rotate(x: f32, y: f32, z: f32, what: String) -> String {
|
||||
format!("rotate([{}, {}, {}]) {{ {} }}", x, y, z, what)
|
||||
}
|
||||
pub fn mirror(x: f32, y: f32, z: f32, what: String) -> String {
|
||||
format!(
|
||||
"mirror([{}, {}, {}]) {{ {} }} {{ {} }}",
|
||||
x, y, z, what, what
|
||||
)
|
||||
}
|
||||
pub fn mirror_nocopy(x: f32, y: f32, z: f32, what: String) -> String {
|
||||
format!("mirror([{}, {}, {}]) {{ {} }}", x, y, z, what)
|
||||
}
|
||||
pub fn intersection(what: &[String]) -> String {
|
||||
let mut s = format!("intersection(){{ ");
|
||||
for i in what.iter() {
|
||||
s = format!("{} {}", s, i);
|
||||
}
|
||||
format!("{} }}", s)
|
||||
}
|
||||
pub fn union(what: &[String]) -> String {
|
||||
let mut s = format!("union(){{ ");
|
||||
for i in what.iter() {
|
||||
s = format!("{} {}", s, i);
|
||||
}
|
||||
format!("{} }}", s)
|
||||
}
|
||||
pub fn difference(what: &[String]) -> String {
|
||||
let mut s = format!("difference(){{ ");
|
||||
for i in what.iter() {
|
||||
s = format!("{} {}", s, i);
|
||||
}
|
||||
format!("{} }}", s)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue