Zdecydowana większość projektów przygotowywana do druku 3D jest tworzona raz- pod konkretne zastosowanie. Nie posiadając oryginalnego pliku oraz programu w którym projekt został stworzony, nie uda nam się w łatwy sposób przerobić obiektu w przypadku zmiany założeń początkowych. Gdy mamy więc projekt który będzie się różnił dla praktycznie każdego użytkownika, to najprościej jest to rozwiązać poprzez projektowanie parametryczne.
1. Pomysł
Projektowanie parametryczne, czyli pokrótce uzależnienie (powiązanie) wartości z których zbudowanie jest projekt ze zmiennymi (parametrami), pozwalające na zmianę jednej lub wielu z wartości i spowodowanie, że projekt sam się do tych zmian zastosuje, niepowodując dziur czy innych artefaktów. Ten sposób projektowanie jest z powodzeniem wykorzystywany w programach graficznych (m.in SolidWorks czy AutoCAD) i gdy mamy dostęp do oryginalnego pliku możemy go łatwo i szybko edytować.
Problem pojawia się, gdy chcemy udostępnić swój projekt szerszemu gronie odbiorców – różne osoby używają różnych programów graficznych, więc jesteśmy ograniczeni tutaj nie tylko dostępnością do oprogramowania, ale i także umiejętnością jego obsługi (np. DesignSpark Mechanical jest darmowy, ale nie wszyscy potrafią go obsłużyć, w tym ja). Z takim problem spotkałem się planując projekt osłony przeciwsłonecznej do mojego tabletu, którego używam jako nawigacji samochodowej. Była bardzo nikła szansa, że ktoś jeszcze używa tego modelu do w tym celu razem z tym samym uchwytem. Ilość możliwych konfiguracji ze względu na różne modele telefonów/tabletów/nawigacji jest naprawdę ogromna.
Przypomniałem sobie wtedy, że na Thingiverse są dostępne projekty, które można z poziomu strony modyfikować i generować STLki potrzebne do wydruku. Tylko jak przygotować taki projekt? Właśnie za pomocą projektu opartego na parametrach. Niestety, nie możemy użyć do tego jakiegoś kombajnu do grafiki 3d, podejście musi być bardziej hardcorowe- ale tylko na pierwszy rzut oka. Do stworzenia projektu musimy użyć darmowego programu OpenSCAD. Jest to program, gdzie obiekty tworzymy pisząc kod, a nie klikając myszką, jest mu raczej bliżej do programowania niż do typowej grafiki 3D. Jako ciekawostkę dodam, że sam program jest niewielki (zaledwie 30MB), a mój projekt zajmował zaledwie 9kB! Pogram po dopaleniu niektórych będzie straszył pustką, innym może się podobać ten ascetyzm.
Programu nawet nie trzeba nawet instalować – gwarantuję, że odpali nawet na starych komputerach :) To nie będzie poradnik jak projektować w OpenSCAD, bo świetny i prosty tutorial możemy znaleźć na youtube: https://www.youtube.com/watch?v=eq5ObNeiAUw Trzy filmy i dwadzieścia minut później wiemy już na tyle dużo, żeby stworzyć coś własnego. Sam program ściągniemy ze strony http://www.openscad.org/ Przydatna będzie też ściąga ze strony programu http://www.openscad.org/cheatsheet/index.html opisująca funkcje i ich wykorzystanie.
Tak jak wspomniałem wyżej, nie będę opisywał tutaj jak powstają konkretne obiekty w programie, ale pokaże na co zwrócić uwagę przy tworzeniu projektu dla jego wykorzystania na Thingiverse, czy po prostu do udostępnienia go innym, tak by nie musieli zagłębiać się w kod programu.
2. Projektowanie
Co do założeń samego projektu, to starałem się stworzyć projekt jak najbardziej uniwersalny, niezależny od modelu urządzenia które używamy do nawigacji oraz sposobu jego przymocowania. Pooglądałem urządzenia dostępne w moim domu i wyciągnąłem wnioski dotyczące potrzeb skalowania poszczególnych elementów osłony.
Ja na samym początku stworzyłem wstępny projekt, praktycznie bez zmiennych, głównie w celu sprawdzenia czy w ogóle dam radę coś zaprojektować. Starałem się tylko dzielić kod na odpowiednio dużo modułów, co znacząco wpływa na jego czytelność i ułatwiło mi późniejsze wprowadzanie zmian. Tutaj ważna uwaga na sam początek – polecam pracować na dodatnich osiach układu współrzędnych. W moim projekcie wartości na osi X mogą przyjmować wartości ujemne – jest to problem przy wrzuceniu projektu na Thingiverse, a to dlatego, że w ich edytorze można podawać tylko wartości dodatnie (i zero). Nie jest to może duży problem, bo później możemy dopisać parę linijek kodu (ja tak zrobiłem) i wszystko będzie działać, ale to zawsze zaciemnia kod.
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
module top(){ translate([-100,0,0]){ cube([200, 12, 2]); } translate([-100,0,0]){ cube([200, 2, 12]); } translate([-100,10,0]){ cube([200, 2, 12]); } } module top_plate(){ translate([-100,12,0]){ cube([200, 38, 2]); } } module left_side_grip(){ translate([-100,0,0]){ cube([2, 12, 110]); } translate([-100,0,0]){ cube([12, 2, 110]); } translate([-100,10,0]){ cube([12, 2, 110]); } } module left_side_plate(){ translate([-100,0,0]){ cube([2, 50, 72]); } // color([0.1,1.0,0.2]){ intersection(){ translate([-100,12,72]){ cube([2, 38, 38]); } translate([-100,12,72]){ rotate([0,90,0]){ cylinder(h=2,r=38); } } } // } } module right_side_all(){ mirror([1,0,0]){ left_side_grip(); left_side_plate(); } } module top_hole(){ color([0.1,0.8,0.2]){ translate([0,1,-1]){ minkowski() //wszystkie wartości się dodają { cube([15,12,7]); cylinder(r=3,h=7); } } } } module top_hole_2(){ color([0.1,0.8,0.2]){ translate([-40,1,-1]){ minkowski() //wszystkie wartości się dodają { cube([15,12,7]); cylinder(r=3,h=7); } } } } module right_hole(){ color([0.1,0.8,0.2]){ translate([93,0,80]){ rotate([0,90,0]){ minkowski() //wszystkie wartości się dodają { cube([15,12,8]); cylinder(r=3,h=5); } } } } } module left_hole(){ color([0.1,0.8,0.2]){ translate([-101,0,70]){ rotate([0,90,0]){ minkowski() //wszystkie wartości się dodają { cube([20,9,10]); cylinder(r=3,h=5); } } } } } module difference_top(){ difference(){ difference(){ top(); top_hole(); } top_hole_2(); } difference(){ difference(){ top_plate(); top_hole(); } top_hole_2(); } } module difference_left(){ difference(){ left_side_grip(); left_hole(); } difference(){ left_side_plate(); left_hole(); } } module difference_right(){ difference(){ right_side_all(); right_hole(); } } difference_top(); difference_right(); difference_left(); |
Niestety, edytor kodu na Majsterkowie nie posiada wyboru składni OpenSCAD, więc analizę kodu polecam zdecydowanie przeprowadzać w samym programie. Teraz aby to wszystko zadziałało na zasadzie wprowadzania wartości do zmiennych, musimy takie zmienne stworzyć. Tutaj trzeba się zastanowić, na jak wiele chcemy pozwolić w przyszłej edycji- trzeba tutaj pamiętać, że im więcej udostępnimy do edycji, tym łatwiej będzie można projekt “zepsuć”, a tym samym będziemy musieli stworzyć wiele instrukcji warunkowych. Oczywiście zmienne najlepiej wprowadzać już na samym początku pisania kodu, choć zrobienie tego trochę później w niczym nie przeszkadza. Sam projekt też cały czas ewoluował, więc różni się lekko od tego co pokazałem wyżej.
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
$fn = 150; //rendering- number of detail //Variables l_dev = 210;//lenght of device t_dev = 8;// thickness of device, w_dev = 124; // width of device, t_sh = 2; // thickness of shield l_sh = 80;//lenght of shield t_grip = 2; // thickness of grip hf_grip = 11; //height of front part of the grip hfs_grip = 7; //height of front left&right side of the grip hb_grip = 15;//height of back part of the grip lh1_top = 30; //lenght of first top hole wh1_top = 14; // width of first top hole d_hole= hb_grip>hf_grip ? hb_grip : hb_grip; //deep of the holes pos_h1_top = 10; // position of first top hole lh2_top = 30; //lenght of second top hole wh2_top = 20; // width of second top hole pos_h2_top = -60; // position of second top hole lh1_right = 30; //lenght of first right hole wh1_right = 10; //width of first right hole pos_h1_right = 60; // position of first right hole lh2_right = 30; //lenght of second right hole wh2_right = 20; //width of second right hole pos_h2_right = 130; // position of second right hole lh1_left = 30; //lenght of first left hole wh1_left = 10; //width of first left hole pos_h1_left = 60; // position of left right hole lh2_left = 30; //lenght of second left hole wh2_left = 20; //width of second left hole pos_h2_left = 130; // position of second left hole module top(){ //bottom grip plate translate([-l_dev/2,0,0]){ cube([l_dev, t_dev + t_grip, t_sh]); } //back grip plate translate([-l_dev/2,0,0]){ cube([l_dev, t_grip, hb_grip]); } //front grip plate translate([-l_dev/2,t_dev + t_grip,0]){ cube([l_dev, t_grip, hf_grip]); } } module top_plate(){ translate([-l_dev/2,t_dev + 2 * t_grip,0]){ cube([l_dev, l_sh, t_sh]); } } module left_side_grip(){ //side grip plate translate([-l_dev/2,0,0]){ cube([t_sh, t_dev + t_grip, w_dev]); } //back grip plate translate([-l_dev/2,0,0]){ cube([hb_grip, t_grip, w_dev]); } //front grip plate translate([-l_dev/2,t_dev + t_grip,0]){ cube([hfs_grip, t_grip, w_dev]); } } module left_side_plate(){ translate([-l_dev/2,t_dev + 2 * t_grip,0]){ cube([t_sh, l_sh, w_dev - l_sh]); } // color([0.1,1.0,0.2]){ intersection(){ translate([-l_dev/2,t_dev + 2 * t_grip,w_dev - l_sh]){ cube([t_sh, l_sh, l_sh]); } translate([-l_dev/2,t_dev + 2 * t_grip,w_dev - l_sh]){ rotate([0,90,0]){ cylinder(h = t_sh,r = l_sh); } } } // } } module right_side_all(){ mirror([1,0,0]){ left_side_grip(); left_side_plate(); } } module top_hole(){ color([0.1,0.8,0.2]){ translate([pos_h1_top+3, 1, -1]){ minkowski() { cube([lh1_top-6,wh1_top-3, d_hole]); cylinder(r=3,h=d_hole); } } } } module top_hole_2(){ color([0.1,0.8,0.2]){ translate([pos_h2_top+3,1,-1]){ minkowski() //wszystkie wartości się dodają { cube([lh2_top - 6, wh2_top - 3, d_hole]); cylinder(r=3,h=d_hole); } } } } module right_hole(){ // color([0.1,0.8,0.2]){ translate([l_dev/2-d_hole-0.001,0,pos_h1_right]){ //0.001 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh1_right,wh1_right,d_hole]); cylinder(r=3,h=d_hole); } } } // } } module right_hole_2(){ // color([0.1,0.8,0.2]){ translate([l_dev/2-d_hole-0.001,0,pos_h2_right]){//0.001 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh2_right,wh2_right,d_hole]); cylinder(r=3,h=d_hole); } } } // } } module left_hole(){ // color([0.1,0.8,0.2]){ translate([-l_dev/2 - 0.01, 0, pos_h1_left]){ //0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh1_left,wh1_left,d_hole]); cylinder(r=3,h=d_hole); } } } // } } module left_hole_2(){ // color([0.1,0.8,0.2]){ translate([-l_dev/2 - 0.01, 0, pos_h2_left]){ //0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh2_left,wh2_left,d_hole]); cylinder(r=3,h=d_hole); } } } // } } module difference_top(){ difference(){ difference(){ top(); top_hole(); } top_hole_2(); } difference(){ difference(){ top_plate(); top_hole(); } top_hole_2(); } } module difference_left(){ difference(){ difference(){ left_side_grip(); left_hole(); } left_hole_2(); } difference(){ difference(){ left_side_plate(); left_hole(); } left_hole_2(); } } module difference_right(){ difference(){ difference(){ right_side_all(); right_hole(); } right_hole_2(); } } difference_top(); difference_right(); difference_left(); |
Tak przygotowany obiekt jest już łatwy w edycji bez wnikania w sam kod. Pora przyjrzeć się jak to dokładnie wygląda na Thingiverse- najlepiej wejść na tę stronę https://customizer.makerbot.com/docs i pobawić się kodem na końcu strony. Najważniejsze to zauważenie, że nazwa zmiennej będzie zostanie wyświetlona pogrubiona, komentarz nad zmienną będzie jej opisem, a w komentarz obok ustalamy zakres w jakim będzie można edytować obiekt. Co ważne, wszystko co znajdzie się w edytorze ustalamy w kodzie w OpenSCAD, różnica we wrzuceniu pliku .scad od zwykłej stlki polega na zafajkowaniu jednej opcji, nic więcej. Sam przerobiłem kod by lepiej wyglądał w edytorze Thingiverse i teraz prezentuje się następująco:
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
//$fn = 350; //rendering- number of detail // preview[view:north east, tilt:top diagonal] /* [Data_of_Your_device] */ //Variables for thingiverse customizer //(tablet, smartphone, GPS navigation device) lenght_of_your_device = 210; // [1:300] thickness_of_your_device = 9;// [1:0.1:30] width_of_your_device = 124; // [1:300] /* [Data for sun shield] */ thickness_of_shield = 2; // [0.5:0.1:4] //Values greater than width of device will not affect model lenght_of_shield = 75;//[1:300] //(exactly the walls of grip) thickness_of_grip = 2; // [0.5:0.1:4] height_of_front_part_of_the_grip = 5;// [1:40] height_of_front_left_and_right_side_of_the_grip = 9;//[1:40] height_of_back_part_of_the_grip = 12;//[1:50] /* [First top hole] */ // If You don't want this hole - type 0 lenght_of_first_top_hole = 47; //[0:300] width_of_first_top_hole = 25; // [0:300] position_of_first_top_hole = 77; // [0:300] /* [Second top hole] */ // If You don't want this hole - type 0 lenght_of_second_top_hole = 50; //[0:300] width_of_second_top_hole = 9; // [0:300] position_of_second_top_hole = 29; //[0:300] /* [First right hole] */ // If You don't want this hole - type 0 lenght_of_first_right_hole = 25; // [0:300] width_of_first_right_hole = 9; // [0:300] position_of_first_right_hole = 24; // [0:300] /* [Second right hole] */ // If You don't want this hole - type 0 lenght_of_second_right_hole = 40; //[0:300] width_of_second_right_hole = 12; //[0:300] position_of_second_right_hole = 43; //[0:300] /* [First left hole] */ // If You don't want this hole - type 0 lenght_of_first_left_hole = 25; //[0:300] width_of_first_left_hole = 9; //[0:300] position_of_left_right_hole = 32; // [0:300] /* [Second left hole] */ // If You don't want this hole - type 0 lenght_of_second_left_hole = 40; //[0:300] width_of_second_left_hole = 12; //[0:300] position_of_second_left_hole = 43; // [0:300] // ignore variable values l_dev = lenght_of_your_device; t_dev = thickness_of_your_device; w_dev = width_of_your_device; t_sh = thickness_of_shield; l_sh = lenght_of_shield>w_dev ? w_dev : lenght_of_shield; //blockade of length of shield t_grip = thickness_of_grip; hf_grip = height_of_front_part_of_the_grip; hfs_grip = height_of_front_left_and_right_side_of_the_grip; hb_grip = height_of_back_part_of_the_grip; d_hole1= hb_grip>hf_grip ? hb_grip : hf_grip; d_hole2= hfs_grip>hb_grip ? hfs_grip : hb_grip;//deep of the holes lh1_top = lenght_of_first_top_hole; wh1_top = width_of_first_top_hole; lh2_top = lenght_of_second_top_hole; wh2_top = width_of_second_top_hole; //solution for minus position of holes a = l_dev/2; //helper pos_h1_top = position_of_first_top_hole - a; pos_h2_top = position_of_second_top_hole - a; lh1_right = lenght_of_first_right_hole; wh1_right = width_of_first_right_hole; //solution for position of holes pos_h1_right = position_of_first_right_hole + lenght_of_first_right_hole; lh2_right = lenght_of_second_right_hole; wh2_right = width_of_second_right_hole; pos_h2_right = position_of_second_right_hole + lenght_of_second_right_hole; lh1_left = lenght_of_first_left_hole; wh1_left = width_of_first_left_hole; pos_h1_left = position_of_left_right_hole + lenght_of_first_left_hole; lh2_left = lenght_of_second_left_hole; wh2_left = width_of_second_left_hole; pos_h2_left = position_of_second_left_hole + lenght_of_second_left_hole; module top(){ //bottom grip plate translate([-l_dev/2 - t_sh,0,0]){ cube([l_dev + 2*t_sh, t_dev + t_grip, t_sh]); } //back grip plate translate([-l_dev/2 - t_sh,0,0]){ cube([l_dev + 2*t_sh, t_grip, hb_grip]); } //front grip plate translate([-l_dev/2 - t_sh,t_dev + t_grip,0]){ cube([l_dev +2*t_sh, t_grip, hf_grip+t_sh]); } } module top_plate(){ translate([-l_dev/2 - t_sh,t_dev + 2 * t_grip,0]){ cube([l_dev +2*t_sh, l_sh, t_sh]); } } module left_side_grip(){ //side grip plate translate([-l_dev/2 - t_sh,0,0]){ cube([t_sh, t_dev + t_grip, w_dev + t_sh]); } //back grip plate translate([-l_dev/2 - t_sh,0,0]){ cube([hb_grip + t_sh, t_grip, w_dev + t_sh]); } //front grip plate translate([-l_dev/2 - t_sh,t_dev + t_grip,0]){ cube([hfs_grip+t_sh, t_grip, w_dev + t_sh]); } } module left_side_plate(){ translate([-l_dev/2 - t_sh,t_dev + 2 * t_grip,0]){ cube([t_sh, l_sh, w_dev - l_sh + t_sh]); } //curved part of the side plate // color([0.1,1.0,0.2]){ intersection(){ translate([-l_dev/2- t_sh,t_dev + 2 * t_grip,w_dev - l_sh + t_sh]){ cube([t_sh, l_sh, l_sh]); } translate([-l_dev/2- t_sh,t_dev + 2 * t_grip,w_dev - l_sh + t_sh]){ rotate([0,90,0]){ cylinder(h = t_sh,r = l_sh); } } } // } } //mirror of the side plate module right_side_all(){ mirror([1,0,0]){ left_side_grip(); left_side_plate(); } } module top_hole(){ // color([0.1,0.8,0.2]){ translate([pos_h1_top+3, 1, -1]){ minkowski() { cube([lh1_top-6,wh1_top-4 + t_sh, d_hole1]); //6 because of cylinder r*2 cylinder(r=3,h=d_hole1); } } // } } module top_hole_2(){ // color([0.1,0.8,0.2]){ translate([pos_h2_top+3,1,-1]){ minkowski() { cube([lh2_top - 6, wh2_top - 4 + t_sh, d_hole1]); cylinder(r=3,h=d_hole1); } } // } } module right_hole(){ // color([0.1,0.8,0.2]){ translate([l_dev/2-d_hole2-0.01,0,pos_h1_right-3]){ //0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh1_right - 6 - t_sh, wh1_right-3 + t_sh,d_hole2]); cylinder(r=3,h=d_hole2); } } } // } } module right_hole_2(){ // color([0.1,0.8,0.2]){ translate([l_dev/2-d_hole2-0.01,0,pos_h2_right-3]){//0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh2_right - 6 - t_sh,wh2_right-3 + t_sh, d_hole2]); cylinder(r=3,h=d_hole2); } } } // } } module left_hole(){ // color([0.1,0.8,0.2]){ translate([-l_dev/2 - 0.01- t_sh, 0, pos_h1_left-3]){ //0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh1_left - 6 - t_sh,wh1_left-3 + t_sh+0.01, d_hole2]);//0.01 value is used beause of rendering problem (shadows) cylinder(r=3,h=d_hole2); } } } // } } module left_hole_2(){ // color([0.1,0.8,0.2]){ translate([-l_dev/2 - 0.01- t_sh, 0, pos_h2_left-3]){ //0.01 value is used beause of rendering problem (shadows) rotate([0,90,0]){ minkowski() { cube([lh2_left - 6 - t_sh,wh2_left-3 + t_sh+0.01,d_hole2]); //0.01 value is used beause of rendering problem (shadows) cylinder(r=3,h=d_hole2); } } } // } } module difference_top(){ difference(){ difference(){ top(); top_hole(); } top_hole_2(); } difference(){ difference(){ top_plate(); top_hole(); } top_hole_2(); } } module difference_left(){ difference(){ difference(){ left_side_grip(); left_hole(); } left_hole_2(); } difference(){ difference(){ left_side_plate(); left_hole(); } left_hole_2(); } } module difference_right(){ difference(){ difference(){ right_side_all(); right_hole(); } right_hole_2(); } } difference_top(); difference_right(); difference_left(); |
Kod nie jest idealny, powinienem tam wstawić jeszcze parę if-ów, ale jest jak najbardziej funkcjonalny. Plik możemy wrzucać na Thingiverse, tak jak wspomniałem wyżej, musimy pamiętać o zaznaczeniu opcji This is a Customizer
Wtedy przy naszym projekcie w menu po prawej stronie pojawi się opcja Open in Customizer po kliknięciu w którą będziemy mogli zobaczyć czy nasz kod działa tak, jak planowaliśmy
Sam jeszcze na tym etapie wyłapywałem błędy w kodzie – pewnie się jeszcze jakieś znajdą, ale nie są one już krytyczne (mam przynajmniej taką nadzieję). W modelu można zmieniać wiele parametrów, najważniejsze to oczywiście dostosowanie do wielkości naszego urządzenia oraz ustalenie wielkości otworów na każdej ściance – przyjąłem, że po dwa otwory na każdą stronę powinny wystarczyć. Dodatkowo, można zmienić grubość ścianki oraz wysokość “chwytów” – nawet pod bezbramkowca jesteśmy w stanie dostosować tę osłonę. Poniżej grafika, w jaki sposób powinniśmy mierzyć nasze urządzenie by wprowadzić prawidłowe dane:
3. Druk
Po ustawieniu odpowiednich parametrów klikamy Create Thing i ściągamy STLke- oczywiście w OpenSCAD też możemy ją wygenerować. Ja wprowadzając dane dla swojego tabletu musiałem pamiętać, że głośniki ma z przodu (potrzebowałem wycięcia dla nich) oraz zachować dostęp do gniazd- audio i USB oraz do przycisków fizycznych. Grubość ścianek ustawiłem na 2mm
Tablet pasuje idalnie
Nie ma też problemu z dostępem do przycisków czy montażu uchwytu:
Przyszedł czas na test w samochodzie
Zrobiłem też zdjęcia z trochę większej odległości, żeby pokazać, że osłona nie zmniejsza znacząco pola widzenia (wiem, że ten tablet wygląda jakby zabierał znaczną cześć pola widzenia, ale spokojnie, nie przeszkadza mi on w prowadzeniu samochodu)
Powyższe zdjęcia powinienem zrobić z miejsca pasażera z tyłu, ale nie chciało mi się przesiadać, wiec musicie uwierzyć na słowo, że w rzeczywistości wygląda to lepiej.
Projektem można się “pobawić” na stronie Thingiverse: https://www.thingiverse.com/thing:2558519 sam plik również załączam tutaj, chociaż można z powodzeniem skopiować kod do OpenSCAD i również będzie działało.
Zachęcam do tworzenia modeli parametrycznych- dzięki temu więcej osób skorzysta z nasze pracy, zwłaszcza gdy nie potrafią jeszcze sami projektować.
Pytanie o materiał do druku. Jaki? Jeśli PLA jak to się zachowuje w lecie, nie zmięknie?