Practice of Programming

プログラム とか Linuxとかの話題

OpenSCADでDIY(家具とか)の設計をする

別に技術系の話ではないのですが、こっちの素養がある方には馴染みやすいツールじゃないかなと思って、こっちに書いてます。

OpenSCADって?

OpenSCADは、3D CADモデラーです。

openscad.org

僕はUbuntuで使っていますが、macOSでも、Windowsでも使えます。

どういうふうに使うのか?

僕は他のCADを使ったことはありませんので、まったく比較とかはできませんが、GUIでぐりぐり動かすような感じのものでは、全く無いです。

プログラム的な感じで、形を定義して、配置して、組み合わせた結果を図として表示してくれるものです。

この記事で書かれていること

今回紹介する機能は、OpenSCADのほんの一部の機能です。あくまでDIYで家具類を作るための最低限の紹介になります。

複雑な構造や、3Dプリンターとかの話は範囲外なので、期待した方は残念ながら対象外です。

百聞は一見にしかず

ということで、実際のコードと図を例示します。これ、最初の頃によくわからずに作ったものなので、愚直にものを定義していっちゃってますが、後で直します。

// left side
translate([0,0,0]) {
    cube([23,2.7,44]);
}

// right side
translate([0,25.7,0]) {
    cube([23,2.7,44]);
}

// back
translate([0,2.7,6.3]) {
    cube([2.7,23,35]);
}

// front 
translate([23,5.2,2.4]) {
    cube([2.7,18,39]);
}

// front left
translate([23,0,2.4]) {
    cube([2.7,5.2,39]);
}

// front right
translate([23,23.2,2.4]) {
    cube([2.7,5.2,39]);
}

// front botttom
translate([23,-0.25,-0.25]) {
    cube([2.7,29,2.7]);
}

// front top
translate([23,-0.25,41.4]) {
    cube([2.7,29,2.7]);
}

// top
translate([0,2.7,41.3]) {
    cube([23,23,2.7]);
}

// bottom
translate([0,2.7,3.6]) {
    cube([23,23,2.7]);
}

上記のコードで、下記のような図ができあがります。

なお、この画像ではわかりませんが、底面に隙間を作っています。キャスターを取り付けるために空けています。

簡単に説明

cube というのは、直方体を定義できます。cube([23,2.7,44]) と書かれているのは、x: 23cm, y: 2.7cm, z: 44cm という意味で使っていますが、単位は、僕が勝手にそう決めているだけなので、230にして、mm としても別に問題ないです。

translateは、その中に書かれているものをどこに配置するか、translate([0,0,0])であれば、中心から配置しますし。translate([0,25,7,0]) であれば、y方向に25.7の位置に配置するということです。

なお、このコードだと、x: 奥行き、y: 幅、z: 高さ という感じになっています(z は大丈夫でしょうが、x,y は、気分で作ると、毎回ちがってたりします)。

moduleを使うべき

先程のものでも、ちゃんと図ができあがるのですが、同じcubeの定義がいくつもあるのが、わかるかと思います。全然いけてません。

moduleとして定義すると良いです。

module side_wall() { // 2枚
    cube([23,2.7,44]);      
}

module front_top_bottom() { // 2枚
    cube([2.7,29,2.7]);
}

module top_bottom() { // 2枚
    cube([23,23,2.7]);
}

module front_side() { // 2枚
    cube([2.7,5.2,39]);
}

module back() { // 1枚
    cube([2.7,23,35]);
}

module front() { // 1枚
    cube([2.7,18,39]);
}

// left side
translate([0,0,0]) {
    side_wall();
}

// right side
translate([0,25.7,0]) {
    side_wall();
}

// back
translate([0,2.7,6.3]) {
    back();
}

// front 
translate([23,5.2,2.4]) {
    front();
}

// front left
translate([23,0,2.4]) {
    front_side();
}

// front right
translate([23,23.2,2.4]) {
    front_side();
}

// front botttom
translate([23,-0.25,-0.25]) {
    front_top_bottom();
}

// front top
translate([23,-0.25,41.4]) {
    front_top_bottom();
}

// top
translate([0,2.7,41.3]) {
    top_bottom();
}

// bottom
translate([0,2.7,3.6]) {
    top_bottom();
}

同じサイズのものは、間違いなくmoduleにしたほうが良いですが、一つしか使わないものも、moduleにしたほうが良いです。

なぜなら、木材を注文する時に、moduleを見て買えば良いからです。なので、コメントに 2枚 とか書いておくと、良いですね。

for を使う

もう少し改善できます。for ループを使うことができます(moduleは同じなので省略します)。

// left/right side
for (i = [0,25.7]) {
  translate([0,i,0]) {
      side_wall();
  }
}

// back
translate([0,2.7,6.3]) {
    back();
}

// front 
translate([23,5.2,2.4]) {
    front();
}

// front left/right
for (i = [0,23.2]) {
  translate([23,i,2.4]) {
    front_side();
  }
}

// front botttom/top
for (i = [-0.25, 41.4]) {
  translate([23,-0.25,i]) {
    front_top_bottom();
  }
}

// top/bottom
for (i = [41.3,3.6]) {
  translate([0,2.7,i]) {
    top_bottom();
  }
}

色を付ける

module に color を付けることもできます。

module side_wall() {
    color("red")
    cube([23,2.7,44]);      
}

こんな感じで赤くなりました。

変数を使う

発注するときに面倒なので、あんまり変数を使いすぎると良くないかもしれませんが。

こんな感じで、height という変数を定義してやると、もともと高さ44cmのを作ろうと思ってたけど、もう少し高くしよう、と思ったときでも、簡単に変更できます。

height = 60;

module side_wall() {
    color("red")
    cube([23,2.7,height]);      
}

module front_top_bottom() {
    cube([2.7,29,2.7]);
}

module top_bottom() {
    cube([23,23,2.7]);
}

module front_side() {
    cube([2.7,5.2,height - 5]);
}

module back() {
    cube([2.7,23,height - 9]);
}

module front() {
    cube([2.7,18,height - 5]);
}

// left/right side
for (i = [0,25.7]) {
  translate([0,i,0]) {
      side_wall();
  }
}

// back
translate([0,2.7,6.3]) {
    back();
}

// front 
translate([23,5.2,2.4]) {
    front();
}

// front left/right
for (i = [0,23.2]) {
  translate([23,i,2.4]) {
    front_side();
  }
}

// front botttom/top
for (i = [-0.25, height - 2.6]) {
  translate([23,-0.25,i]) {
    front_top_bottom();
  }
}

// top/bottom
for (i = [height - 2.7,3.6]) {
  translate([0,2.7,i]) {
    top_bottom();
  }
}

鉄のシェルフブラケットを表してみる

箱から離れまして、よく、壁に取り付ける「シェルフブラケット」と呼ばれるものがあるんですが、下記のようなものです。

item.rakuten.co.jp

下記のようなmoduleで定義できます。

module bracketInner(){
    cube([21,1.2,7]);
}

module bracket() {
  color("black")
  difference () {
    cube([22.5,1,57]);
    for (i = [0.8:8:56]) {
      translate([0.5,-0.1,i]) bracketInner();
    }
  }
}

cube で大きな、板を作って、for で回して、angleInnerを、difference(2番目以降の子ノードを減算する)を使って抜いています(angleInnerを少し大きくしておく必要があるので、1 に対して、1.2となっています)。

ちなみに実際の箱

こんな感じで出来上がっています。接続部分は、鉄のアングルで、内側から止めています。

DIY素材の購入

大体のサイトで、cm単位で木を切った状態で送ってくれるので、今回の箱とかでは、鋸刃一切使っていません。ので、滅茶簡単です。

箱の素材は、下記で購入しました。

www.woodpro21.com

ここの素材は、サイズに割と制限があって、設計してると、パズル作ってるみたいになってしまって微妙なときがあるんですが、よく使っています。

自由なサイズで注文するなら、下記のサイトとかが良いと思います。簡単な加工も依頼できますし、希望すれば端材をもらえます。

https://diy-lab.jp/

終わり

DIYするときは、割と簡単なものでも、OpenSCADで設計するようにしています。紙に書くより正確だし変更が容易。moduleを作っておけば、注文するものがわかりやすい。3Dの図としてできあがると完成イメージが湧くので良いです。

また、大きなものだと、作成する以外の物(冷蔵庫とか、既存の棚、天井とか)とかもOpenSCADで表現してやると良いと思います。

例として、以下は、うちのキッチンに棚を作るときに用意したものです。

天井の段差、冷蔵庫、電子レンジ、食器棚、蓋をあけた炊飯器とかを雑に表現していますが、これくらいでも作っておけば、随分イメージがわきます。思ったよりものが入りそうにないなーとか...。

というわけで、OpenSCAD非常におすすめですよ。

参照

OpenSCADのマニュアルは下記にあります。

ja.wikibooks.org