summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven <steven.vasilogianis@gmail.com>2022-03-16 14:26:00 -0400
committerSteven <steven.vasilogianis@gmail.com>2022-03-16 14:26:00 -0400
commita5ba57218ddfe0c0fb09ca388d76da38b3df9e26 (patch)
tree767bd3f19ef28aeb89d2ee67cad3d859c5aabc63
initial public repository
-rw-r--r--.gitmodules3
m---------BOSL20
-rw-r--r--Makefile23
-rw-r--r--README.md313
-rw-r--r--cubbies.scad209
-rwxr-xr-xcubbies.sh65
-rw-r--r--description1
-rwxr-xr-xshopenscad.sh238
m---------svasilogianis.github.io0
-rwxr-xr-xtest_fits.sh28
10 files changed, 880 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..faf109d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
1[submodule "BOSL2"]
2 path = BOSL2
3 url = https://github.com/revarbat/BOSL2
diff --git a/BOSL2 b/BOSL2
new file mode 160000
Subproject 9f5214adc0476f29aa9437dc401c01e8f1cd5da
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4275aa8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,23 @@
1README.html: pandoc.css README.md
2 pandoc --standalone --css=$^ -o $@
3 cp README.html svasilogianis.github.io/index.html
4
5stls: reference-stls test-fit-stls
6
7reference-stls: bottom.stl side.stl
8
9bottom.stl: shopenscad.sh cubbies.scad
10 part='"bottom"' ./shopenscad.sh cubbies.scad -o $@
11
12side.stl: shopenscad.sh cubbies.scad
13 part='"side"' ./shopenscad.sh cubbies.scad -o $@
14
15test_fit_stls = male_tabs-40-120-90-5-5-0-10-5-0.5-true.stl \
16 female_tabs-40-120-90-5-5-0-10-5-0.1-true.stl \
17 female_tabs-40-120-90-5-5-0-10-5-0.2-true.stl \
18 female_tabs-40-120-90-5-5-0-10-5-0.3-true.stl \
19 female_tabs-40-120-90-5-5-0-10-5-0.4-true.stl \
20 female_tabs-40-120-90-5-5-0-10-5-0.5-true.stl
21
22test-fit-stls: $(wildcard $test_fit_stls)
23 ./test_fits.sh
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..10a8611
--- /dev/null
+++ b/README.md
@@ -0,0 +1,313 @@
1# 3D Printable Parametric Cubbies #
2
3::: { .parts }
4
5Bottom Part:
6: [![Bottom Part](pictures/bottom.png "Bottom part")](pictures/side.png)
7
8Side Part:
9: [![Side](pictures/side.png "Side part"){#fig:side}](pictures/side.png)
10
11:::
12
133D printable parametric cubbies to store your 3D things. There are two distinct
14shapes — a `bottom` and a `side` — that are generated to the dimensions of your
15things, 3D printed, then assembled into modular storage units. The parts are
16optimized for printing by using [sparse
17structures](https://github.com/revarbat/BOSL2/wiki/walls.scad#module-sparse_strut)
18(to save material) that lay flat on the print bed (for ease of printing).
19
20## Pictures ##
21
22::: { .figs }
23
24![[Bottom part (printed)](pictures/bottom-printed-full.jpg "Bottom part, printed (full resolution)")](pictures/bottom-printed-thumbnail.jpg)
25
26![[Side part (printed)](pictures/side-printed-full.jpg "Side part, printed (full resolution)")](pictures/side-printed-thumbnail.jpg "Side part, printed")
27
28![[The Smurftruder with a fresh print](pictures/smurfstrusion-full.jpg "Smurfstrusion (full resolution)")](pictures/smurfstrusion-thumbnail.jpg)
29
30![[Mounted Cubbies (empty)](pictures/cubbies-mounted-empty-full.jpg "Mounted Cubbies (full resolution)")](pictures/cubbies-mounted-empty-thumbnail.jpg)
31
32![[Mounted Cubbies (empty, viewed from an angle)](pictures/cubbies-mounted-empty-angle-view-full.jpg "Empty cubbies, mounted (full resolution)")](pictures/cubbies-mounted-empty-angle-view-thumbnail.jpg)
33
34![[Mounted Cubbies (filled)](pictures/cubbies-full-full.jpg "Mounted cubbies, filled (full resolution)")](pictures/cubbies-full-thumbnail.jpg)
35
36![[Cubby Development](pictures/cubby-development-full.jpg "Cubby Development (full resolution)")](pictures/cubby-development-thumbnail.jpg)
37
38:::
39
40## Instructions ##
41
42### 🚫 Do NOT Scale in a Slicer 🚫 ###
43
44All models should be generated by specifying, at minimum, the parameters
45`cubby_width`, `cubby_depth`, and `cubby_height` in `cubbies.scad` (ways to do
46this are described below.) The dovetail joints are generated to a constant size
47(controlled through the parameters `tab_width`, `tab_padding`, and
48`tab_tolerance`) and should not be expected to fit after being scaled. Cubbies
49can be generated in in one of the following ways:
50
51 * Using the Thingiverse Customizer
52
53 * Using [OpenScad](https://openscad.org "Homepage for OpenSCAD \"The
54 Programmers Solid 3D Cad Modeller\"") -- either by using its builtin
55 customizer (choose `Window -> Customizer` from the menu bar if it is not
56 visible), or by modifying the variables at the top of the `cubbies.scad`
57 file. As mentioned above, the minimum paramaters to generate a custom sized
58 cubby are `cubby_width`, `cubby_depth`, and `cubby_height`. (Even those
59 arguments can be omitted, and your cubby will be whatever abritrary size I
60 decided as defaults (`40`,`120`,`90`).)
61
62 * There are two scripts for generating cubbies from the commandline:
63 `cubbies.sh` (run [`./cubbies.sh -h` for details](#cubbies.sh) can generate
64 entire sets of cubbies, and `shopenscad.sh` (run `./shopenscad.sh -h` for
65 details[^1]) generates individual parts.
66
67For a single cubby, you will need to print the side piece twice, and the bottom
68piece once. To add additional cubbies, print one bottom and one side. The bottom
69and side pieces can be flipped upside down so that the bottom piece's tabs fit
70into the extra unused holes of the side piece. You can also use this to control
71whether the screw tabs end up on the inside or outside of the cubby.
72
73You can print tolerance test fit pieces (which are the minimum material
74necessary to confirm that the pieces will fit with your printer and slicer
75settings). These test pieces were generated using `dovetail_test_fits.sh`, which
76you can use to generate your own at different tolerances (run
77`dovetail_test_fits.sh -h` for details). You can also generate them in `OpenSCAD`
78by specifying either `male_tabs` or `female_tabs` for the `part` paramaters (the
79`cubby_depth` paramater is respected as the length of those dovetail test
80pieces).
81
82## Parameters ##
83
84`part` Controls which part will be generated, and can be any of:
85
86: `bottom` — a bottom part whose dimensions will be `cubby_width` x `cubby_depth`.
87
88: `side` — a side part whose dimensions will be `cubby_depth` x `cubby_height`.
89
90: `female_tabs` — generates a shape consisting of the minimum amount of material
91 needed to test the dovetail joint fit. `cubby_depth` is respected as the
92 length that the tab holes (mortises) should run. (I have found that although
93 my printer could print a single tab accurately, spanning the entire length of
94 `cubby_depth` gave me the most accurate test.
95
96: `male_tabs` — as `female_tabs` above, except with male tabs (tenons)
97
98: `view_fit` — used as a debugging aid during development -- displays two sets
99 of tops and bottoms posiitioned to inspect tab fit.
100
101: `both` — a `bottom` and a `side` laid next each other. (These may look like
102 two seperate models, but is only one model, and obnixious to work with in a
103 slicer. Generating them seperately will allow you to manipulate them
104 individually).
105
106### Cubby Dimensions ###
107
108`cubby_width`
109: How wide the cubby should be, used as one dimension of the `bottom` and `male_tabs` `part`.
110
111`cubby_depth`
112: How deep the cubby should be, used as one dimension of the `side` and `female_tabs` `part`.
113
114`cubby_height`
115: How deep the cubby should be, used as one dimension of the `side`.
116
117`thickness`
118: How thick the `bottom`, `side`, or test fit pieces (`male_tabs`,
119 `female_tabs`) should be. When either part is eventually laid flat on the
120 print bed, this effectively becomes the `z` axis height. (The `tab_depth` is
121 dictated by this `thickness` dimension.)
122
123`strut_thickness`
124: The thickness of the strut members in the sparse structures. Applies to both
125 `bottom` and `side`.
126
127`max_bridge`
128: Maximum bridging distance between cross-braces of sparse struts. Applies to
129 `bottom`, and `side`.
130
131### Tab/Dovetail Dimensions ###
132
133`tab_width`
134: The width of each tab.
135
136`tab_padding`
137: The distance of the first tab from the edge, as well as between each tab.
138
139`tab_tolerance`
140: How much bigger the hole (or mortise) should be than the tab (tenon)
141
142![[Dovetail Test Fit](pictures/dovetail_test_fit.jpg-full "Dovetail Test Fit (full resolution)")](pictures/dovetail_test_fit-thumbnail.jpg)
143
144## Source Repository ##
145
146 The source repository is a Git repository that is hosted both on a read-only
147 HTTPS URL and on a read-write SSH url.
148
149 You can push to the read-write URL simply without creating any user account.
150 You only need to generate a SSH public key on your own system.
151
152### Read-Only Clone ###
153
154 The read-only clone command is:
155
156 git clone --recurse-submodules https://git.cryptonomic.net/cubbies.git
157
158### Read-Write Clone ###
159
160 To clone from the read-write URL, you first need to have your own ssh identity.
161 Then you can run `git clone`.
162
163 # Generate an SSH key if needed
164 command -v ssh-keygen || { echo Please Install OpenSSH; exit; }
165 [ -d ~/.ssh ] || mkdir ~/.ssh
166 [ -e ~/.ssh/id_ed25519.pub ] || ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N
167
168 # Add the public key for cryptonomic.net
169 echo cryptonomic.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPK7K8KsygvXtjw0yH4h43bwBGKq9oWBdCa1eY5rzT5D >> ~/.ssh/known_hosts
170
171 # Perform the clone
172 git clone --recurse-submodules ssh://d@cryptonomic.net:public_git/cubbies.git
173
174 You can push your changes back simply:
175
176 git add .
177 git commit -a -m 'commit message'
178 git push
179
180## Cubbies on the Web ##
181
182 * thingiverse
183 * thangs
184 * cults3d
185
186## Dependencies/Credits ##
187
188 * [OpenSCAD](https://openscad.org "OpenSCAD")
189 * [Belfry OpenSCAD Library](https://github.com/revarbat/BOSL "Belfry OpenSCAD Library")
190
191## Contributions ##
192
193![Megachurch Pastor](pictures/kenneth-copeland.jpg) ![Donation Basket](pictures/basket.jpg)
194
195
196- PayPal: <https://paypal.me/svasilogianis>
197- Venmo: <https://venmo.com/u/Steven-Vasilogianis>
198- CashApp: <https://cash.app/$svasi>
199
200## Shell Scripts ##
201
202### cubbies.sh ###
203
204```
205$ ./cubbies.sh -h
206./cubbies.sh: generate sets of cubbies. You will need print the side piece twice for your
207first bottom piece, then a single side piece for each additional bottom piece.
208
209Usage:
210./cubbies.sh cubby-depth cubby-height cubby-width1 [cubby-width2 ... cubby-widthN]
211
212Examples:
213
214 ./cubbies.sh 150 90 20
215
216 Generates two total pieces: a side piece (150mm depth, 90mm height) and a
217 bottom piece (150mm depth and 20mm width). You will need to print the side
218 piece twice and bottom piece once.
219
220 ./cubbies.sh 180 120 20 30 35
221
222 Generates four total pieces, which can be assembled to form a row of
223 cubbies: one side piece (180mm depth, 120mm height) and three bottom pieces,
224 with widths of 20mm, 30mm, and 35mm (and each sharing the same depth of
225 180mm). The side piece will need to be printed 4 times, and each bottom
226 piece printed once.
227
228 thickness=3 strut_thickness=4 ./cubbies.sh 200 140 20
229
230 You can override any of the other variables from your scad file by passing
231 them into ./cubbies.sh in this manner.
232```
233
234### shopenscad.sh ###
235
236```
237$ ./shopenscad.sh -h
238./shopenscad.sh: parse and execute OpenSCAD files, allowing default variables from input scad
239 to be overridden with values supplied from the shell. (The parsing of scad
240 files is done from the shell mostly with sed, and is very primitive)
241
242Usage: ./shopenscad.sh [-h] [-n] [-p] [-i] [-o OUTPUT-FILENAME] INPUT.scad
243
244 -h, --help display this help
245 -p, --print-vars print variables parsed from INPUT.scad
246 -i, --interactive show output command and query for execution
247 -n, --no-act show output command, do not execute
248 -s, --shell-skel output a skeleton shell script for generating models
249 -o, --output-filename Specify an output filename. The following variables are
250 available to you:
251
252 $VALUES - all values from INPUT.scad. This is the
253 default (-o '${VALUES}.stl'):
254 cube-15-10-5.stl
255
256 $ALL - all variable names and values from INPUT.scad
257 (-o '${ALL}.stl'):
258 shape=cube,width=15,height=10,depth=5.stl
259
260 Additionally, all variables parsed from INPUT.scad
261 are available in the associatve array , e.g.:
262 -o '${SCAD[part]}.stl'
263
264Usage examples:
265
266 1) Run openscad with default values from input scad file:
267
268 $ ./shopenscad.sh input.scad
269
270 2) You can override variables in the input file with variables passed in
271 through the shell; this will override "part" and "cubby_width"
272 paramaters from input scad file. (Note that if the part is a string,
273 you need to include quotes.):
274
275 $ cubby_width=200 part='"bottom"' ./shopenscad.sh input.scad
276
277
278 3) Generate multiple models:
279
280 $ for w in 250 300 350 400; do
281 cubby_width="" part="bottom" ./shopenscad.sh cubbies.scad
282 done
283```
284
285### test_fits.sh ###
286
287```
288$ ./test_fits.sh -h
289Usage:
290./test_fits.sh
291./test_fits.sh [depth] [tolerance1 tolerance2 .. toleranceN]
292
293By default five test fit pieces are generated with a length of 120mm at the
294tolerances 0.1mm, 0.2mm, 0.3mm, 0.4mm, and 0.5mm.
295
296Over ride the defaults by supplying paramaters; the first parameter the depth and the rest are
297taken as tolerances.
298```
299
300## GPLv3 License ##
301
302Copyright (C) Steven Vasilogianis
303
304This program is free software: you can redistribute it and/or modify it under
305the terms of the GNU General Public License as published by the Free Software
306Foundation, either version 3 of the License, or (at your option) any later
307version.
308
309[^1]: OpenSCAD already allows you to generate models with varying paramaters
310through, e.g., `OpenSCAD -D "param1=100" -D "param2=10" scadfile.scad -o
311output.stl`. Now you're going to want to change the output.stl filename to avoid
312overwriting a previously generated model; generally, the information going into
313your variables is useful to have in the output filename.
diff --git a/cubbies.scad b/cubbies.scad
new file mode 100644
index 0000000..9497c5e
--- /dev/null
+++ b/cubbies.scad
@@ -0,0 +1,209 @@
1include <BOSL2/std.scad>; // https://github.com/revarbat/BOSL2
2include <BOSL2/walls.scad>;
3include <BOSL2/fnliterals.scad>;
4include <BOSL2/joiners.scad>;
5
6$fn=20;
7
8part="both"; // [bottom::Bottom Only,side:Side Only,female_tabs:Holes only from side,male_tabs:Tabs only from bottom,view_fit:Debugging view to confirm tab fit,both:Bottom + Side]
9
10/* [Cubby dimensions] */
11cubby_width=40;
12cubby_depth=120;
13cubby_height=90;
14
15// thickness of bottom and side
16thickness=5;
17
18// thickness of struts (used in both bottom and side)
19strut_thickness=5;
20
21// If set (to non zero), this is used in the max_bridge paramater for the
22// sparse_struct BOSL 2 function (which generates the wireframe rectangles). By
23// default, it is calculated as max_bridge=(cubby_height + cubby_width)/5.
24max_bridge=0;
25
26/* [Tab Dimensions] */
27// width of each tab
28tab_width=10;
29// material between tabs
30tab_padding=5;
31// this value will be added to the mortises for additional tolerance
32tab_tolerance=0.5;
33
34/* [Screw Tabs] */
35screw_tabs=true;
36
37/* [Hidden] */
38tab_depth=thickness;
39tab_height=thickness;
40default_max_bridge=(cubby_height + cubby_width) / 5;
41
42if ( part == "both" ) {
43 both();
44} else if ( part =="bottom") {
45 cubby_bottom(cubby_width, cubby_depth);
46} else if ( part == "side" ) {
47 cubby_side(cubby_depth, cubby_height, screw_tabs);
48} else if ( part == "view_fit") {
49 view_tab_fit(cubby_width, cubby_depth, cubby_height);
50} else if ( part == "male_tabs" ) {
51 male_tabs(cubby_width, cubby_depth);
52} else if ( part == "female_tabs" ) {
53 female_tabs(cubby_depth, cubby_height);
54}
55
56function assert_cubby_width() =
57 let (min_width = strut_thickness + 1) // I'm not sure why I need the +1
58 assert(cubby_width >= min_width,
59 str("Cubby width must be atleast ", min_width, "mm"));
60
61function assert_cubby_depth() =
62 let (min_depth = tab_width * 2)
63 assert(cubby_depth >= min_depth,
64 str("Cubby width must be atleast ", min_depth, "mm"));
65
66function assert_cubby_height() =
67 let (min_height = cubby_side_bracket_height())
68 assert(cubby_height >= min_height,
69 str("Cubby width must be atleast ", min_height, "mm"));
70
71function double (x) = x * 2;
72function half (x) = x / 2;
73
74module both () {
75 gap=5;
76 cubby_bottom(cubby_width, cubby_depth);
77 left(((cubby_width + cubby_height) / 2) + (tab_height * 2) + gap)
78 cubby_side(cubby_depth, cubby_height, screw_tabs);
79}
80
81module cubby_bottom (width, depth) {
82 let (_=assert_cubby_width());
83 let (_=assert_cubby_depth());
84
85 rot(90) yrot(90) color("blue") bottom_wall() yrot(90) down(tab_height / 2) {
86 move_dist=(width / 2) + (tab_depth / 2);
87 fwd(move_dist)
88 alternating_tabs(false, "male", depth, tab_width,
89 tab_depth, tab_height, tab_padding, tab_tolerance);
90 back(move_dist)
91 alternating_tabs(true, "male", depth, tab_width,
92 tab_depth, tab_height, tab_padding, tab_tolerance);
93 }
94 children();
95 module bottom_wall () {
96 strut_wall(width, depth) children();
97 }
98}
99
100// this calculation needs to be referenced by the view_tab_fit function
101function cubby_side_bracket_height() = double(tab_height) + tab_tolerance;
102module cubby_side (depth, height, screw_tabs=true) {
103 let (_=assert_cubby_depth());
104 let (_=assert_cubby_height());
105
106 screw_tab_width=15;
107 screw_tab_height=20;
108 screw_tab_thickness=thickness;
109
110 yrot(-90) color("red") side_wall() {
111 if ( screw_tabs ) {
112 position(TOP+FRONT+LEFT) screw_tab();
113 up(screw_tab_height) position(BOTTOM+FRONT+LEFT) screw_tab();
114 }
115 attach(BOTTOM, TOP) zrot(90) tab_bracket();
116 attach(TOP, BOTTOM) zrot(90) tab_bracket();
117 }
118 children();
119
120 module side_wall () {
121 strut_wall(depth, height - cubby_side_bracket_height() * 2) children();
122 }
123
124 module tab_bracket () {
125 difference() {
126 cuboid([depth,thickness,cubby_side_bracket_height()]);
127 alternating_tabs(true, "female", depth, tab_width, tab_depth,
128 tab_height, tab_padding, tab_tolerance);
129 alternating_tabs(false, "female", depth, tab_width, tab_depth,
130 tab_height, tab_padding, tab_tolerance);
131 }
132 children();
133 }
134
135 module screw_tab () {
136 difference() {
137 cuboid([screw_tab_width, screw_tab_thickness,screw_tab_height],
138 anchor=LEFT+TOP);
139 right(screw_tab_width * (2 / 3)) zrot(90) yrot(90) {
140 right(screw_tab_height * (1 / 3)) cyl(l=15, r=2, anchor=RIGHT);
141 right(screw_tab_height * (2 / 3)) cyl(l=15, r=2, anchor=LEFT);
142 }
143 }
144 children();
145 }
146}
147
148module strut_wall(w, h) {
149 bridge=max_bridge ? max_bridge : default_max_bridge;
150 sparse_strut(
151 l=w,
152 h=h,
153 thick=thickness,
154 maxang=45,
155 strut=5,
156 max_bridge=bridge
157 ) children();
158}
159
160module male_tabs (w, d) {
161 keep=(w / 2) - thickness;
162 left_half(x=-keep) cubby_bottom(cubby_width, cubby_depth);
163}
164
165module female_tabs (d, h) {
166 // text inscribed (when printing tolerances)
167 text_inscription_depth=0.6;
168 text_size=thickness * 0.9;
169 text=str(tab_tolerance);
170 text_pos=[-h/2 + (thickness * 0.95),
171 -d / 2 + (thickness / 2),
172 (thickness / 2)];
173
174 xrot(180) left_half(x=(h / -2 + (thickness * 3)))
175 cubby_side(d, h, screw_tabs=false);
176 translate(text_pos) zrot(90) linear_extrude(text_inscription_depth)
177 color("green") text(size=text_size, text, font="Bitstream Vera Sans:style=Bold");
178}
179
180module view_tab_fit (w, d, h) {
181 // position for testing tab fit
182 module position_fit_test (left=true) {
183 cubby_bottom(w, d);
184 dist=(w / 2) + (thickness / -2) + tab_depth - 2;
185 down=half(h) - half(thickness) -
186 tab_height - half(tab_tolerance);
187 yflip() yrot(90) down(dist * (left ? 1 : -1)) left(down)
188 cubby_side(d, h, screw_tabs);
189 }
190
191 position_fit_test(left=true);
192 yrot(180) up(h) position_fit_test(left=false);
193}
194
195module alternating_tabs (first, gender, length, tab_width, tab_depth,
196 tab_height, tab_padding, tolerance) {
197 dist=length - (tab_padding * 2);
198 total_tabs=dist / (tab_width + tab_padding + tolerance);
199 half_tabs=total_tabs / 2;
200 tab_qty = total_tabs % 2 == 0 ? half_tabs : first ?
201 ceil(half_tabs) : floor(half_tabs);
202 start = first ? tab_padding : (tab_padding * 2) + tab_width;
203 spacing = (tab_width + tab_padding) * 2;
204 xcopies(spacing, tab_qty, dist, sp=((dist / -2) + start))
205 dovetail(gender, angle=0, slide=add_tol(tab_depth),
206 width=add_tol(tab_width), height=add_tol(tab_height));
207
208 function add_tol (x) = gender == "male" ? x : x + tolerance;
209}
diff --git a/cubbies.sh b/cubbies.sh
new file mode 100755
index 0000000..43a2416
--- /dev/null
+++ b/cubbies.sh
@@ -0,0 +1,65 @@
1#!/bin/bash
2# this script started off generated using "shopenscad.sh -s cubbies.scad"
3
4usage() {
5 cat <<EOF
6$0: generate sets of cubbies. You will need print the side piece twice for your
7first bottom piece, then a single side piece for each additional bottom piece.
8
9Usage:
10$0 cubby-depth cubby-height cubby-width1 [cubby-width2 ... cubby-widthN]
11
12Examples:
13
14 $0 150 90 20
15
16 Generates two total pieces: a side piece (150mm depth, 90mm height) and a
17 bottom piece (150mm depth and 20mm width). You will need to print the side
18 piece twice and bottom piece once.
19
20 $0 180 120 20 30 35
21
22 Generates four total pieces, which can be assembled to form a row of
23 cubbies: one side piece (180mm depth, 120mm height) and three bottom pieces,
24 with widths of 20mm, 30mm, and 35mm (and each sharing the same depth of
25 180mm). The side piece will need to be printed 4 times, and each bottom
26 piece printed once.
27
28 thickness=3 strut_thickness=4 $0 200 140 20
29
30 You can override any of the other variables from your scad file by passing
31 them into $0 in this manner.
32EOF
33}
34
35[ "-h" == "$1" ] && usage && exit;
36if [ "$#" -lt 3 ]; then
37 echo "$0: Needs atleast three paramaters. See usage:"; usage; exit 1;
38fi;
39
40shopenscad_cmd="./shopenscad.sh cubbies.scad "
41
42export $(echo $($shopenscad_cmd -p))
43# # $ ./shopenscad.sh -p cubbies.scad
44# part='"both"'
45# cubby_width=40
46# cubby_depth=120
47# cubby_height=90
48# thickness=5
49# strut_thickness=5
50# max_bridge=0
51# tab_width=10
52# tab_padding=5
53# tab_tolerance=0.5
54# screw_tabs=true
55
56cubby_depth=$1; shift
57cubby_height=$1; shift
58
59# generate the single side piece
60part='"side"' ${shopenscad_cmd}
61
62# generate each bottom piece
63for i in "$@"; do
64 part='"bottom"' cubby_width="$i" ${shopenscad_cmd}
65done;
diff --git a/description b/description
new file mode 100644
index 0000000..b1639de
--- /dev/null
+++ b/description
@@ -0,0 +1 @@
3d Printable Parametric Cubbies
diff --git a/shopenscad.sh b/shopenscad.sh
new file mode 100755
index 0000000..3c71b1f
--- /dev/null
+++ b/shopenscad.sh
@@ -0,0 +1,238 @@
1#!/bin/bash
2
3#set -x
4
5OPENSCAD=${OPENSCAD:-"openscad"}
6RUN=y
7INTERACTIVE=
8PRINT_VARS=
9USER_OUTPUT_FILENAME=
10SCAD_FILE=
11SHELL_SKEL=
12
13help()
14{
15 cat <<EOF
16$0: parse and execute OpenSCAD files, allowing default variables from input scad
17 to be overridden with values supplied from the shell. (The parsing of scad
18 files is done from the shell mostly with sed, and is very primitive)
19
20Usage: $0 [-h] [-n] [-p] [-i] [-o OUTPUT-FILENAME] INPUT.scad
21
22 -h, --help display this help
23 -p, --print-vars print variables parsed from INPUT.scad
24 -i, --interactive show output command and query for execution
25 -n, --no-act show output command, do not execute
26 -s, --shell-skel output a skeleton shell script for generating models
27 -o, --output-filename Specify an output filename. The following variables are
28 available to you:
29
30 \$VALUES - all values from INPUT.scad. This is the
31 default (-o '\${VALUES}.stl'):
32 cube-15-10-5.stl
33
34 \$ALL - all variable names and values from INPUT.scad
35 (-o '\${ALL}.stl'):
36 shape=cube,width=15,height=10,depth=5.stl
37
38 Additionally, all variables parsed from INPUT.scad
39 are available in the associatve array $SCAD, e.g.:
40 -o '\${SCAD[part]}.stl'
41
42Usage examples:
43
44 1) Run $OPENSCAD with default values from input scad file:
45
46 $ $0 input.scad
47
48 2) You can override variables in the input file with variables passed in
49 through the shell; this will override "part" and "cubby_width"
50 paramaters from input scad file. (Note that if the part is a string,
51 you need to include quotes.):
52
53 $ cubby_width=200 part='"bottom"' $0 input.scad
54
55
56 3) Generate multiple models:
57
58 $ for w in 250 300 350 400; do
59 cubby_width="$w" part="bottom" $0 cubbies.scad
60 done
61EOF
62}
63
64parse_options()
65{
66 OPTS=$(getopt \
67 --options 'hpinso:' \
68 --longoptions 'help,print-vars,interactive,no-act,shell-skel,output-filename:' \
69 -- "$@")
70 eval set -- "$OPTS"
71 unset OPTS
72
73 if [ $# = 0 ]; then
74 help
75 exit
76 fi
77
78 while true; do
79 case "$1" in
80 -h | --help ) help; exit;;
81 -p | --print-vars ) PRINT_VARS=y;;
82 -i | --interactive ) INTERACTIVE=y;;
83 -n | --no-act ) RUN=;;
84 -s | --shell-skel ) SHELL_SKEL=y;;
85 -o | --output-filename ) shift; USER_OUTPUT_FILENAME=$1;;
86 -- ) shift; break;;
87 esac
88 shift
89 done
90
91 SCAD_FILE="$*";
92 [ -f "$SCAD_FILE" ] || die "$0: Needs an input scad file"
93}
94
95die() { printf 'Error: %s\n' "$*" >&2; exit 1; }
96warn() { printf 'Warning: %s\n' "$*" >&2; }
97
98strip_multiline_comments () {
99 # https://stackoverflow.com/questions/13061785/remove-multi-line-comments
100 # https://stackoverflow.com/users/751863/steve
101 sed -r ':a; s%(.*)/\*.*\*/%\1%; ta; /\/\*/ !b; N; ba'
102}
103
104strip_trailing_semicolon () {
105 sed -r 's/;$//'
106}
107
108strip_leading_spaces () {
109 sed -r 's/^ +//'
110}
111
112strip_trailing_spaces () {
113 sed -r 's/ +$//'
114}
115
116strip_nonassignments () {
117 grep -e '^[A-Za-z0-9_]\+\s*='
118}
119
120chomp () {
121 strip_leading_spaces |strip_trailing_spaces
122}
123
124parse_variable () {
125 #sed -r 's/^([a-zA-Z0-9_]+).*/\1/'
126 sed -r 's/^([^=]+)=.*/\1/'
127}
128
129parse_value () {
130 #sed -r 's/^.*?=\s*([^;]+);.*$/\1/'
131 #sed -r 's/^[^=]+\s*=\s*([^;]+);.*$/\1/'
132 sed -r 's/.*=\s*([^;]+?).*/\1/'
133}
134
135val_to_filename () {
136 echo "$1" |sed -r 's/"//g' |sed -r 's/ /_/g'
137}
138
139strip_after_hidden () {
140 sed -n '/\/\* \[Hidden\] \*\//q;p' "$1"
141}
142
143strip_trailing () {
144 trailing="$1"
145 input="$2"
146 echo ${input%${trailing}}
147}
148
149main()
150{
151 parse_options "$@"
152
153 output_params=""
154 default_output_filename=""
155 ALL=""
156 VALUES=""
157 val_sep="-"
158 var_sep=","
159 declare -A SCAD
160 declare -a scad_var_order
161
162 while IFS= read -r line; do
163 [ "$line" ] || continue;
164 clean="$(echo -n "$line" |chomp)"
165 var=$(echo -n "$clean" |parse_variable |chomp)
166
167 # use value provided on command line preferentially to any values in the .scad file
168 val=""
169 if [[ -n "${!var}" ]]; then
170 val=${!var}
171 else
172 val=$(echo -n "$clean" |parse_value |chomp)
173 fi
174
175 if [ "$var" ] && [ "$val" ]; then
176 scad_var_order+=($var);
177 SCAD[$var]="$val"
178 output_params+="-D '$var=$val' "
179 VALUES+="$(val_to_filename "$val")${val_sep}"
180 ALL+="${var}=$(val_to_filename "$val")${var_sep}"
181 fi;
182 done < <(strip_after_hidden $SCAD_FILE | \
183 strip_multiline_comments |strip_nonassignments |strip_trailing_semicolon)
184
185 if [ "$PRINT_VARS" ]; then
186 for k in "${scad_var_order[@]}"; do
187 # Make sure quotes surround openscad strings
188 case "${SCAD[$k]:0:1}" in
189 \" ) line="${k}='${SCAD[$k]}'";;
190 \' ) line=${k}="\"${SCAD[$k]}\"";;
191 * ) line="${k}=${SCAD[$k]}";;
192 esac
193 echo $line
194 done
195 exit
196 fi
197
198 if [ "$SHELL_SKEL" ]; then
199 all_vars=$($0 $SCAD_FILE -p |sed -e 's/^/# /')
200 cat <<EOF
201#!/bin/bash
202shopenscad_cmd="$0 $SCAD_FILE "
203export \$(echo \$(\$shopenscad_cmd -p))
204${all_vars}
205\$shopenscad_cmd
206EOF
207 exit;
208 fi;
209
210 ALL=$(strip_trailing "$var_sep" "$ALL")
211 VALUES=$(strip_trailing "$val_sep" "$VALUES")
212
213 default_output_filename="${VALUES}.stl"
214 output_filename="$default_output_filename"
215 if [ "$USER_OUTPUT_FILENAME" ]; then
216 output_filename=$(echo $(eval "echo $USER_OUTPUT_FILENAME"))
217 fi
218
219 openscad_str="$OPENSCAD '$SCAD_FILE' "$output_params" -o '$output_filename'"
220 echo "${openscad_str}"
221
222 [ ! "$RUN" ] && [ ! "$INTERACTIVE" ] && exit
223
224 if [ "$INTERACTIVE" ]; then
225 eval_prompt="Evaulate openscad command? (type y for yes, anything else to exit): "
226 read -p "$eval_prompt" -n1 yes_eval_read
227 echo
228 case "$yes_eval_read" in
229 [Yy]) RUN=y ;; # still true
230 *) RUN=;;
231 esac
232 fi
233
234 [ "$RUN" ] && eval "$(echo "$openscad_str")"
235}
236
237main "$@"
238#parse_options "$@"
diff --git a/svasilogianis.github.io b/svasilogianis.github.io
new file mode 160000
Subproject eb3190880ecf556e030131a8a2be879662ea4c6
diff --git a/test_fits.sh b/test_fits.sh
new file mode 100755
index 0000000..003cb3d
--- /dev/null
+++ b/test_fits.sh
@@ -0,0 +1,28 @@
1#!/bin/bash
2usage() {
3 cat <<EOF
4Usage:
5$0
6$0 [depth] [tolerance1 tolerance2 .. toleranceN]
7
8By default five test fit pieces are generated with a length of 120mm at the
9tolerances 0.1mm, 0.2mm, 0.3mm, 0.4mm, and 0.5mm.
10
11Over ride the defaults by supplying paramaters; the first parameter the depth and the rest are
12taken as tolerances.
13EOF
14}
15
16[ "-h" == "$1" ] || [ "--help" == "$1" ]&& usage && exit;
17
18depth=${1:-120}; shift
19tolerances=${*:-0.1 0.2 0.3 0.4 0.5};
20
21male='"male_tabs"'
22female='"female_tabs"'
23shopen="./shopenscad.sh cubbies.scad"
24
25part="$male" $shopen
26for t in ${tolerances[@]}; do
27 tab_tolerance=$t part="$female" $shopen
28done;